OSDN Git Service

Come to think of it, functions in FROM have the same syntactic restriction
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 30 Sep 2004 00:24:27 +0000 (00:24 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
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 c54197f..8f1b393 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 a0dd961..af3cbff 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 35375c3..b130a84 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 e1cd2dc..71dfd35 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 */