diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/parser/gram.y | 20 | ||||
-rw-r--r-- | src/interfaces/ecpg/preproc/preproc.y | 10 | ||||
-rw-r--r-- | src/test/regress/expected/plpgsql.out | 4 |
3 files changed, 26 insertions, 8 deletions
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 2b992fab4a7..4688bc79778 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.606 2008/02/07 21:07:55 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.607 2008/02/15 22:17:06 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -477,6 +477,7 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args) %nonassoc BETWEEN %nonassoc IN_P %left POSTFIXOP /* dummy for postfix Op rules */ +%nonassoc IDENT /* to support target_el without AS */ %left Op OPERATOR /* multi-character ops and user-defined operators */ %nonassoc NOTNULL %nonassoc ISNULL @@ -8705,7 +8706,6 @@ target_list: | target_list ',' target_el { $$ = lappend($1, $3); } ; -/* AS is not optional because shift/red conflict with unary ops */ target_el: a_expr AS ColLabel { $$ = makeNode(ResTarget); @@ -8714,6 +8714,22 @@ target_el: a_expr AS ColLabel $$->val = (Node *)$1; $$->location = @1; } + /* + * We support omitting AS only for column labels that aren't + * any known keyword. There is an ambiguity against postfix + * operators: is "a ! b" an infix expression, or a postfix + * expression and a column label? We prefer to resolve this + * as an infix expression, which we accomplish by assigning + * IDENT a precedence higher than POSTFIXOP. + */ + | a_expr IDENT + { + $$ = makeNode(ResTarget); + $$->name = $2; + $$->indirection = NIL; + $$->val = (Node *)$1; + $$->location = @1; + } | a_expr { $$ = makeNode(ResTarget); diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y index 6dd32b930b3..43efc431dba 100644 --- a/src/interfaces/ecpg/preproc/preproc.y +++ b/src/interfaces/ecpg/preproc/preproc.y @@ -1,4 +1,4 @@ -/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.360 2008/02/14 14:54:48 meskes Exp $ */ +/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.361 2008/02/15 22:17:06 tgl Exp $ */ /* Copyright comment */ %{ @@ -521,8 +521,9 @@ add_typedef(char *name, char * dimension, char * length, enum ECPGttype type_enu %nonassoc OVERLAPS %nonassoc BETWEEN %nonassoc IN_P -%left POSTFIXOP /* dummy for postfix Op rules */ -%left Op OPERATOR /* multi-character ops and user-defined operators */ +%left POSTFIXOP /* dummy for postfix Op rules */ +%nonassoc IDENT /* to support target_el without AS */ +%left Op OPERATOR /* multi-character ops and user-defined operators */ %nonassoc NOTNULL %nonassoc ISNULL %nonassoc IS NULL_P TRUE_P FALSE_P UNKNOWN @@ -4695,9 +4696,10 @@ target_list: target_list ',' target_el { $$ = $1; } ; -/* AS is not optional because shift/red conflict with unary ops */ target_el: a_expr AS ColLabel { $$ = cat_str(3, $1, make_str("as"), $3); } + | a_expr IDENT + { $$ = cat_str(3, $1, make_str("as"), $2); } | a_expr { $$ = $1; } | '*' diff --git a/src/test/regress/expected/plpgsql.out b/src/test/regress/expected/plpgsql.out index 78466426f1c..03204b66e6b 100644 --- a/src/test/regress/expected/plpgsql.out +++ b/src/test/regress/expected/plpgsql.out @@ -2337,9 +2337,9 @@ begin end loop; return 5; end;$$ language plpgsql; -ERROR: syntax error at or near "fought" +ERROR: syntax error at or near "the" LINE 1: select I fought the law, the law won - ^ + ^ QUERY: select I fought the law, the law won CONTEXT: SQL statement in PL/PgSQL function "bad_sql2" near line 3 -- a RETURN expression is mandatory, except for void-returning |