From: Tom Lane Date: Wed, 29 Sep 2004 23:39:20 +0000 (+0000) Subject: Split out everything that looks like a function call from c_expr into X-Git-Tag: REL8_0_0BETA4~251 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=912c27f9c2a228fbba41547f10a109a338439a2b;p=postgresql Split out everything that looks like a function call from c_expr into a separate production func_expr. This allows us to accept all these variants in the backwards-compatible syntax for creating a functional index; which beats documenting exactly which things work and which don't. Interestingly, it also seems to make the generated state machine a little bit smaller. --- diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index fcd46ddf18..c54197ffb7 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.475 2004/08/29 04:12:35 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.476 2004/09/29 23:39:20 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -272,8 +272,8 @@ static void doNegateFloat(Value *v); %type columnDef %type def_elem %type def_arg columnElem where_clause - a_expr b_expr c_expr AexprConst indirection_el columnref - in_expr having_clause func_table array_expr + a_expr b_expr c_expr func_expr AexprConst indirection_el + columnref in_expr having_clause func_table array_expr %type row type_list array_expr_list %type case_expr case_arg when_clause case_default %type when_clause_list @@ -3238,18 +3238,12 @@ index_elem: ColId opt_class $$->expr = NULL; $$->opclass = $2; } - | func_name '(' expr_list ')' opt_class + | func_expr opt_class { - FuncCall *n = makeNode(FuncCall); - n->funcname = $1; - n->args = $3; - n->agg_star = FALSE; - n->agg_distinct = FALSE; - $$ = makeNode(IndexElem); $$->name = NULL; - $$->expr = (Node *)n; - $$->opclass = $5; + $$->expr = $1; + $$->opclass = $2; } | '(' a_expr ')' opt_class { @@ -6479,7 +6473,55 @@ c_expr: columnref { $$ = $1; } } | case_expr { $$ = $1; } - | func_name '(' ')' + | func_expr + { $$ = $1; } + | select_with_parens %prec UMINUS + { + SubLink *n = makeNode(SubLink); + n->subLinkType = EXPR_SUBLINK; + n->lefthand = NIL; + n->operName = NIL; + n->subselect = $1; + $$ = (Node *)n; + } + | EXISTS select_with_parens + { + SubLink *n = makeNode(SubLink); + n->subLinkType = EXISTS_SUBLINK; + n->lefthand = NIL; + n->operName = NIL; + n->subselect = $2; + $$ = (Node *)n; + } + | ARRAY select_with_parens + { + SubLink *n = makeNode(SubLink); + n->subLinkType = ARRAY_SUBLINK; + n->lefthand = NIL; + n->operName = NIL; + n->subselect = $2; + $$ = (Node *)n; + } + | ARRAY array_expr + { $$ = $2; } + | row + { + RowExpr *r = makeNode(RowExpr); + r->args = $1; + r->row_typeid = InvalidOid; /* not analyzed yet */ + $$ = (Node *)r; + } + ; + +/* + * func_expr is split out from c_expr just so that we have a classification + * for "everything that is a function call or looks like one". This isn't + * very important, but it saves us having to document which variants are + * legal in the backwards-compatible functional-index syntax for CREATE INDEX. + * (Note that many of the special SQL functions wouldn't actually make any + * sense as functional index entries, but we ignore that consideration here.) + */ +func_expr: func_name '(' ')' { FuncCall *n = makeNode(FuncCall); n->funcname = $1; @@ -6936,42 +6978,6 @@ c_expr: columnref { $$ = $1; } n->agg_distinct = FALSE; $$ = (Node *)n; } - | select_with_parens %prec UMINUS - { - SubLink *n = makeNode(SubLink); - n->subLinkType = EXPR_SUBLINK; - n->lefthand = NIL; - n->operName = NIL; - n->subselect = $1; - $$ = (Node *)n; - } - | EXISTS select_with_parens - { - SubLink *n = makeNode(SubLink); - n->subLinkType = EXISTS_SUBLINK; - n->lefthand = NIL; - n->operName = NIL; - n->subselect = $2; - $$ = (Node *)n; - } - | ARRAY select_with_parens - { - SubLink *n = makeNode(SubLink); - n->subLinkType = ARRAY_SUBLINK; - n->lefthand = NIL; - n->operName = NIL; - n->subselect = $2; - $$ = (Node *)n; - } - | ARRAY array_expr - { $$ = $2; } - | row - { - RowExpr *r = makeNode(RowExpr); - r->args = $1; - r->row_typeid = InvalidOid; /* not analyzed yet */ - $$ = (Node *)r; - } ; /*