提交 009b1809 编写于 作者: S sambitesh 提交者: GitHub

Cherry-pick 'ae47eb1' from upstream to fix Nested CTE errors (#3360)

Before this cherry-pick the below query would have errored out

WITH outermost(x) AS (
  SELECT 1
  UNION (WITH innermost as (SELECT 2)
         SELECT * FROM innermost
         UNION SELECT 3)
)
SELECT * FROM outermost;
Signed-off-by: NMelanie Plageman <mplageman@pivotal.io>
上级 4daa7c5f
......@@ -1861,6 +1861,7 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
SelectStmt *leftmostSelect;
int leftmostRTI;
Query *leftmostQuery;
WithClause *withClause;
SetOperationStmt *sostmt;
List *intoColNames = NIL;
List *sortClause;
......@@ -1910,11 +1911,13 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
limitOffset = stmt->limitOffset;
limitCount = stmt->limitCount;
lockingClause = stmt->lockingClause;
withClause = stmt->withClause;
stmt->sortClause = NIL;
stmt->limitOffset = NULL;
stmt->limitCount = NULL;
stmt->lockingClause = NIL;
stmt->withClause = NULL;
/* We don't support FOR UPDATE/SHARE with set ops at the moment. */
if (lockingClause)
......@@ -1923,10 +1926,10 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
errmsg("SELECT FOR UPDATE/SHARE is not allowed with UNION/INTERSECT/EXCEPT")));
/* process the WITH clause */
if (stmt->withClause)
if (withClause)
{
qry->hasRecursive = stmt->withClause->recursive;
qry->cteList = transformWithClause(pstate, stmt->withClause);
qry->hasRecursive = withClause->recursive;
qry->cteList = transformWithClause(pstate, withClause);
}
/*
......@@ -2289,7 +2292,7 @@ transformSetOperationTree_internal(ParseState *pstate, SelectStmt *stmt,
{
Assert(stmt->larg != NULL && stmt->rarg != NULL);
if (stmt->sortClause || stmt->limitOffset || stmt->limitCount ||
stmt->lockingClause)
stmt->lockingClause || stmt->withClause)
isLeaf = true;
else
isLeaf = false;
......
......@@ -677,6 +677,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 ALL.
* These don't make sense because it's impossible to figure out what
......
......@@ -788,3 +788,20 @@ from int4_tbl;
-2147483647
(5 rows)
--
-- test Nested CTE
--
WITH outermost(x) AS (
SELECT 1
UNION (WITH innermost as (SELECT 2)
SELECT * FROM innermost
UNION SELECT 3)
)
SELECT * FROM outermost;
x
---
1
2
3
(3 rows)
......@@ -457,3 +457,14 @@ from int4_tbl;
select ( with cte(foo) as ( values(f1) )
values((select foo from cte)) )
from int4_tbl;
--
-- test Nested CTE
--
WITH outermost(x) AS (
SELECT 1
UNION (WITH innermost as (SELECT 2)
SELECT * FROM innermost
UNION SELECT 3)
)
SELECT * FROM outermost;
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册