diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2008-02-15 22:17:06 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2008-02-15 22:17:06 +0000 |
commit | e67867b26cf052e166b39c6457ee04861cb81ead (patch) | |
tree | dafa8a47410c9f23565fe3df13368d06640bb060 /src | |
parent | cc80f0a340cdeba7716c5e128346481b82cc6949 (diff) | |
download | postgresql-e67867b26cf052e166b39c6457ee04861cb81ead.tar.gz postgresql-e67867b26cf052e166b39c6457ee04861cb81ead.zip |
Allow AS to be omitted when specifying an output column name in SELECT
(or RETURNING), but only when the output name is not any SQL keyword.
This seems as close as we can get to the standard's syntax without a
great deal of thrashing. Original patch by Hiroshi Saito, amended by me.
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 |