OSDN Git Service

Fix GetCTEForRTE() to deal with the possibility that the RTE it's given came
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 6 Oct 2008 15:15:22 +0000 (15:15 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 6 Oct 2008 15:15:22 +0000 (15:15 +0000)
from a query level above the current ParseState.

src/backend/parser/analyze.c
src/backend/parser/parse_relation.c
src/backend/parser/parse_target.c
src/include/parser/parse_relation.h

index 8934c04..8e762f8 100644 (file)
@@ -17,7 +17,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- *     $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.380 2008/10/04 21:56:54 tgl Exp $
+ *     $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.381 2008/10/06 15:15:22 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1896,7 +1896,7 @@ transformLockingClause(ParseState *pstate, Query *qry, LockingClause *lc)
                                                        ereport(ERROR,
                                                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                                                                         errmsg("SELECT FOR UPDATE/SHARE cannot be applied to an outer-level WITH query")));
-                                               cte = GetCTEForRTE(pstate, rte);
+                                               cte = GetCTEForRTE(pstate, rte, -1);
                                                /* should be analyzed by now */
                                                Assert(IsA(cte->ctequery, Query));
                                                transformLockingClause(pstate,
@@ -1989,7 +1989,7 @@ transformLockingClause(ParseState *pstate, Query *qry, LockingClause *lc)
                                                                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                                                                                         errmsg("SELECT FOR UPDATE/SHARE cannot be applied to an outer-level WITH query"),
                                                                                         parser_errposition(pstate, thisrel->location)));
-                                                               cte = GetCTEForRTE(pstate, rte);
+                                                               cte = GetCTEForRTE(pstate, rte, -1);
                                                                /* should be analyzed by now */
                                                                Assert(IsA(cte->ctequery, Query));
                                                                transformLockingClause(pstate,
index 870911c..14ddd34 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.137 2008/10/06 02:12:56 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.138 2008/10/06 15:15:22 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -371,15 +371,23 @@ GetRTEByRangeTablePosn(ParseState *pstate,
 
 /*
  * Fetch the CTE for a CTE-reference RTE.
+ *
+ * rtelevelsup is the number of query levels above the given pstate that the
+ * RTE came from.  Callers that don't have this information readily available
+ * may pass -1 instead.
  */
 CommonTableExpr *
-GetCTEForRTE(ParseState *pstate, RangeTblEntry *rte)
+GetCTEForRTE(ParseState *pstate, RangeTblEntry *rte, int rtelevelsup)
 {
        Index           levelsup;
        ListCell   *lc;
 
+       /* Determine RTE's levelsup if caller didn't know it */
+       if (rtelevelsup < 0)
+               (void) RTERangeTablePosn(pstate, rte, &rtelevelsup);
+
        Assert(rte->rtekind == RTE_CTE);
-       levelsup = rte->ctelevelsup;
+       levelsup = rte->ctelevelsup + rtelevelsup;
        while (levelsup-- > 0)
        {
                pstate = pstate->parentParseState;
index ed54abe..d83caab 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.166 2008/10/05 22:20:16 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.167 2008/10/06 15:15:22 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -308,7 +308,7 @@ markTargetListOrigin(ParseState *pstate, TargetEntry *tle,
                         */
                        if (attnum != InvalidAttrNumber && !rte->self_reference)
                        {
-                               CommonTableExpr *cte = GetCTEForRTE(pstate, rte);
+                               CommonTableExpr *cte = GetCTEForRTE(pstate, rte, netlevelsup);
                                TargetEntry *ste;
 
                                /* should be analyzed by now */
@@ -1206,7 +1206,7 @@ expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
                        /* CTE reference: examine subquery's output expr */
                        if (!rte->self_reference)
                        {
-                               CommonTableExpr *cte = GetCTEForRTE(pstate, rte);
+                               CommonTableExpr *cte = GetCTEForRTE(pstate, rte, netlevelsup);
                                TargetEntry *ste;
 
                                /* should be analyzed by now */
@@ -1230,7 +1230,9 @@ expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
 
                                        MemSet(&mypstate, 0, sizeof(mypstate));
                                        /* this loop must work, since GetCTEForRTE did */
-                                       for (levelsup = 0; levelsup < rte->ctelevelsup; levelsup++)
+                                       for (levelsup = 0;
+                                                levelsup < rte->ctelevelsup + netlevelsup;
+                                                levelsup++)
                                                pstate = pstate->parentParseState;
                                        mypstate.parentParseState = pstate;
                                        mypstate.p_rtable = ((Query *) cte->ctequery)->rtable;
index f5212c4..84cfa97 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/parser/parse_relation.h,v 1.60 2008/10/06 02:12:56 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/parser/parse_relation.h,v 1.61 2008/10/06 15:15:22 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -34,7 +34,8 @@ extern int RTERangeTablePosn(ParseState *pstate,
 extern RangeTblEntry *GetRTEByRangeTablePosn(ParseState *pstate,
                                           int varno,
                                           int sublevels_up);
-extern CommonTableExpr *GetCTEForRTE(ParseState *pstate, RangeTblEntry *rte);
+extern CommonTableExpr *GetCTEForRTE(ParseState *pstate, RangeTblEntry *rte,
+                                                                        int rtelevelsup);
 extern Node *scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte,
                                 char *colname, int location);
 extern Node *colNameToVar(ParseState *pstate, char *colname, bool localonly,