From: Tom Lane Date: Thu, 5 Sep 2002 22:52:48 +0000 (+0000) Subject: Fix some operator-precedence problems. New constructs IS DISTINCT FRM X-Git-Tag: REL7_3~530 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6fe27ca2fb20b67736d7af3acec08ed64488ab44;p=postgresql Fix some operator-precedence problems. New constructs IS DISTINCT FRM and IS [NOT] OF were not being parsed consistently with other IS forms. Also, make the world a little safer for functions named LEFT, RIGHT, etc. --- diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 674a6d0d92..d038cdd46e 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.365 2002/09/02 02:13:01 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.366 2002/09/05 22:52:48 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -416,7 +416,6 @@ static void doNegateFloat(Value *v); /* precedence: lowest to highest */ %left UNION EXCEPT %left INTERSECT -%left JOIN UNIONJOIN CROSS LEFT FULL RIGHT INNER_P NATURAL %left OR %left AND %right NOT @@ -425,7 +424,7 @@ static void doNegateFloat(Value *v); %nonassoc LIKE ILIKE SIMILAR %nonassoc ESCAPE %nonassoc OVERLAPS -%nonassoc BETWEEN DISTINCT +%nonassoc BETWEEN %nonassoc IN_P %left POSTFIXOP /* dummy for postfix Op rules */ %left Op OPERATOR /* multi-character ops and user-defined operators */ @@ -443,6 +442,14 @@ static void doNegateFloat(Value *v); %left COLLATE %left TYPECAST %left '.' +/* + * These might seem to be low-precedence, but actually they are not part + * of the arithmetic hierarchy at all in their use as JOIN operators. + * We make them high-precedence to support their use as function names. + * They wouldn't be given a precedence at all, were it not that we need + * left-associativity among the JOIN rules themselves. + */ +%left JOIN UNIONJOIN CROSS LEFT FULL RIGHT INNER_P NATURAL %% /* @@ -5419,6 +5426,7 @@ r_expr: row IN_P select_with_parens $$ = (Node *)makeOverlaps($1, $3); } | row IS DISTINCT FROM row + %prec IS { /* IS DISTINCT FROM has the following rules for non-array types: * a) the row lengths must be equal @@ -5736,13 +5744,13 @@ a_expr: c_expr { $$ = $1; } b->booltesttype = IS_NOT_UNKNOWN; $$ = (Node *)b; } - | a_expr IS DISTINCT FROM a_expr %prec DISTINCT + | a_expr IS DISTINCT FROM a_expr %prec IS { $$ = (Node *) makeSimpleA_Expr(DISTINCT, "=", $1, $5); } - | a_expr IS OF '(' type_list ')' + | a_expr IS OF '(' type_list ')' %prec IS { $$ = (Node *) makeSimpleA_Expr(OF, "=", $1, (Node *) $5); } - | a_expr IS NOT OF '(' type_list ')' + | a_expr IS NOT OF '(' type_list ')' %prec IS { $$ = (Node *) makeSimpleA_Expr(OF, "!=", $1, (Node *) $6); } @@ -5890,13 +5898,13 @@ b_expr: c_expr { $$ = (Node *) makeA_Expr(OP, $1, NULL, $2); } | b_expr qual_Op %prec POSTFIXOP { $$ = (Node *) makeA_Expr(OP, $2, $1, NULL); } - | b_expr IS DISTINCT FROM b_expr %prec Op + | b_expr IS DISTINCT FROM b_expr %prec IS { $$ = (Node *) makeSimpleA_Expr(DISTINCT, "=", $1, $5); } - | b_expr IS OF '(' type_list ')' + | b_expr IS OF '(' type_list ')' %prec IS { $$ = (Node *) makeSimpleA_Expr(OF, "=", $1, (Node *) $5); } - | b_expr IS NOT OF '(' type_list ')' + | b_expr IS NOT OF '(' type_list ')' %prec IS { $$ = (Node *) makeSimpleA_Expr(OF, "!=", $1, (Node *) $6); }