Tweak the order of processing of WITH clauses so that they are processed
authorTom Lane
Fri, 12 Feb 2010 22:48:56 +0000 (22:48 +0000)
committerTom Lane
Fri, 12 Feb 2010 22:48:56 +0000 (22:48 +0000)
before we start analyzing the parent statement.  This is to make it
more clear that the WITH isn't affected by anything in the parent.
I don't believe there's any actual bug here, because the stuff that
was being done before WITH didn't affect subqueries; but it's certainly
a potential for error (and apparently misled Marko into committing some
real errors...).

src/backend/parser/analyze.c

index efa4e47b1a46fb7972ac6f482dec9a1419df7df9..027cb972ee7b6c7c9aa9bbc15a6883aebadf9f54 100644 (file)
@@ -17,7 +17,7 @@
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.400 2010/01/15 22:36:33 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.401 2010/02/12 22:48:56 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -783,19 +783,19 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
 
    qry->commandType = CMD_SELECT;
 
-   /* make FOR UPDATE/FOR SHARE info available to addRangeTableEntry */
-   pstate->p_locking_clause = stmt->lockingClause;
-
-   /* make WINDOW info available for window functions, too */
-   pstate->p_windowdefs = stmt->windowClause;
-
-   /* process the WITH clause */
+   /* process the WITH clause independently of all else */
    if (stmt->withClause)
    {
        qry->hasRecursive = stmt->withClause->recursive;
        qry->cteList = transformWithClause(pstate, stmt->withClause);
    }
 
+   /* make FOR UPDATE/FOR SHARE info available to addRangeTableEntry */
+   pstate->p_locking_clause = stmt->lockingClause;
+
+   /* make WINDOW info available for window functions, too */
+   pstate->p_windowdefs = stmt->windowClause;
+
    /* process the FROM clause */
    transformFromClause(pstate, stmt->fromClause);
 
@@ -929,7 +929,7 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt)
    Assert(stmt->windowClause == NIL);
    Assert(stmt->op == SETOP_NONE);
 
-   /* process the WITH clause */
+   /* process the WITH clause independently of all else */
    if (stmt->withClause)
    {
        qry->hasRecursive = stmt->withClause->recursive;
@@ -1149,6 +1149,13 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
 
    qry->commandType = CMD_SELECT;
 
+   /* process the WITH clause independently of all else */
+   if (stmt->withClause)
+   {
+       qry->hasRecursive = stmt->withClause->recursive;
+       qry->cteList = transformWithClause(pstate, stmt->withClause);
+   }
+
    /*
     * Find leftmost leaf SelectStmt; extract the one-time-only items from it
     * and from the top-level node.
@@ -1188,13 +1195,6 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                 errmsg("SELECT FOR UPDATE/SHARE is not allowed with UNION/INTERSECT/EXCEPT")));
 
-   /* process the WITH clause */
-   if (stmt->withClause)
-   {
-       qry->hasRecursive = stmt->withClause->recursive;
-       qry->cteList = transformWithClause(pstate, stmt->withClause);
-   }
-
    /*
     * Recursively transform the components of the tree.
     */