aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_expr.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2008-07-16 01:30:23 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2008-07-16 01:30:23 +0000
commitd89737d31c03d90a2b0412e63953493576a2a3d7 (patch)
tree0afc63e59fae7ec3c53339641a6f65e6a04733d2 /src/backend/parser/parse_expr.c
parent2c773296f88fe800315ca1bf131287662ecef999 (diff)
downloadpostgresql-d89737d31c03d90a2b0412e63953493576a2a3d7.tar.gz
postgresql-d89737d31c03d90a2b0412e63953493576a2a3d7.zip
Support "variadic" functions, which can accept a variable number of arguments
so long as all the trailing arguments are of the same (non-array) type. The function receives them as a single array argument (which is why they have to all be the same type). It might be useful to extend this facility to aggregates, but this patch doesn't do that. This patch imposes a noticeable slowdown on function lookup --- a follow-on patch will fix that by adding a redundant column to pg_proc. Pavel Stehule
Diffstat (limited to 'src/backend/parser/parse_expr.c')
-rw-r--r--src/backend/parser/parse_expr.c36
1 files changed, 16 insertions, 20 deletions
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 362108ba3fa..8addb53e51e 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.228 2008/04/29 14:59:16 alvherre Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.229 2008/07/16 01:30:22 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -358,8 +358,8 @@ transformIndirection(ParseState *pstate, Node *basenode, List *indirection)
result = ParseFuncOrColumn(pstate,
list_make1(n),
list_make1(result),
- false, false, true,
- -1);
+ false, false, false,
+ true, -1);
}
}
/* process trailing subscripts, if any */
@@ -481,8 +481,8 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
node = ParseFuncOrColumn(pstate,
list_make1(makeString(name2)),
list_make1(node),
- false, false, true,
- cref->location);
+ false, false, false,
+ true, cref->location);
}
break;
}
@@ -511,8 +511,8 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
node = ParseFuncOrColumn(pstate,
list_make1(makeString(name3)),
list_make1(node),
- false, false, true,
- cref->location);
+ false, false, false,
+ true, cref->location);
}
break;
}
@@ -552,8 +552,8 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
node = ParseFuncOrColumn(pstate,
list_make1(makeString(name4)),
list_make1(node),
- false, false, true,
- cref->location);
+ false, false, false,
+ true, cref->location);
}
break;
}
@@ -1018,25 +1018,21 @@ transformFuncCall(ParseState *pstate, FuncCall *fn)
List *targs;
ListCell *args;
- /*
- * Transform the list of arguments. We use a shallow list copy and then
- * transform-in-place to avoid O(N^2) behavior from repeated lappend's.
- *
- * XXX: repeated lappend() would no longer result in O(n^2) behavior;
- * worth reconsidering this design?
- */
- targs = list_copy(fn->args);
- foreach(args, targs)
+ /* Transform the list of arguments ... */
+ targs = NIL;
+ foreach(args, fn->args)
{
- lfirst(args) = transformExpr(pstate,
- (Node *) lfirst(args));
+ targs = lappend(targs, transformExpr(pstate,
+ (Node *) lfirst(args)));
}
+ /* ... and hand off to ParseFuncOrColumn */
return ParseFuncOrColumn(pstate,
fn->funcname,
targs,
fn->agg_star,
fn->agg_distinct,
+ fn->func_variadic,
false,
fn->location);
}