-2

The OPs request for an explanation of how the following works threw up a point which I'm uncertain of.

select sysdate + (interval_difference * 1440) - sysdate
  from (select systimestamp - (systimestamp - 1) as interval_difference
          from dual )

Namely, does a plus or a minus have operator precedence? The documentation1 lists the operator order as follows

+----------------------------+-------------------------------------------+
| Operator                   |Operation                                  |
+------------------------------------------------------------------------+
| +, - (as unary operators)  | Identity, negation, location in hierarchy |
| , PRIOR, CONNECT_BY_ROOT   |                                           |
+----------------------------+-------------------------------------------+ 
| *, /                       | Multiplication, division                  |
+----------------------------+-------------------------------------------+
| +, - (as binary operators) | Addition, subtraction, concatenation      |
| , ||                       |                                           |
+----------------------------+-------------------------------------------+

The query, once reduced, becomes date + interval - date. However, the interval - date part is invalid.

Does the operation work because the operator order of precedence places a binary plus above a binary minus or because Oracle's clever enough to know that one operation is invalid and the other isn't (i.e. it's been hacked for datetime/interval arithmetic)?

In other words, why is date + interval - date executed as (date + interval) - date and not as date + (interval - date)?

The documentation placing + before - might be construed to imply that a + does have precedence but this doesn't prove anything and the fact that this operation is successful might also prove something, save that it couldn't be if executed in any other way.

The information to hand points to + having precedence but it's all circumstantial. Is this provable one way or the other?

1. For 11.2 but the 10g and 9i documentation is, unsurprisingly, identical

Community
  • 1
  • 1
Ben
  • 51,770
  • 36
  • 127
  • 149

1 Answers1

6

It is because + and - are both left-associative.

  • a + b + c means (a + b) + c.
  • a + b - c means (a + b) - c.
  • a - b + c means (a - b) + c. (And (3 - 2) + 1 != 3 - (2 + 1).)
  • a - b - c means (a - b) - c. (And (3 - 2) - 1 != 3 - (2 - 1).)

(The page that you link to actually mentions this:

Oracle evaluates operators with equal precedence from left to right within an expression.

though it's easy to miss if you don't know what to look for.)

ruakh
  • 175,680
  • 26
  • 273
  • 307
  • 1
    Now I feel really stupid :-). Can't remember basic maths... and yes just re-read the documentation and seen it :-(. Thanks! – Ben Jul 03 '13 at 20:58
  • 3
    Curiously the [PL/SQL equivalent](http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/fundamentals.htm#sthref127) says 'Operators with equal precedence are evaluated in no particular order'. – Alex Poole Jul 03 '13 at 21:02
  • @AlexPoole: Crazy! Do you think they really mean that? – ruakh Jul 03 '13 at 21:08
  • Can you come up with an example of this then @Alex? The [same thing](http://www.sqlfiddle.com/#!4/6666c/33) executed in PL/SQL could imply that it still happens as it may fail if it didn't. – Ben Jul 03 '13 at 21:11
  • No, I doubt they mean it, I think the docs are badly worded. I would expect it to work as it does in SQL, but I haven't tried to test it (yet!). Probably a doc bug. Hard to believe the behaviour of something that fundamental could be indeterminate. – Alex Poole Jul 03 '13 at 21:23