Give 'a_expr ::= a_expr Op' production a slightly lower precedence than
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 23 Jan 2001 22:39:08 +0000 (22:39 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 23 Jan 2001 22:39:08 +0000 (22:39 +0000)
Op, so that the sequence 'a_expr Op Op a_expr' will be parsed as
a_expr Op (Op a_expr) not (a_expr Op) Op a_expr as formerly.  In other
words, prefer treating user-defined operators as prefix operators to
treating them as postfix operators, when there is an ambiguity.
Also clean up a couple of other infelicities in production priority
assignment --- for example, BETWEEN wasn't being given the intended
priority, but that of AND.

src/backend/parser/gram.y

index 36690cf1e68df47a1781fc1bc93dcbfc7d70a414..dfa97e797319b975379e6c87b16b8afea18c0d46 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.217 2001/01/20 17:37:52 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.218 2001/01/23 22:39:08 tgl Exp $
  *
  * HISTORY
  *   AUTHOR            DATE            MAJOR EVENT
@@ -383,16 +383,16 @@ static void doNegateFloat(Value *v);
 %nonassoc  OVERLAPS
 %nonassoc  BETWEEN
 %nonassoc  IN
+%left      POSTFIXOP       /* dummy for postfix Op rules */
 %left      Op              /* multi-character ops and user-defined operators */
 %nonassoc  NOTNULL
 %nonassoc  ISNULL
-%nonassoc  NULL_P
-%nonassoc  IS
+%nonassoc  IS NULL_P TRUE_P FALSE_P    /* sets precedence for IS NULL, etc */
 %left      '+' '-'
 %left      '*' '/' '%'
 %left      '^'
 /* Unary Operators */
-%left      AT
+%left      AT ZONE         /* sets precedence for AT TIME ZONE */
 %right     UMINUS
 %left      '.'
 %left      '[' ']'
@@ -4355,7 +4355,7 @@ a_expr:  c_expr
                {   $$ = makeA_Expr(OP, $2, $1, $3); }
        | Op a_expr
                {   $$ = makeA_Expr(OP, $1, NULL, $2); }
-       | a_expr Op
+       | a_expr Op                 %prec POSTFIXOP
                {   $$ = makeA_Expr(OP, $2, $1, NULL); }
 
        | a_expr AND a_expr
@@ -4463,13 +4463,13 @@ a_expr:  c_expr
                    n->typename->typmod = -1;
                    $$ = makeA_Expr(OP, "=", $1,(Node *)n);
                }
-       | a_expr BETWEEN b_expr AND b_expr
+       | a_expr BETWEEN b_expr AND b_expr          %prec BETWEEN
                {
                    $$ = makeA_Expr(AND, NULL,
                        makeA_Expr(OP, ">=", $1, $3),
                        makeA_Expr(OP, "<=", $1, $5));
                }
-       | a_expr NOT BETWEEN b_expr AND b_expr
+       | a_expr NOT BETWEEN b_expr AND b_expr      %prec BETWEEN
                {
                    $$ = makeA_Expr(OR, NULL,
                        makeA_Expr(OP, "<", $1, $4),
@@ -4529,7 +4529,7 @@ a_expr:  c_expr
                        $$ = n;
                    }
                }
-       | a_expr all_Op sub_type select_with_parens
+       | a_expr all_Op sub_type select_with_parens     %prec Op
                {
                    SubLink *n = makeNode(SubLink);
                    n->lefthand = makeList1($1);
@@ -4591,7 +4591,7 @@ b_expr:  c_expr
                {   $$ = makeA_Expr(OP, $2, $1, $3); }
        | Op b_expr
                {   $$ = makeA_Expr(OP, $1, NULL, $2); }
-       | b_expr Op
+       | b_expr Op                 %prec POSTFIXOP
                {   $$ = makeA_Expr(OP, $2, $1, NULL); }
        ;