OSDN Git Service

Still another place to make the world safe for zero-column tables:
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 23 May 2004 17:10:54 +0000 (17:10 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 23 May 2004 17:10:54 +0000 (17:10 +0000)
remove the ancient (and always pretty dodgy) assumption in parse_clause.c
that a query can't have an empty targetlist.

src/backend/parser/analyze.c
src/backend/parser/parse_clause.c
src/include/parser/parse_clause.h

index 4a251b6..2b1eddb 100644 (file)
@@ -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;
index c15dd9b..2c6e994 100644 (file)
@@ -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);
 
                                /*
index fbe1f06..923f2e2 100644 (file)
@@ -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,