1111 *
1212 *
1313 * IDENTIFICATION
14- * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.523 2006/01/2205: 20:33 neilc Exp $
14+ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.524 2006/01/22 20:03:16 tgl Exp $
1515 *
1616 * HISTORY
1717 * AUTHORDATEMAJOR EVENT
@@ -429,6 +429,7 @@ static void doNegateFloat(Value *v);
429429%token <ival> ICONST PARAM
430430
431431/* precedence: lowest to highest*/
432+ %nonassoc SET /* see relation_expr_opt_alias*/
432433%left UNION EXCEPT
433434%left INTERSECT
434435%left OR
@@ -5880,11 +5881,27 @@ relation_expr:
58805881;
58815882
58825883
5883- relation_expr_opt_alias: relation_expr
5884+ /*
5885+ * Given "UPDATE foo set set ...", we have to decide without looking any
5886+ * further ahead whether the first "set" is an alias or the UPDATE's SET
5887+ * keyword. Since "set" is allowed as a column name both interpretations
5888+ * are feasible. We resolve the shift/reduce conflict by giving the first
5889+ * relation_expr_opt_alias production a higher precedence than the SET token
5890+ * has, causing the parser to prefer to reduce, in effect assuming that the
5891+ * SET is not an alias.
5892+ */
5893+ relation_expr_opt_alias: relation_expr%prec UMINUS
58845894{
58855895$$ =$1 ;
58865896}
5887- | relation_expr opt_as IDENT
5897+ | relation_expr ColId
5898+ {
5899+ Alias *alias = makeNode(Alias);
5900+ alias->aliasname =$2 ;
5901+ $1 ->alias = alias;
5902+ $$ =$1 ;
5903+ }
5904+ | relation_expr AS ColId
58885905{
58895906Alias *alias = makeNode(Alias);
58905907alias->aliasname =$3 ;
@@ -6827,7 +6844,7 @@ a_expr:c_expr{ $$ = $1; }
68276844$$ = (Node *) makeSimpleA_Expr(AEXPR_IN," <>" ,$1 ,$4 );
68286845}
68296846}
6830- | a_expr subquery_Op sub_type select_with_parens %prec Op
6847+ | a_expr subquery_Op sub_type select_with_parens %prec Op
68316848{
68326849SubLink *n = makeNode(SubLink);
68336850n->subLinkType =$3 ;
@@ -6836,14 +6853,14 @@ a_expr:c_expr{ $$ = $1; }
68366853n->subselect =$4 ;
68376854$$ = (Node *)n;
68386855}
6839- | a_expr subquery_Op sub_type' (' a_expr' )' %prec Op
6856+ | a_expr subquery_Op sub_type' (' a_expr' )' %prec Op
68406857{
68416858if ($3 == ANY_SUBLINK)
68426859$$ = (Node *) makeA_Expr(AEXPR_OP_ANY,$2 ,$1 ,$5 );
68436860else
68446861$$ = (Node *) makeA_Expr(AEXPR_OP_ALL,$2 ,$1 ,$5 );
68456862}
6846- | UNIQUE select_with_parens %prec Op
6863+ | UNIQUE select_with_parens
68476864{
68486865/* Not sure how to get rid of the parentheses
68496866 * but there are lots of shift/reduce errors without them.
@@ -6901,7 +6918,7 @@ b_expr:c_expr
69016918{$$ = (Node *) makeA_Expr(AEXPR_OP,$1 ,NULL ,$2 ); }
69026919| b_expr qual_Op%prec POSTFIXOP
69036920{$$ = (Node *) makeA_Expr(AEXPR_OP,$2 ,$1 ,NULL ); }
6904- | b_expr IS DISTINCT FROM b_expr%prec IS
6921+ | b_expr IS DISTINCT FROM b_expr %prec IS
69056922{
69066923$$ = (Node *) makeSimpleA_Expr(AEXPR_DISTINCT," =" ,$1 ,$5 );
69076924}
@@ -6910,7 +6927,7 @@ b_expr:c_expr
69106927$$ = (Node *) makeA_Expr(AEXPR_NOT, NIL,
69116928NULL , (Node *) makeSimpleA_Expr(AEXPR_DISTINCT," =" ,$1 ,$6 ));
69126929}
6913- | b_expr IS OF' (' type_list' )' %prec IS
6930+ | b_expr IS OF' (' type_list' )' %prec IS
69146931{
69156932$$ = (Node *) makeSimpleA_Expr(AEXPR_OF," =" ,$1 , (Node *)$5 );
69166933}