aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_expr.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2003-02-13 18:29:07 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2003-02-13 18:29:07 +0000
commit5f5da0a6cb865599ca159509ed239d577a285fff (patch)
tree500722d94e7f8809aa7f5d761b2261c966a37dd8 /src/backend/parser/parse_expr.c
parent8d33f80fc43853b6d6f63fac42b19b5ceba2e306 (diff)
downloadpostgresql-5f5da0a6cb865599ca159509ed239d577a285fff.tar.gz
postgresql-5f5da0a6cb865599ca159509ed239d577a285fff.zip
transformExpr() was missing some cases it ought to allow; per report
from Greg Stark. Also, twiddle the FuncCall case to not scribble on the input structure, which was the proximate cause of the problem. Someday we ought to fix things so that transformExpr() isn't called on already-transformed trees ...
Diffstat (limited to 'src/backend/parser/parse_expr.c')
-rw-r--r--src/backend/parser/parse_expr.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index ec95870ec9e..f059a1db2c0 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.144 2003/02/10 04:44:46 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.145 2003/02/13 18:29:07 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -322,15 +322,23 @@ transformExpr(ParseState *pstate, Node *expr)
case T_FuncCall:
{
FuncCall *fn = (FuncCall *) expr;
+ List *targs;
List *args;
- /* transform the list of arguments */
- foreach(args, fn->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.
+ */
+ targs = listCopy(fn->args);
+ foreach(args, targs)
+ {
lfirst(args) = transformExpr(pstate,
(Node *) lfirst(args));
+ }
result = ParseFuncOrColumn(pstate,
fn->funcname,
- fn->args,
+ targs,
fn->agg_star,
fn->agg_distinct,
false);
@@ -664,12 +672,15 @@ transformExpr(ParseState *pstate, Node *expr)
* taking a conservative approach, and only accepting node
* types that are demonstrably necessary to accept.
*********************************************/
- case T_Expr:
case T_Var:
case T_Const:
case T_Param:
case T_Aggref:
case T_ArrayRef:
+ case T_FuncExpr:
+ case T_OpExpr:
+ case T_DistinctExpr:
+ case T_BoolExpr:
case T_FieldSelect:
case T_RelabelType:
case T_CoerceToDomain: