aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_cte.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2012-07-31 17:56:27 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2012-07-31 17:56:27 -0400
commit3786b9b4668743b99e837fe276e14be1f1bdfde9 (patch)
tree6674d832fc55b76d4391d2b647b9e11b48ce134c /src/backend/parser/parse_cte.c
parent63aba79c7f1f06422b22e2b44fdcb563bbc3f7a5 (diff)
downloadpostgresql-3786b9b4668743b99e837fe276e14be1f1bdfde9.tar.gz
postgresql-3786b9b4668743b99e837fe276e14be1f1bdfde9.zip
Fix WITH attached to a nested set operation (UNION/INTERSECT/EXCEPT).
Parse analysis neglected to cover the case of a WITH clause attached to an intermediate-level set operation; it only handled WITH at the top level or WITH attached to a leaf-level SELECT. Per report from Adam Mackler. In HEAD, I rearranged the order of SelectStmt's fields to put withClause with the other fields that can appear on non-leaf SelectStmts. In back branches, leave it alone to avoid a possible ABI break for third-party code. Back-patch to 8.4 where WITH support was added.
Diffstat (limited to 'src/backend/parser/parse_cte.c')
-rw-r--r--src/backend/parser/parse_cte.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/src/backend/parser/parse_cte.c b/src/backend/parser/parse_cte.c
index 2a7d4cd0724..d04fb6dec14 100644
--- a/src/backend/parser/parse_cte.c
+++ b/src/backend/parser/parse_cte.c
@@ -678,6 +678,18 @@ checkWellFormedRecursion(CteState *cstate)
if (cstate->selfrefcount != 1) /* shouldn't happen */
elog(ERROR, "missing recursive reference");
+ /* WITH mustn't contain self-reference, either */
+ if (stmt->withClause)
+ {
+ cstate->curitem = i;
+ cstate->innerwiths = NIL;
+ cstate->selfrefcount = 0;
+ cstate->context = RECURSION_SUBLINK;
+ checkWellFormedRecursionWalker((Node *) stmt->withClause->ctes,
+ cstate);
+ Assert(cstate->innerwiths == NIL);
+ }
+
/*
* Disallow ORDER BY and similar decoration atop the UNION. These
* don't make sense because it's impossible to figure out what they
@@ -933,7 +945,7 @@ checkWellFormedSelectStmt(SelectStmt *stmt, CteState *cstate)
cstate);
checkWellFormedRecursionWalker((Node *) stmt->lockingClause,
cstate);
- break;
+ /* stmt->withClause is intentionally ignored here */
break;
case SETOP_EXCEPT:
if (stmt->all)
@@ -952,6 +964,7 @@ checkWellFormedSelectStmt(SelectStmt *stmt, CteState *cstate)
cstate);
checkWellFormedRecursionWalker((Node *) stmt->lockingClause,
cstate);
+ /* stmt->withClause is intentionally ignored here */
break;
default:
elog(ERROR, "unrecognized set op: %d",