From: Peter Eisentraut Date: Sat, 1 Jun 2002 20:56:55 +0000 (+0000) Subject: Add section explaining unspecified expression evaluation order. X-Git-Tag: REL7_3~1467 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bf886d5baf1a2dcd9cd2f114713c3ade7ec21d0b;p=postgresql Add section explaining unspecified expression evaluation order. --- diff --git a/doc/src/sgml/syntax.sgml b/doc/src/sgml/syntax.sgml index e1b1ac3596..ce55878477 100644 --- a/doc/src/sgml/syntax.sgml +++ b/doc/src/sgml/syntax.sgml @@ -1,5 +1,5 @@ @@ -44,7 +44,6 @@ $Header: /cvsroot/pgsql/doc/src/sgml/syntax.sgml,v 1.60 2002/04/25 20:14:43 tgl whitespace. - For example, the following is (syntactically) valid SQL input: @@ -56,7 +55,6 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); is not required; more than one command can be on a line, and commands can usefully be split across lines). - The SQL syntax is not very consistent regarding what tokens @@ -328,18 +326,16 @@ SELECT 'foo' 'bar'; characters embedded in the constant. - - - These are some examples of valid floating-point constants: - + + These are some examples of valid floating-point constants: + 3.5 4. .001 5e2 1.925e-3 - - - + + Floating-point constants are of type DOUBLE @@ -347,10 +343,10 @@ SELECT 'foo' 'bar'; by using SQL string notation or PostgreSQL type notation: - + REAL '1.23' -- string style '1.23'::REAL -- PostgreSQL (historical) style - + @@ -621,6 +617,184 @@ CAST ( 'string' AS type ) analysis and is effectively replaced by whitespace. + + + Lexical Precedence + + + operators + precedence + + + + The precedence and associativity of the operators is hard-wired + into the parser. Most operators have the same precedence and are + left-associative. This may lead to non-intuitive behavior; for + example the Boolean operators < and > have a different + precedence than the Boolean operators <= and >=. Also, + you will sometimes need to add parentheses when using combinations + of binary and unary operators. For instance + +SELECT 5 ! - 6; + + will be parsed as + +SELECT 5 ! (- 6); + + because the parser has no idea -- until it is too late -- that + ! is defined as a postfix operator, not an infix one. + To get the desired behavior in this case, you must write + +SELECT (5 !) - 6; + + This is the price one pays for extensibility. + + + + Operator Precedence (decreasing) + + + + + Operator/Element + Associativity + Description + + + + + + . + left + table/column name separator + + + + :: + left + PostgreSQL-style typecast + + + + [ ] + left + array element selection + + + + - + right + unary minus + + + + ^ + left + exponentiation + + + + * / % + left + multiplication, division, modulo + + + + + - + left + addition, subtraction + + + + IS + + test for TRUE, FALSE, UNKNOWN, NULL + + + + ISNULL + + test for NULL + + + + NOTNULL + + test for NOT NULL + + + + (any other) + left + all other native and user-defined operators + + + + IN + + set membership + + + + BETWEEN + + containment + + + + OVERLAPS + + time interval overlap + + + + LIKE ILIKE + + string pattern matching + + + + < > + + less than, greater than + + + + = + right + equality, assignment + + + + NOT + right + logical negation + + + + AND + left + logical conjunction + + + + OR + left + logical disjunction + + + +
+ + + Note that the operator precedence rules also apply to user-defined + operators that have the same names as the built-in operators + mentioned above. For example, if you define a + + operator for some custom data type it will have + the same precedence as the built-in + operator, no + matter what yours does. + +
@@ -728,11 +902,11 @@ CAST ( 'string' AS type ) need to write a qualified operator name in an expression, there is a special provision: you must write - OPERATOR(schema.operator) +OPERATOR(schema.operator) This is needed to avoid syntactic ambiguity. An example is - SELECT 3 OPERATOR(pg_catalog.+) 4; +SELECT 3 OPERATOR(pg_catalog.+) 4; In practice one usually relies on the search path for operators, so as not to have to write anything so ugly as that. @@ -1256,186 +1430,39 @@ FROM states; - - - - - Lexical Precedence + + Expression Evaluation - - operators - precedence - + + The order of evaluation of subexpressions is not defined. In + particular, subexpressions are not necessarily evaluated + left-to-right, right-to-left, or according to the lexical + precedence rules. + - The precedence and associativity of the operators is hard-wired - into the parser. Most operators have the same precedence and are - left-associative. This may lead to non-intuitive behavior; for - example the Boolean operators < and > have a different - precedence than the Boolean operators <= and >=. Also, - you will sometimes need to add parentheses when using combinations - of binary and unary operators. For instance + Furthermore, if the result of an expression can be determined by + evaluating only some parts of it, then some subexpressions + might not be evaluated at all. For instance, if one wrote -SELECT 5 ! - 6; +SELECT true OR somefunc(); - will be parsed as + then somefunc() would (probably) not be called + at all. The same would be the case if one wrote -SELECT 5 ! (- 6); +SELECT somefunc() OR true; - because the parser has no idea -- until it is too late -- that - ! is defined as a postfix operator, not an infix one. - To get the desired behavior in this case, you must write - -SELECT (5 !) - 6; - - This is the price one pays for extensibility. + Note that this is not the same as the left-to-right + short-circuiting of Boolean operators that is found + in some programming languages. - - Operator Precedence (decreasing) - - - - - Operator/Element - Associativity - Description - - - - - - . - left - table/column name separator - - - - :: - left - PostgreSQL-style typecast - - - - [ ] - left - array element selection - - - - - - right - unary minus - - - - ^ - left - exponentiation - - - - * / % - left - multiplication, division, modulo - - - - + - - left - addition, subtraction - - - - IS - - test for TRUE, FALSE, UNKNOWN, NULL - - - - ISNULL - - test for NULL - - - - NOTNULL - - test for NOT NULL - - - - (any other) - left - all other native and user-defined operators - - - - IN - - set membership - - - - BETWEEN - - containment - - - - OVERLAPS - - time interval overlap - - - - LIKE ILIKE - - string pattern matching - - - - < > - - less than, greater than - - - - = - right - equality, assignment - - - - NOT - right - logical negation - - - - AND - left - logical conjunction - - - - OR - left - logical disjunction - - - -
- - Note that the operator precedence rules also apply to user-defined - operators that have the same names as the built-in operators - mentioned above. For example, if you define a - + operator for some custom data type it will have - the same precedence as the built-in + operator, no - matter what yours does. + As a consequence, it is unwise to use functions with side effects + as part of complex expressions. -
+ +