diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index c54197ffb7e04811ae50b46b5b0b790e76a882fc..8f1b393d29a084f8e2f5221f37fba14874532969 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.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: diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c index a0dd961363db7b4f3f5aa5c277403eb5df6cc875..af3cbffa7007c35ecd4a4a33673a8581bba8a5e0 100644 --- a/src/backend/parser/parse_clause.c +++ b/src/backend/parser/parse_clause.c @@ -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); diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c index 35375c39ac37f9c4e70341000690fd0d137102dc..b130a842aff00db3afa1e9e16002f94d360a0bbb 100644 --- a/src/backend/parser/parse_target.c +++ b/src/backend/parser/parse_target.c @@ -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; diff --git a/src/include/parser/parse_target.h b/src/include/parser/parse_target.h index e1cd2dcca55bd5b376caeb53208fc70a1ec58a6f..71dfd35c1d82f187a2ba17064f62ee3536f4733b 100644 --- a/src/include/parser/parse_target.h +++ b/src/include/parser/parse_target.h @@ -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 */