diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index ec95870ec9e5f3a75c777419752393cfdffd5b8d..f059a1db2c098cfa29e38f9994218b90728846b0 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: