mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-30 19:00:29 +08:00
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.
This commit is contained in:
parent
a712570880
commit
27edff700e
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
/*
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user