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 <[email protected]> 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 <[email protected]> http://fetter.org/ Phone: +1 415 235 3778 AIM: dfetter666 Yahoo!: dfetter Skype: davidfetter XMPP: [email protected] 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 ([email protected]) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
