Skip to content

Commit 27edff7

Browse files
committed
Still another place to make the world safe for zero-column tables:
remove the ancient (and always pretty dodgy) assumption in parse_clause.c that a query can't have an empty targetlist.
1 parent a712570 commit 27edff7

File tree

3 files changed

+34
-30
lines changed

3 files changed

+34
-30
lines changed

src/backend/parser/analyze.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.299 2004/05/05 04:48:46 tgl Exp $
9+
* $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.300 2004/05/23 17:10:54 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -1929,17 +1929,17 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
19291929
*/
19301930
qry->sortClause = transformSortClause(pstate,
19311931
stmt->sortClause,
1932-
qry->targetList,
1932+
&qry->targetList,
19331933
true /* fix unknowns */ );
19341934

19351935
qry->groupClause = transformGroupClause(pstate,
19361936
stmt->groupClause,
1937-
qry->targetList,
1937+
&qry->targetList,
19381938
qry->sortClause);
19391939

19401940
qry->distinctClause = transformDistinctClause(pstate,
19411941
stmt->distinctClause,
1942-
qry->targetList,
1942+
&qry->targetList,
19431943
&qry->sortClause);
19441944

19451945
qry->limitOffset = transformLimitClause(pstate, stmt->limitOffset,
@@ -2145,7 +2145,7 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
21452145

21462146
qry->sortClause = transformSortClause(pstate,
21472147
sortClause,
2148-
qry->targetList,
2148+
&qry->targetList,
21492149
false /* no unknowns expected */ );
21502150

21512151
pstate->p_namespace = sv_namespace;

src/backend/parser/parse_clause.c

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.128 2004/04/18 18:12:57 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.129 2004/05/23 17:10:54 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -58,7 +58,7 @@ static Node *transformFromClauseItem(ParseState *pstate, Node *n,
5858
static Node *buildMergedJoinVar(ParseState *pstate, JoinType jointype,
5959
Var *l_colvar, Var *r_colvar);
6060
static TargetEntry *findTargetlistEntry(ParseState *pstate, Node *node,
61-
List *tlist, int clause);
61+
List **tlist, int clause);
6262

6363

6464
/*
@@ -1076,12 +1076,11 @@ transformLimitClause(ParseState *pstate, Node *clause,
10761076
* list as a "resjunk" node.
10771077
*
10781078
* node the ORDER BY, GROUP BY, or DISTINCT ON expression to be matched
1079-
* tlist the existing target list (NB: this will never be NIL, which is a
1080-
* good thing since we'd be unable to append to it if it were...)
1081-
* clause identifies clause type being processed.
1079+
* tlist the target list (passed by reference so we can append to it)
1080+
* clause identifies clause type being processed
10821081
*/
10831082
static TargetEntry *
1084-
findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause)
1083+
findTargetlistEntry(ParseState *pstate, Node *node, List **tlist, int clause)
10851084
{
10861085
TargetEntry *target_result = NULL;
10871086
List *tl;
@@ -1157,7 +1156,7 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause)
11571156

11581157
if (name != NULL)
11591158
{
1160-
foreach(tl, tlist)
1159+
foreach(tl, *tlist)
11611160
{
11621161
TargetEntry *tle = (TargetEntry *) lfirst(tl);
11631162
Resdom *resnode = tle->resdom;
@@ -1196,7 +1195,7 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause)
11961195
errmsg("non-integer constant in %s",
11971196
clauseText[clause])));
11981197
target_pos = intVal(val);
1199-
foreach(tl, tlist)
1198+
foreach(tl, *tlist)
12001199
{
12011200
TargetEntry *tle = (TargetEntry *) lfirst(tl);
12021201
Resdom *resnode = tle->resdom;
@@ -1224,7 +1223,7 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause)
12241223
*/
12251224
expr = transformExpr(pstate, node);
12261225

1227-
foreach(tl, tlist)
1226+
foreach(tl, *tlist)
12281227
{
12291228
TargetEntry *tle = (TargetEntry *) lfirst(tl);
12301229

@@ -1238,7 +1237,8 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause)
12381237
* that it will not be projected into the final tuple.
12391238
*/
12401239
target_result = transformTargetEntry(pstate, node, expr, NULL, true);
1241-
lappend(tlist, target_result);
1240+
1241+
*tlist = lappend(*tlist, target_result);
12421242

