Come to think of it, functions in FROM have the same syntactic restriction
authorTom Lane
Thu, 30 Sep 2004 00:24:27 +0000 (00:24 +0000)
committerTom Lane
Thu, 30 Sep 2004 00:24:27 +0000 (00:24 +0000)
as CREATE INDEX did, and can be fixed the same way, for another small
improvement in usability and reduction in grammar size.

src/backend/parser/gram.y
src/backend/parser/parse_clause.c
src/backend/parser/parse_target.c
src/include/parser/parse_target.h

index c54197ffb7e04811ae50b46b5b0b790e76a882fc..8f1b393d29a084f8e2f5221f37fba14874532969 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.476 2004/09/29 23:39:20 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.477 2004/09/30 00:24:20 tgl Exp $
  *
  * HISTORY
  *   AUTHOR            DATE            MAJOR EVENT
@@ -5368,24 +5368,7 @@ relation_expr:
        ;
 
 
-func_table: func_name '(' ')'
-               {
-                   FuncCall *n = makeNode(FuncCall);
-                   n->funcname = $1;
-                   n->args = NIL;
-                   n->agg_star = FALSE;
-                   n->agg_distinct = FALSE;
-                   $$ = (Node *)n;
-               }
-           | func_name '(' expr_list ')'
-               {
-                   FuncCall *n = makeNode(FuncCall);
-                   n->funcname = $1;
-                   n->args = $3;
-                   n->agg_star = FALSE;
-                   n->agg_distinct = FALSE;
-                   $$ = (Node *)n;
-               }
+func_table: func_expr                              { $$ = $1; }
        ;
 
 
@@ -6978,6 +6961,16 @@ func_expr:   func_name '(' ')'
                    n->agg_distinct = FALSE;
                    $$ = (Node *)n;
                }
+           | NULLIF '(' a_expr ',' a_expr ')'
+               {
+                   $$ = (Node *) makeSimpleA_Expr(AEXPR_NULLIF, "=", $3, $5);
+               }
+           | COALESCE '(' expr_list ')'
+               {
+                   CoalesceExpr *c = makeNode(CoalesceExpr);
+                   c->args = $3;
+                   $$ = (Node *)c;
+               }
        ;
 
 /*
@@ -7206,24 +7199,12 @@ in_expr:    select_with_parens
            | '(' expr_list ')'                     { $$ = (Node *)$2; }
        ;
 
-/* Case clause
+/*
  * Define SQL92-style case clause.
- * Allow all four forms described in the standard:
  * - Full specification
  * CASE WHEN a = b THEN c ... ELSE d END
  * - Implicit argument
  * CASE a WHEN b THEN c ... ELSE d END
- * - Conditional NULL
- * NULLIF(x,y)
- * same as CASE WHEN x = y THEN NULL ELSE x END
- * - Conditional substitution from list, use first non-null argument
- * COALESCE(a,b,...)
- * same as CASE WHEN a IS NOT NULL THEN a WHEN b IS NOT NULL THEN b ... END
- * - thomas 1998-11-09
- *
- * NULLIF and COALESCE have become first class nodes to
- * prevent double evaluation of arguments.
- * - Kris Jurka 2003-02-11
  */
 case_expr: CASE case_arg when_clause_list case_default END_P
                {
@@ -7234,16 +7215,6 @@ case_expr:   CASE case_arg when_clause_list case_default END_P
                    c->defresult = (Expr *) $4;
                    $$ = (Node *)c;
                }
-           | NULLIF '(' a_expr ',' a_expr ')'
-               {
-                   $$ = (Node *) makeSimpleA_Expr(AEXPR_NULLIF, "=", $3, $5);
-               }
-           | COALESCE '(' expr_list ')'
-               {
-                   CoalesceExpr *c = makeNode(CoalesceExpr);
-                   c->args = $3;
-                   $$ = (Node *)c;
-               }
        ;
 
 when_clause_list:
index a0dd961363db7b4f3f5aa5c277403eb5df6cc875..af3cbffa7007c35ecd4a4a33673a8581bba8a5e0 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.136 2004/08/29 05:06:44 momjian Exp $
+ *   $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.137 2004/09/30 00:24:21 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -497,12 +497,16 @@ transformRangeFunction(ParseState *pstate, RangeFunction *r)
    RangeTblEntry *rte;
    RangeTblRef *rtr;
 
-   /* Get function name for possible use as alias */
-   Assert(IsA(r->funccallnode, FuncCall));
-   funcname = strVal(llast(((FuncCall *) r->funccallnode)->funcname));
+   /*
+    * Get function name for possible use as alias.  We use the same
+    * transformation rules as for a SELECT output expression.  For a
+    * FuncCall node, the result will be the function name, but it is
+    * possible for the grammar to hand back other node types.
+    */
+   funcname = FigureColname(r->funccallnode);
 
    /*
-    * Transform the raw FuncCall node.
+    * Transform the raw expression.
     */
    funcexpr = transformExpr(pstate, r->funccallnode);
 
index 35375c39ac37f9c4e70341000690fd0d137102dc..b130a842aff00db3afa1e9e16002f94d360a0bbb 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.125 2004/08/29 05:06:44 momjian Exp $
+ *   $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.126 2004/09/30 00:24:21 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -41,7 +41,6 @@ static Node *transformAssignmentIndirection(ParseState *pstate,
 static List *ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref);
 static List *ExpandAllTables(ParseState *pstate);
 static List *ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind);
-static char *FigureColname(Node *node);
 static int FigureColnameInternal(Node *node, char **name);
 
 
@@ -893,7 +892,7 @@ ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind)
  * Note that the argument is the *untransformed* parse tree for the target
  * item.  This is a shade easier to work with than the transformed tree.
  */
-static char *
+char *
 FigureColname(Node *node)
 {
    char       *name = NULL;
index e1cd2dcca55bd5b376caeb53208fc70a1ec58a6f..71dfd35c1d82f187a2ba17064f62ee3536f4733b 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/parser/parse_target.h,v 1.33 2004/08/29 04:13:09 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/parser/parse_target.h,v 1.34 2004/09/30 00:24:27 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -27,5 +27,6 @@ extern void updateTargetListEntry(ParseState *pstate, TargetEntry *tle,
                      List *indirection);
 extern List *checkInsertTargets(ParseState *pstate, List *cols,
                   List **attrnos);
+extern char *FigureColname(Node *node);
 
 #endif   /* PARSE_TARGET_H */