diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2003-02-13 18:29:07 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2003-02-13 18:29:07 +0000 |
commit | 5f5da0a6cb865599ca159509ed239d577a285fff (patch) | |
tree | 500722d94e7f8809aa7f5d761b2261c966a37dd8 /src/backend/parser/parse_expr.c | |
parent | 8d33f80fc43853b6d6f63fac42b19b5ceba2e306 (diff) | |
download | postgresql-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.c | 21 |
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: |