On Mon, Feb 11, 2013 at 10:48:38AM -0800, David Fetter wrote:
> On Sun, Feb 10, 2013 at 10:09:19AM -0500, Tom Lane wrote:
> > David Fetter <da...@fetter.org> writes:
> > > Per suggestions and lots of help from Andrew Gierth, please find
> > > attached a patch to clean up the call sites for FuncCall nodes, which
> > > I'd like to expand centrally rather than in each of the 37 (or 38, but
> > > I only redid 37) places where it's called.  The remaining one is in
> > > src/backend/nodes/copyfuncs.c, which has to be modified for any
> > > changes in the that struct anyhow.
> > 
> > TBH, I don't think this is an improvement.
> > 
> > The problem with adding a new field to any struct is that you have to
> > run around and examine (and, usually, modify) every place that
> > manufactures that type of struct.  With a makeFuncCall defined like
> > this, you'd still have to do that; it would just become a lot easier
> > to forget to do so.
> > 
> > If the subroutine were defined like most other makeXXX subroutines,
> > ie you have to supply *all* the fields, that argument would go away,
> > but the notational advantage is then dubious.
> > 
> > The bigger-picture point is that you're proposing to make the coding
> > conventions for building FuncCalls different from what they are for
> > any other grammar node.  I don't think that's a great idea; it will
> > mostly foster confusion.
> 
> The major difference between FuncCalls and others is that `while most
> raw-parsetree nodes are constructed only in their own syntax
> productions, FuncCall is constructed in many places unrelated to
> actual function call syntax.
> 
> This really will make things a good bit easier on our successors.

Here's a rebased patch with comments illustrating how best to employ.

In my previous message, I characterized the difference between
FuncCalls and other raw-parsetree nodes.  Is there some flaw in that
logic? If there isn't, is there some reason not to treat them in a
less redundant, more uniform manner as this patch does?

Cheers,
David.
-- 
David Fetter <da...@fetter.org> http://fetter.org/
Phone: +1 415 235 3778  AIM: dfetter666  Yahoo!: dfetter
Skype: davidfetter      XMPP: david.fet...@gmail.com
iCal: webcal://www.tripit.com/feed/ical/people/david74/tripit.ics

Remember to vote!
Consider donating to Postgres: http://www.postgresql.org/about/donate
*** a/src/backend/nodes/makefuncs.c
--- b/src/backend/nodes/makefuncs.c
***************
*** 508,510 **** makeDefElemExtended(char *nameSpace, char *name, Node *arg,
--- 508,535 ----
  
        return res;
  }
+ 
+ /*
+  * makeFuncCall -
+  *
+  * Initialize a FuncCall struct with the information every caller must
+  * supply.  Any non-default parameters have to be handled by the
+  * caller.
+  *
+  */
+ 
+ FuncCall *
+ makeFuncCall(List *name, List *args, int location)
+ {
+       FuncCall *n = makeNode(FuncCall);
+       n->funcname = name;
+       n->args = args;
+       n->location = location;
+       n->agg_order = NIL;
+       n->agg_star = FALSE;
+       n->agg_distinct = FALSE;
+       n->func_variadic = FALSE;
+       n->over = NULL;
+       return n;
+ }
+ 
*** a/src/backend/parser/gram.y
--- b/src/backend/parser/gram.y
***************
*** 10487,10502 **** a_expr:            c_expr                                  
                                { $$ = $1; }
                                }
                        | a_expr AT TIME ZONE a_expr                    %prec AT
                                {
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = 
SystemFuncName("timezone");
!                                       n->args = list_make2($5, $1);
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
!                                       n->func_variadic = FALSE;
!                                       n->over = NULL;
!                                       n->location = @2;
!                                       $$ = (Node *) n;
                                }
                /*
                 * These operators must be called out explicitly in order to 
make use
--- 10487,10495 ----
                                }
                        | a_expr AT TIME ZONE a_expr                    %prec AT
                                {
!                                       $$ = (Node *) 
makeFuncCall(SystemFuncName("timezone"),
!                                                                               
           list_make2($5, $1),
!                                                                               
           @2);
                                }
                /*
                 * These operators must be called out explicitly in order to 
make use
***************
*** 10548,10660 **** a_expr:            c_expr                                  
                                { $$ = $1; }
                                { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, 
"~~", $1, $3, @2); }
                        | a_expr LIKE a_expr ESCAPE a_expr
                                {
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = 
SystemFuncName("like_escape");
!                                       n->args = list_make2($3, $5);
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
!                                       n->func_variadic = FALSE;
!                                       n->over = NULL;
!                                       n->location = @2;
!                                       $$ = (Node *) 
makeSimpleA_Expr(AEXPR_OP, "~~", $1, (Node *) n, @2);
                                }
                        | a_expr NOT LIKE a_expr
                                { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, 
"!~~", $1, $4, @2); }
                        | a_expr NOT LIKE a_expr ESCAPE a_expr
                                {
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = 
SystemFuncName("like_escape");
!                                       n->args = list_make2($4, $6);
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
!                                       n->func_variadic = FALSE;
!                                       n->over = NULL;
!                                       n->location = @2;
                                        $$ = (Node *) 
makeSimpleA_Expr(AEXPR_OP, "!~~", $1, (Node *) n, @2);
                                }
                        | a_expr ILIKE a_expr
                                { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, 
"~~*", $1, $3, @2); }
                        | a_expr ILIKE a_expr ESCAPE a_expr
                                {
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = 
SystemFuncName("like_escape");
!                                       n->args = list_make2($3, $5);
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
!                                       n->func_variadic = FALSE;
!                                       n->over = NULL;
!                                       n->location = @2;
                                        $$ = (Node *) 
makeSimpleA_Expr(AEXPR_OP, "~~*", $1, (Node *) n, @2);
                                }
                        | a_expr NOT ILIKE a_expr
                                { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, 
"!~~*", $1, $4, @2); }
                        | a_expr NOT ILIKE a_expr ESCAPE a_expr
                                {
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = 
SystemFuncName("like_escape");
!                                       n->args = list_make2($4, $6);
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
!                                       n->func_variadic = FALSE;
!                                       n->over = NULL;
!                                       n->location = @2;
                                        $$ = (Node *) 
makeSimpleA_Expr(AEXPR_OP, "!~~*", $1, (Node *) n, @2);
                                }
  
                        | a_expr SIMILAR TO a_expr                              
%prec SIMILAR
                                {
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = 
SystemFuncName("similar_escape");
!                                       n->args = list_make2($4, 
makeNullAConst(-1));
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
!                                       n->func_variadic = FALSE;
!                                       n->over = NULL;
!                                       n->location = @2;
                                        $$ = (Node *) 
makeSimpleA_Expr(AEXPR_OP, "~", $1, (Node *) n, @2);
                                }
                        | a_expr SIMILAR TO a_expr ESCAPE a_expr
                                {
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = 
SystemFuncName("similar_escape");
!                                       n->args = list_make2($4, $6);
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
!                                       n->func_variadic = FALSE;
!                                       n->over = NULL;
!                                       n->location = @2;
                                        $$ = (Node *) 
makeSimpleA_Expr(AEXPR_OP, "~", $1, (Node *) n, @2);
                                }
                        | a_expr NOT SIMILAR TO a_expr                  %prec 
SIMILAR
                                {
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = 
SystemFuncName("similar_escape");
!                                       n->args = list_make2($5, 
makeNullAConst(-1));
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
!                                       n->func_variadic = FALSE;
!                                       n->over = NULL;
!                                       n->location = @2;
                                        $$ = (Node *) 
makeSimpleA_Expr(AEXPR_OP, "!~", $1, (Node *) n, @2);
                                }
                        | a_expr NOT SIMILAR TO a_expr ESCAPE a_expr
                                {
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = 
SystemFuncName("similar_escape");
!                                       n->args = list_make2($5, $7);
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
!                                       n->func_variadic = FALSE;
!                                       n->over = NULL;
!                                       n->location = @2;
                                        $$ = (Node *) 
makeSimpleA_Expr(AEXPR_OP, "!~", $1, (Node *) n, @2);
                                }
  
--- 10541,10606 ----
                                { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, 
"~~", $1, $3, @2); }
                        | a_expr LIKE a_expr ESCAPE a_expr
                                {
!                                       FuncCall *n = 
makeFuncCall(SystemFuncName("like_escape"),
!                                                                               
           list_make2($3, $5),
!                                                                               
           @2);
!                     $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~~", $1, (Node 
*) n, @2);
! 
                                }
                        | a_expr NOT LIKE a_expr
                                { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, 
"!~~", $1, $4, @2); }
                        | a_expr NOT LIKE a_expr ESCAPE a_expr
                                {
!                                       FuncCall *n = 
makeFuncCall(SystemFuncName("like_escape"),
!                                                                               
           list_make2($4, $6),
!                                                                               
           @2);
                                        $$ = (Node *) 
makeSimpleA_Expr(AEXPR_OP, "!~~", $1, (Node *) n, @2);
                                }
                        | a_expr ILIKE a_expr
                                { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, 
"~~*", $1, $3, @2); }
                        | a_expr ILIKE a_expr ESCAPE a_expr
                                {
!                                       FuncCall *n = 
makeFuncCall(SystemFuncName("like_escape"),
!                                                                               
           list_make2($3, $5),
!                                                                               
           @2);
                                        $$ = (Node *) 
makeSimpleA_Expr(AEXPR_OP, "~~*", $1, (Node *) n, @2);
                                }
                        | a_expr NOT ILIKE a_expr
                                { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, 
"!~~*", $1, $4, @2); }
                        | a_expr NOT ILIKE a_expr ESCAPE a_expr
                                {
!                                       FuncCall *n = 
makeFuncCall(SystemFuncName("like_escape"),
!                                                                               
           list_make2($4, $6),
!                                                                               
           @2);
                                        $$ = (Node *) 
makeSimpleA_Expr(AEXPR_OP, "!~~*", $1, (Node *) n, @2);
                                }
  
                        | a_expr SIMILAR TO a_expr                              
%prec SIMILAR
                                {
!                                       FuncCall *n = 
makeFuncCall(SystemFuncName("similar_escape"),
!                                                                               
           list_make2($4, makeNullAConst(-1)),
!                                                                               
           @2);
                                        $$ = (Node *) 
makeSimpleA_Expr(AEXPR_OP, "~", $1, (Node *) n, @2);
                                }
                        | a_expr SIMILAR TO a_expr ESCAPE a_expr
                                {
!                                       FuncCall *n = 
makeFuncCall(SystemFuncName("similar_escape"),
!                                                                               
           list_make2($4, $6),
!                                                                               
           @2);
                                        $$ = (Node *) 
makeSimpleA_Expr(AEXPR_OP, "~", $1, (Node *) n, @2);
                                }
                        | a_expr NOT SIMILAR TO a_expr                  %prec 
SIMILAR
                                {
!                                       FuncCall *n = 
makeFuncCall(SystemFuncName("similar_escape"),
!                                                                               
           list_make2($5, makeNullAConst(-1)),
!                                                                               
           @2);
                                        $$ = (Node *) 
makeSimpleA_Expr(AEXPR_OP, "!~", $1, (Node *) n, @2);
                                }
                        | a_expr NOT SIMILAR TO a_expr ESCAPE a_expr
                                {
!                                       FuncCall *n = 
makeFuncCall(SystemFuncName("similar_escape"),
!                                                                               
           list_make2($5, $7),
!                                                                               
           @2);
                                        $$ = (Node *) 
makeSimpleA_Expr(AEXPR_OP, "!~", $1, (Node *) n, @2);
                                }
  
***************
*** 11089,11185 **** c_expr:            columnref                               
                                { $$ = $1; }
   */
  func_expr:    func_name '(' ')' over_clause
                                {
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = $1;
!                                       n->args = NIL;
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
!                                       n->func_variadic = FALSE;
                                        n->over = $4;
-                                       n->location = @1;
                                        $$ = (Node *)n;
                                }
                        | func_name '(' func_arg_list ')' over_clause
                                {
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = $1;
!                                       n->args = $3;
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
!                                       n->func_variadic = FALSE;
                                        n->over = $5;
-                                       n->location = @1;
                                        $$ = (Node *)n;
                                }
                        | func_name '(' VARIADIC func_arg_expr ')' over_clause
                                {
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = $1;
!                                       n->args = list_make1($4);
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
                                        n->func_variadic = TRUE;
                                        n->over = $6;
-                                       n->location = @1;
                                        $$ = (Node *)n;
                                }
                        | func_name '(' func_arg_list ',' VARIADIC 
func_arg_expr ')' over_clause
                                {
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = $1;
!                                       n->args = lappend($3, $6);
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
                                        n->func_variadic = TRUE;
                                        n->over = $8;
-                                       n->location = @1;
                                        $$ = (Node *)n;
                                }
                        | func_name '(' func_arg_list sort_clause ')' 
over_clause
                                {
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = $1;
!                                       n->args = $3;
                                        n->agg_order = $4;
-                                       n->agg_star = FALSE;
-                                       n->agg_distinct = FALSE;
-                                       n->func_variadic = FALSE;
                                        n->over = $6;
-                                       n->location = @1;
                                        $$ = (Node *)n;
                                }
                        | func_name '(' ALL func_arg_list opt_sort_clause ')' 
over_clause
                                {
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = $1;
!                                       n->args = $4;
                                        n->agg_order = $5;
-                                       n->agg_star = FALSE;
-                                       n->agg_distinct = FALSE;
                                        /* Ideally we'd mark the FuncCall node 
to indicate
                                         * "must be an aggregate", but there's 
no provision
                                         * for that in FuncCall at the moment.
                                         */
-                                       n->func_variadic = FALSE;
                                        n->over = $7;
-                                       n->location = @1;
                                        $$ = (Node *)n;
                                }
                        | func_name '(' DISTINCT func_arg_list opt_sort_clause 
')' over_clause
                                {
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = $1;
!                                       n->args = $4;
                                        n->agg_order = $5;
-                                       n->agg_star = FALSE;
                                        n->agg_distinct = TRUE;
-                                       n->func_variadic = FALSE;
                                        n->over = $7;
-                                       n->location = @1;
                                        $$ = (Node *)n;
                                }
                        | func_name '(' '*' ')' over_clause
--- 11035,11088 ----
   */
  func_expr:    func_name '(' ')' over_clause
                                {
!                                       FuncCall *n = makeFuncCall($1, NIL, @1);
                                        n->over = $4;
                                        $$ = (Node *)n;
                                }
                        | func_name '(' func_arg_list ')' over_clause
                                {
!                                       FuncCall *n = makeFuncCall($1, $3, @1);
                                        n->over = $5;
                                        $$ = (Node *)n;
                                }
                        | func_name '(' VARIADIC func_arg_expr ')' over_clause
                                {
!                                       FuncCall *n = makeFuncCall($1, 
list_make1($4), @1);
                                        n->func_variadic = TRUE;
                                        n->over = $6;
                                        $$ = (Node *)n;
                                }
                        | func_name '(' func_arg_list ',' VARIADIC 
func_arg_expr ')' over_clause
                                {
!                                       FuncCall *n = makeFuncCall($1, 
lappend($3, $6), @1);
                                        n->func_variadic = TRUE;
                                        n->over = $8;
                                        $$ = (Node *)n;
                                }
                        | func_name '(' func_arg_list sort_clause ')' 
over_clause
                                {
!                                       FuncCall *n = makeFuncCall($1, $3, @1);
                                        n->agg_order = $4;
                                        n->over = $6;
                                        $$ = (Node *)n;
                                }
                        | func_name '(' ALL func_arg_list opt_sort_clause ')' 
over_clause
                                {
!                                       FuncCall *n = makeFuncCall($1, $4, @1);
                                        n->agg_order = $5;
                                        /* Ideally we'd mark the FuncCall node 
to indicate
                                         * "must be an aggregate", but there's 
no provision
                                         * for that in FuncCall at the moment.
                                         */
                                        n->over = $7;
                                        $$ = (Node *)n;
                                }
                        | func_name '(' DISTINCT func_arg_list opt_sort_clause 
')' over_clause
                                {
!                                       FuncCall *n = makeFuncCall($1, $4, @1);
                                        n->agg_order = $5;
                                        n->agg_distinct = TRUE;
                                        n->over = $7;
                                        $$ = (Node *)n;
                                }
                        | func_name '(' '*' ')' over_clause
***************
*** 11194,11222 **** func_expr: func_name '(' ')' over_clause
                                         * so that later processing can detect 
what the argument
                                         * really was.
                                         */
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = $1;
!                                       n->args = NIL;
!                                       n->agg_order = NIL;
                                        n->agg_star = TRUE;
-                                       n->agg_distinct = FALSE;
-                                       n->func_variadic = FALSE;
                                        n->over = $5;
-                                       n->location = @1;
                                        $$ = (Node *)n;
                                }
                        | COLLATION FOR '(' a_expr ')'
                                {
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = 
SystemFuncName("pg_collation_for");
!                                       n->args = list_make1($4);
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
!                                       n->func_variadic = FALSE;
!                                       n->over = NULL;
!                                       n->location = @1;
!                                       $$ = (Node *)n;
                                }
                        | CURRENT_DATE
                                {
--- 11097,11112 ----
                                         * so that later processing can detect 
what the argument
                                         * really was.
                                         */
!                                       FuncCall *n = makeFuncCall($1, NIL, @1);
                                        n->agg_star = TRUE;
                                        n->over = $5;
                                        $$ = (Node *)n;
                                }
                        | COLLATION FOR '(' a_expr ')'
                                {
!                                       $$ = (Node *) 
makeFuncCall(SystemFuncName("pg_collation_for"),
!                                                                               
           list_make1($4),
!                                                                               
           @1);
                                }
                        | CURRENT_DATE
                                {
***************
*** 11268,11283 **** func_expr: func_name '(' ')' over_clause
                                         * Translate as "now()", since we have 
a function that
                                         * does exactly what is needed.
                                         */
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = SystemFuncName("now");
!                                       n->args = NIL;
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
!                                       n->func_variadic = FALSE;
!                                       n->over = NULL;
!                                       n->location = @1;
!                                       $$ = (Node *)n;
                                }
                        | CURRENT_TIMESTAMP '(' Iconst ')'
                                {
--- 11158,11164 ----
                                         * Translate as "now()", since we have 
a function that
                                         * does exactly what is needed.
                                         */
!                                       $$ = (Node *) 
makeFuncCall(SystemFuncName("now"), NIL, @1);
                                }
                        | CURRENT_TIMESTAMP '(' Iconst ')'
                                {
***************
*** 11340,11435 **** func_expr: func_name '(' ')' over_clause
                                }
                        | CURRENT_ROLE
                                {
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = 
SystemFuncName("current_user");
!                                       n->args = NIL;
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
!                                       n->func_variadic = FALSE;
!                                       n->over = NULL;
!                                       n->location = @1;
!                                       $$ = (Node *)n;
                                }
                        | CURRENT_USER
                                {
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = 
SystemFuncName("current_user");
!                                       n->args = NIL;
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
!                                       n->func_variadic = FALSE;
!                                       n->over = NULL;
!                                       n->location = @1;
!                                       $$ = (Node *)n;
                                }
                        | SESSION_USER
                                {
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = 
SystemFuncName("session_user");
!                                       n->args = NIL;
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
!                                       n->func_variadic = FALSE;
!                                       n->over = NULL;
!                                       n->location = @1;
!                                       $$ = (Node *)n;
                                }
                        | USER
                                {
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = 
SystemFuncName("current_user");
!                                       n->args = NIL;
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
!                                       n->func_variadic = FALSE;
!                                       n->over = NULL;
!                                       n->location = @1;
!                                       $$ = (Node *)n;
                                }
                        | CURRENT_CATALOG
                                {
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = 
SystemFuncName("current_database");
!                                       n->args = NIL;
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
!                                       n->func_variadic = FALSE;
!                                       n->over = NULL;
!                                       n->location = @1;
!                                       $$ = (Node *)n;
                                }
                        | CURRENT_SCHEMA
                                {
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = 
SystemFuncName("current_schema");
!                                       n->args = NIL;
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
!                                       n->func_variadic = FALSE;
!                                       n->over = NULL;
!                                       n->location = @1;
!                                       $$ = (Node *)n;
                                }
                        | CAST '(' a_expr AS Typename ')'
                                { $$ = makeTypeCast($3, $5, @1); }
                        | EXTRACT '(' extract_list ')'
                                {
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = 
SystemFuncName("date_part");
!                                       n->args = $3;
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
!                                       n->func_variadic = FALSE;
!                                       n->over = NULL;
!                                       n->location = @1;
!                                       $$ = (Node *)n;
                                }
                        | OVERLAY '(' overlay_list ')'
                                {
--- 11221,11253 ----
                                }
                        | CURRENT_ROLE
                                {
!                                       $$ = (Node *) 
makeFuncCall(SystemFuncName("current_user"), NIL, @1);
                                }
                        | CURRENT_USER
                                {
!                                       $$ = (Node *) 
makeFuncCall(SystemFuncName("current_user"), NIL, @1);
                                }
                        | SESSION_USER
                                {
!                                       $$ = (Node *) 
makeFuncCall(SystemFuncName("session_user"), NIL, @1);
                                }
                        | USER
                                {
!                                       $$ = (Node *) 
makeFuncCall(SystemFuncName("current_user"), NIL, @1);
                                }
                        | CURRENT_CATALOG
                                {
!                                       $$ = (Node *) 
makeFuncCall(SystemFuncName("current_database"), NIL, @1);
                                }
                        | CURRENT_SCHEMA
                                {
!                                       $$ = (Node *) 
makeFuncCall(SystemFuncName("current_schema"), NIL, @1);
                                }
                        | CAST '(' a_expr AS Typename ')'
                                { $$ = makeTypeCast($3, $5, @1); }
                        | EXTRACT '(' extract_list ')'
                                {
!                                       $$ = (Node *) 
makeFuncCall(SystemFuncName("date_part"), $3, @1);
                                }
                        | OVERLAY '(' overlay_list ')'
                                {
***************
*** 11438,11483 **** func_expr: func_name '(' ')' over_clause
                                         * overlay(A PLACING B FROM C) is 
converted to
                                         * overlay(A, B, C)
                                         */
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = SystemFuncName("overlay");
!                                       n->args = $3;
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
!                                       n->func_variadic = FALSE;
!                                       n->over = NULL;
!                                       n->location = @1;
!                                       $$ = (Node *)n;
                                }
                        | POSITION '(' position_list ')'
                                {
                                        /* position(A in B) is converted to 
position(B, A) */
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = 
SystemFuncName("position");
!                                       n->args = $3;
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
!                                       n->func_variadic = FALSE;
!                                       n->over = NULL;
!                                       n->location = @1;
!                                       $$ = (Node *)n;
                                }
                        | SUBSTRING '(' substr_list ')'
                                {
                                        /* substring(A from B for C) is 
converted to
                                         * substring(A, B, C) - thomas 
2000-11-28
                                         */
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = 
SystemFuncName("substring");
!                                       n->args = $3;
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
!                                       n->func_variadic = FALSE;
!                                       n->over = NULL;
!                                       n->location = @1;
!                                       $$ = (Node *)n;
                                }
                        | TREAT '(' a_expr AS Typename ')'
                                {
--- 11256,11274 ----
                                         * overlay(A PLACING B FROM C) is 
converted to
                                         * overlay(A, B, C)
                                         */
!                                       $$ = (Node *) 
makeFuncCall(SystemFuncName("overlay"), $3, @1);
                                }
                        | POSITION '(' position_list ')'
                                {
                                        /* position(A in B) is converted to 
position(B, A) */
!                                       $$ = (Node *) 
makeFuncCall(SystemFuncName("position"), $3, @1);
                                }
                        | SUBSTRING '(' substr_list ')'
                                {
                                        /* substring(A from B for C) is 
converted to
                                         * substring(A, B, C) - thomas 
2000-11-28
                                         */
!                                       $$ = (Node *) 
makeFuncCall(SystemFuncName("substring"), $3, @1);
                                }
                        | TREAT '(' a_expr AS Typename ')'
                                {
***************
*** 11486,11560 **** func_expr: func_name '(' ')' over_clause
                                         * In SQL99, this is intended for use 
with structured UDTs,
                                         * but let's make this a generally 
useful form allowing stronger
                                         * coercions than are handled by 
implicit casting.
!                                        */
!                                       FuncCall *n = makeNode(FuncCall);
!                                       /* Convert SystemTypeName() to 
SystemFuncName() even though
                                         * at the moment they result in the 
same thing.
                                         */
!                                       n->funcname = SystemFuncName(((Value 
*)llast($5->names))->val.str);
!                                       n->args = list_make1($3);
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
!                                       n->func_variadic = FALSE;
!                                       n->over = NULL;
!                                       n->location = @1;
!                                       $$ = (Node *)n;
                                }
                        | TRIM '(' BOTH trim_list ')'
                                {
                                        /* various trim expressions are defined 
in SQL
                                         * - thomas 1997-07-19
                                         */
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = SystemFuncName("btrim");
!                                       n->args = $4;
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
!                                       n->func_variadic = FALSE;
!                                       n->over = NULL;
!                                       n->location = @1;
!                                       $$ = (Node *)n;
                                }
                        | TRIM '(' LEADING trim_list ')'
                                {
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = SystemFuncName("ltrim");
!                                       n->args = $4;
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
!                                       n->func_variadic = FALSE;
!                                       n->over = NULL;
!                                       n->location = @1;
!                                       $$ = (Node *)n;
                                }
                        | TRIM '(' TRAILING trim_list ')'
                                {
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = SystemFuncName("rtrim");
!                                       n->args = $4;
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
!                                       n->func_variadic = FALSE;
!                                       n->over = NULL;
!                                       n->location = @1;
!                                       $$ = (Node *)n;
                                }
                        | TRIM '(' trim_list ')'
                                {
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = SystemFuncName("btrim");
!                                       n->args = $3;
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
!                                       n->func_variadic = FALSE;
!                                       n->over = NULL;
!                                       n->location = @1;
!                                       $$ = (Node *)n;
                                }
                        | NULLIF '(' a_expr ',' a_expr ')'
                                {
--- 11277,11308 ----
                                         * In SQL99, this is intended for use 
with structured UDTs,
                                         * but let's make this a generally 
useful form allowing stronger
                                         * coercions than are handled by 
implicit casting.
!                      *
!                                        * Convert SystemTypeName() to 
SystemFuncName() even though
                                         * at the moment they result in the 
same thing.
                                         */
!                                       $$ = (Node *) 
makeFuncCall(SystemFuncName(((Value *)llast($5->names))->val.str),
!                                                                               
            list_make1($3),
!                                                                               
            @1);
                                }
                        | TRIM '(' BOTH trim_list ')'
                                {
                                        /* various trim expressions are defined 
in SQL
                                         * - thomas 1997-07-19
                                         */
!                                       $$ = (Node *) 
makeFuncCall(SystemFuncName("btrim"), $4, @1);
                                }
                        | TRIM '(' LEADING trim_list ')'
                                {
!                                       $$ = (Node *) 
makeFuncCall(SystemFuncName("ltrim"), $4, @1);
                                }
                        | TRIM '(' TRAILING trim_list ')'
                                {
!                                       $$ = (Node *) 
makeFuncCall(SystemFuncName("rtrim"), $4, @1);
                                }
                        | TRIM '(' trim_list ')'
                                {
!                                       $$ = (Node *) 
makeFuncCall(SystemFuncName("btrim"), $3, @1);
                                }
                        | NULLIF '(' a_expr ',' a_expr ')'
                                {
***************
*** 11607,11622 **** func_expr: func_name '(' ')' over_clause
                                {
                                        /* xmlexists(A PASSING [BY REF] B [BY 
REF]) is
                                         * converted to xmlexists(A, B)*/
!                                       FuncCall *n = makeNode(FuncCall);
!                                       n->funcname = 
SystemFuncName("xmlexists");
!                                       n->args = list_make2($3, $4);
!                                       n->agg_order = NIL;
!                                       n->agg_star = FALSE;
!                                       n->agg_distinct = FALSE;
!                                       n->func_variadic = FALSE;
!                                       n->over = NULL;
!                                       n->location = @1;
!                                       $$ = (Node *)n;
                                }
                        | XMLFOREST '(' xml_attribute_list ')'
                                {
--- 11355,11361 ----
                                {
                                        /* xmlexists(A PASSING [BY REF] B [BY 
REF]) is
                                         * converted to xmlexists(A, B)*/
!                                       $$ = (Node *) 
makeFuncCall(SystemFuncName("xmlexists"), list_make2($3, $4), @1);
                                }
                        | XMLFOREST '(' xml_attribute_list ')'
                                {
***************
*** 13272,13280 **** makeBoolAConst(bool state, int location)
  static FuncCall *
  makeOverlaps(List *largs, List *rargs, int location, core_yyscan_t yyscanner)
  {
!       FuncCall *n = makeNode(FuncCall);
! 
!       n->funcname = SystemFuncName("overlaps");
        if (list_length(largs) == 1)
                largs = lappend(largs, largs);
        else if (list_length(largs) != 2)
--- 13011,13017 ----
  static FuncCall *
  makeOverlaps(List *largs, List *rargs, int location, core_yyscan_t yyscanner)
  {
!       FuncCall *n;
        if (list_length(largs) == 1)
                largs = lappend(largs, largs);
        else if (list_length(largs) != 2)
***************
*** 13289,13301 **** makeOverlaps(List *largs, List *rargs, int location, 
core_yyscan_t yyscanner)
                                (errcode(ERRCODE_SYNTAX_ERROR),
                                 errmsg("wrong number of parameters on right 
side of OVERLAPS expression"),
                                 parser_errposition(location)));
!       n->args = list_concat(largs, rargs);
!       n->agg_order = NIL;
!       n->agg_star = FALSE;
!       n->agg_distinct = FALSE;
!       n->func_variadic = FALSE;
!       n->over = NULL;
!       n->location = location;
        return n;
  }
  
--- 13026,13032 ----
                                (errcode(ERRCODE_SYNTAX_ERROR),
                                 errmsg("wrong number of parameters on right 
side of OVERLAPS expression"),
                                 parser_errposition(location)));
!       n = makeFuncCall(SystemFuncName("overlaps"), list_concat(largs, rargs), 
location);
        return n;
  }
  
*** a/src/backend/parser/parse_utilcmd.c
--- b/src/backend/parser/parse_utilcmd.c
***************
*** 448,463 **** transformColumnDefinition(CreateStmtContext *cxt, ColumnDef 
*column)
                castnode->typeName = SystemTypeName("regclass");
                castnode->arg = (Node *) snamenode;
                castnode->location = -1;
!               funccallnode = makeNode(FuncCall);
!               funccallnode->funcname = SystemFuncName("nextval");
!               funccallnode->args = list_make1(castnode);
!               funccallnode->agg_order = NIL;
!               funccallnode->agg_star = false;
!               funccallnode->agg_distinct = false;
!               funccallnode->func_variadic = false;
!               funccallnode->over = NULL;
!               funccallnode->location = -1;
! 
                constraint = makeNode(Constraint);
                constraint->contype = CONSTR_DEFAULT;
                constraint->location = -1;
--- 448,456 ----
                castnode->typeName = SystemTypeName("regclass");
                castnode->arg = (Node *) snamenode;
                castnode->location = -1;
!               funccallnode = makeFuncCall(SystemFuncName("nextval"),
!                                                                       
list_make1(castnode),
!                                                                       -1);
                constraint = makeNode(Constraint);
                constraint->contype = CONSTR_DEFAULT;
                constraint->location = -1;
*** a/src/include/nodes/makefuncs.h
--- b/src/include/nodes/makefuncs.h
***************
*** 75,80 **** extern TypeName *makeTypeNameFromOid(Oid typeOid, int32 typmod);
--- 75,82 ----
  extern FuncExpr *makeFuncExpr(Oid funcid, Oid rettype, List *args,
                         Oid funccollid, Oid inputcollid, CoercionForm fformat);
  
+ extern FuncCall *makeFuncCall(List *name, List *args, int location);
+ 
  extern DefElem *makeDefElem(char *name, Node *arg);
  extern DefElem *makeDefElemExtended(char *nameSpace, char *name, Node *arg,
                                        DefElemAction defaction);
*** a/src/include/nodes/parsenodes.h
--- b/src/include/nodes/parsenodes.h
***************
*** 285,290 **** typedef struct CollateClause
--- 285,295 ----
   * construct *must* be an aggregate call.  Otherwise, it might be either an
   * aggregate or some other kind of function.  However, if OVER is present
   * it had better be an aggregate or window function.
+  *
+  * Normally, you'd initialize this via makeFuncCall() and then only
+  * change the parts of the struct its defaults don't match afterwards
+  * if needed.
+  *
   */
  typedef struct FuncCall
  {
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to