diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 4a251b63de4666c1155ab6dcb81b85e273f233d2..2b1eddbcf09716e70af213abc2d11284e4267397 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.299 2004/05/05 04:48:46 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.300 2004/05/23 17:10:54 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1929,17 +1929,17 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt) */ qry->sortClause = transformSortClause(pstate, stmt->sortClause, - qry->targetList, + &qry->targetList, true /* fix unknowns */ ); qry->groupClause = transformGroupClause(pstate, stmt->groupClause, - qry->targetList, + &qry->targetList, qry->sortClause); qry->distinctClause = transformDistinctClause(pstate, stmt->distinctClause, - qry->targetList, + &qry->targetList, &qry->sortClause); qry->limitOffset = transformLimitClause(pstate, stmt->limitOffset, @@ -2145,7 +2145,7 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt) qry->sortClause = transformSortClause(pstate, sortClause, - qry->targetList, + &qry->targetList, false /* no unknowns expected */ ); pstate->p_namespace = sv_namespace; diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c index c15dd9b78922d269952b28c0cf995ecbacb1aadc..2c6e99428997906ac90522481034d39d65d58ee4 100644 --- a/src/backend/parser/parse_clause.c +++ b/src/backend/parser/parse_clause.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.128 2004/04/18 18:12:57 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.129 2004/05/23 17:10:54 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -58,7 +58,7 @@ static Node *transformFromClauseItem(ParseState *pstate, Node *n, static Node *buildMergedJoinVar(ParseState *pstate, JoinType jointype, Var *l_colvar, Var *r_colvar); static TargetEntry *findTargetlistEntry(ParseState *pstate, Node *node, - List *tlist, int clause); + List **tlist, int clause); /* @@ -1076,12 +1076,11 @@ transformLimitClause(ParseState *pstate, Node *clause, * list as a "resjunk" node. * * node the ORDER BY, GROUP BY, or DISTINCT ON expression to be matched - * tlist the existing target list (NB: this will never be NIL, which is a - * good thing since we'd be unable to append to it if it were...) - * clause identifies clause type being processed. + * tlist the target list (passed by reference so we can append to it) + * clause identifies clause type being processed */ static TargetEntry * -findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause) +findTargetlistEntry(ParseState *pstate, Node *node, List **tlist, int clause) { TargetEntry *target_result = NULL; List *tl; @@ -1157,7 +1156,7 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause) if (name != NULL) { - foreach(tl, tlist) + foreach(tl, *tlist) { TargetEntry *tle = (TargetEntry *) lfirst(tl); Resdom *resnode = tle->resdom; @@ -1196,7 +1195,7 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause) errmsg("non-integer constant in %s", clauseText[clause]))); target_pos = intVal(val); - foreach(tl, tlist) + foreach(tl, *tlist) { TargetEntry *tle = (TargetEntry *) lfirst(tl); Resdom *resnode = tle->resdom; @@ -1224,7 +1223,7 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause) */ expr = transformExpr(pstate, node); - foreach(tl, tlist) + foreach(tl, *tlist) { TargetEntry *tle = (TargetEntry *) lfirst(tl); @@ -1238,7 +1237,8 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause) * that it will not be projected into the final tuple. */ target_result = transformTargetEntry(pstate, node, expr, NULL, true); - lappend(tlist, target_result); + + *tlist = lappend(*tlist, target_result); return target_result; } @@ -1247,10 +1247,13 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause) /* * transformGroupClause - * transform a GROUP BY clause + * + * GROUP BY items will be added to the targetlist (as resjunk columns) + * if not already present, so the targetlist must be passed by reference. */ List * transformGroupClause(ParseState *pstate, List *grouplist, - List *targetlist, List *sortClause) + List **targetlist, List *sortClause) { List *glist = NIL, *gl; @@ -1304,7 +1307,7 @@ transformGroupClause(ParseState *pstate, List *grouplist, } grpcl = makeNode(GroupClause); - grpcl->tleSortGroupRef = assignSortGroupRef(tle, targetlist); + grpcl->tleSortGroupRef = assignSortGroupRef(tle, *targetlist); grpcl->sortop = ordering_op; glist = lappend(glist, grpcl); } @@ -1315,11 +1318,14 @@ transformGroupClause(ParseState *pstate, List *grouplist, /* * transformSortClause - * transform an ORDER BY clause + * + * ORDER BY items will be added to the targetlist (as resjunk columns) + * if not already present, so the targetlist must be passed by reference. */ List * transformSortClause(ParseState *pstate, List *orderlist, - List *targetlist, + List **targetlist, bool resolveUnknown) { List *sortlist = NIL; @@ -1334,7 +1340,7 @@ transformSortClause(ParseState *pstate, targetlist, ORDER_CLAUSE); sortlist = addTargetToSortList(pstate, tle, - sortlist, targetlist, + sortlist, *targetlist, sortby->sortby_kind, sortby->useOp, resolveUnknown); @@ -1348,13 +1354,11 @@ transformSortClause(ParseState *pstate, * transform a DISTINCT or DISTINCT ON clause * * Since we may need to add items to the query's sortClause list, that list - * is passed by reference. We might also need to add items to the query's - * targetlist, but we assume that cannot be empty initially, so we can - * lappend to it even though the pointer is passed by value. + * is passed by reference. Likewise for the targetlist. */ List * transformDistinctClause(ParseState *pstate, List *distinctlist, - List *targetlist, List **sortClause) + List **targetlist, List **sortClause) { List *result = NIL; List *slitem; @@ -1377,7 +1381,7 @@ transformDistinctClause(ParseState *pstate, List *distinctlist, */ *sortClause = addAllTargetsToSortList(pstate, *sortClause, - targetlist, + *targetlist, true); /* @@ -1390,7 +1394,7 @@ transformDistinctClause(ParseState *pstate, List *distinctlist, foreach(slitem, *sortClause) { SortClause *scl = (SortClause *) lfirst(slitem); - TargetEntry *tle = get_sortgroupclause_tle(scl, targetlist); + TargetEntry *tle = get_sortgroupclause_tle(scl, *targetlist); if (tle->resdom->resjunk) ereport(ERROR, @@ -1442,7 +1446,7 @@ transformDistinctClause(ParseState *pstate, List *distinctlist, else { *sortClause = addTargetToSortList(pstate, tle, - *sortClause, targetlist, + *sortClause, *targetlist, SORTBY_ASC, NIL, true); /* diff --git a/src/include/parser/parse_clause.h b/src/include/parser/parse_clause.h index fbe1f06c22aadf4a089c2de53ea3a4cbef82075a..923f2e23af4367bf5fa891e17c50d93e2947936d 100644 --- a/src/include/parser/parse_clause.h +++ b/src/include/parser/parse_clause.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/parser/parse_clause.h,v 1.40 2004/01/23 02:13:12 neilc Exp $ + * $PostgreSQL: pgsql/src/include/parser/parse_clause.h,v 1.41 2004/05/23 17:10:54 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -27,11 +27,11 @@ extern Node *transformWhereClause(ParseState *pstate, Node *clause, extern Node *transformLimitClause(ParseState *pstate, Node *clause, const char *constructName); extern List *transformGroupClause(ParseState *pstate, List *grouplist, - List *targetlist, List *sortClause); + List **targetlist, List *sortClause); extern List *transformSortClause(ParseState *pstate, List *orderlist, - List *targetlist, bool resolveUnknown); + List **targetlist, bool resolveUnknown); extern List *transformDistinctClause(ParseState *pstate, List *distinctlist, - List *targetlist, List **sortClause); + List **targetlist, List **sortClause); extern List *addAllTargetsToSortList(ParseState *pstate, List *sortlist, List *targetlist,