Split out everything that looks like a function call from c_expr into
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 29 Sep 2004 23:39:20 +0000 (23:39 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 29 Sep 2004 23:39:20 +0000 (23:39 +0000)
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.

src/backend/parser/gram.y

index fcd46ddf182ae96d2a8513d1c94214a6b8b98dcb..c54197ffb7e04811ae50b46b5b0b790e76a882fc 100644 (file)
@@ -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 <node>   columnDef
 %type <defelt> def_elem
 %type <node>   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 <list>   row type_list array_expr_list
 %type <node>   case_expr case_arg when_clause case_default
 %type <list>   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;
-               }
        ;
 
 /*