12431243
return target_result;
12441244
}
@@ -1247,10 +1247,13 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause)
12471247
/*
12481248
* transformGroupClause -
12491249
* transform a GROUP BY clause
1250+
*
1251+
* GROUP BY items will be added to the targetlist (as resjunk columns)
1252+
* if not already present, so the targetlist must be passed by reference.
12501253
*/
12511254
List *
12521255
transformGroupClause(ParseState *pstate, List *grouplist,
1253-
List *targetlist, List *sortClause)
1256+
List **targetlist, List *sortClause)
12541257
{
12551258
List *glist = NIL,
12561259
*gl;
@@ -1304,7 +1307,7 @@ transformGroupClause(ParseState *pstate, List *grouplist,
13041307
}
13051308

13061309
grpcl = makeNode(GroupClause);
1307-
grpcl->tleSortGroupRef = assignSortGroupRef(tle, targetlist);
1310+
grpcl->tleSortGroupRef = assignSortGroupRef(tle, *targetlist);
13081311
grpcl->sortop = ordering_op;
13091312
glist = lappend(glist, grpcl);
13101313
}
@@ -1315,11 +1318,14 @@ transformGroupClause(ParseState *pstate, List *grouplist,
13151318
/*
13161319
* transformSortClause -
13171320
* transform an ORDER BY clause
1321+
*
1322+
* ORDER BY items will be added to the targetlist (as resjunk columns)
1323+
* if not already present, so the targetlist must be passed by reference.
13181324
*/
13191325
List *
13201326
transformSortClause(ParseState *pstate,
13211327
List *orderlist,
1322-
List *targetlist,
1328+
List **targetlist,
13231329
bool resolveUnknown)
13241330
{
13251331
List *sortlist = NIL;
@@ -1334,7 +1340,7 @@ transformSortClause(ParseState *pstate,
13341340
targetlist, ORDER_CLAUSE);
13351341

13361342
sortlist = addTargetToSortList(pstate, tle,
1337-
sortlist, targetlist,
1343+
sortlist, *targetlist,
13381344
sortby->sortby_kind,
13391345
sortby->useOp,
13401346
resolveUnknown);
@@ -1348,13 +1354,11 @@ transformSortClause(ParseState *pstate,
13481354
* transform a DISTINCT or DISTINCT ON clause
13491355
*
13501356
* Since we may need to add items to the query's sortClause list, that list
1351-
* is passed by reference. We might also need to add items to the query's
1352-
* targetlist, but we assume that cannot be empty initially, so we can
1353-
* lappend to it even though the pointer is passed by value.
1357+
* is passed by reference. Likewise for the targetlist.
13541358
*/
13551359
List *
13561360
transformDistinctClause(ParseState *pstate, List *distinctlist,
1357-
List *targetlist, List **sortClause)
1361+
List **targetlist, List **sortClause)
13581362
{
13591363
List *result = NIL;
13601364
List *slitem;
@@ -1377,7 +1381,7 @@ transformDistinctClause(ParseState *pstate, List *distinctlist,
13771381
*/
13781382
*sortClause = addAllTargetsToSortList(pstate,
13791383
*sortClause,
1380-
targetlist,
1384+
*targetlist,
13811385
true);
13821386

13831387
/*
@@ -1390,7 +1394,7 @@ transformDistinctClause(ParseState *pstate, List *distinctlist,
13901394
foreach(slitem, *sortClause)
13911395
{
13921396
SortClause *scl = (SortClause *) lfirst(slitem);
1393-
TargetEntry *tle = get_sortgroupclause_tle(scl, targetlist);
1397+
TargetEntry *tle = get_sortgroupclause_tle(scl, *targetlist);
13941398

13951399
if (tle->resdom->resjunk)
13961400
ereport(ERROR,
@@ -1442,7 +1446,7 @@ transformDistinctClause(ParseState *pstate, List *distinctlist,
14421446
else
14431447
{
14441448
*sortClause = addTargetToSortList(pstate, tle,
1445-
*sortClause, targetlist,
1449+
*sortClause, *targetlist,
14461450
SORTBY_ASC, NIL, true);
14471451

14481452
/*

src/include/parser/parse_clause.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/parser/parse_clause.h,v 1.40 2004/01/23 02:13:12 neilc Exp $
10+
* $PostgreSQL: pgsql/src/include/parser/parse_clause.h,v 1.41 2004/05/23 17:10:54 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -27,11 +27,11 @@ extern Node *transformWhereClause(ParseState *pstate, Node *clause,
2727
extern Node *transformLimitClause(ParseState *pstate, Node *clause,
2828
const char *constructName);
2929
extern List *transformGroupClause(ParseState *pstate, List *grouplist,
30-
List *targetlist, List *sortClause);
30+
List **targetlist, List *sortClause);
3131
extern List *transformSortClause(ParseState *pstate, List *orderlist,
32-
List *targetlist, bool resolveUnknown);
32+
List **targetlist, bool resolveUnknown);
3333
extern List *transformDistinctClause(ParseState *pstate, List *distinctlist,
34-
List *targetlist, List **sortClause);
34+
List **targetlist, List **sortClause);
3535

3636
extern List *addAllTargetsToSortList(ParseState *pstate,
3737
List *sortlist, List *targetlist,

0 commit comments

Comments
 (0)