提交 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) ...@@ -1861,6 +1861,7 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
SelectStmt *leftmostSelect; SelectStmt *leftmostSelect;
int leftmostRTI; int leftmostRTI;
Query *leftmostQuery; Query *leftmostQuery;
WithClause *withClause;
SetOperationStmt *sostmt; SetOperationStmt *sostmt;
List *intoColNames = NIL; List *intoColNames = NIL;
List *sortClause; List *sortClause;
...@@ -1910,11 +1911,13 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt) ...@@ -1910,11 +1911,13 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
limitOffset = stmt->limitOffset; limitOffset = stmt->limitOffset;
limitCount = stmt->limitCount; limitCount = stmt->limitCount;
lockingClause = stmt->lockingClause; lockingClause = stmt->lockingClause;
withClause = stmt->withClause;
stmt->sortClause = NIL; stmt->sortClause = NIL;
stmt->limitOffset = NULL; stmt->limitOffset = NULL;
stmt->limitCount = NULL; stmt->limitCount = NULL;
stmt->lockingClause = NIL; stmt->lockingClause = NIL;
stmt->withClause = NULL;
/* We don't support FOR UPDATE/SHARE with set ops at the moment. */ /* We don't support FOR UPDATE/SHARE with set ops at the moment. */
if (lockingClause) if (lockingClause)
...@@ -1923,10 +1926,10 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt) ...@@ -1923,10 +1926,10 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
errmsg("SELECT FOR UPDATE/SHARE is not allowed with UNION/INTERSECT/EXCEPT"))); errmsg("SELECT FOR UPDATE/SHARE is not allowed with UNION/INTERSECT/EXCEPT")));
/* process the WITH clause */ /* process the WITH clause */
if (stmt->withClause) if (withClause)
{ {
qry->hasRecursive = stmt->withClause->recursive; qry->hasRecursive = withClause->recursive;
qry->cteList = transformWithClause(pstate, stmt->withClause); qry->cteList = transformWithClause(pstate, withClause);
} }
/* /*
...@@ -2289,7 +2292,7 @@ transformSetOperationTree_internal(ParseState *pstate, SelectStmt *stmt, ...@@ -2289,7 +2292,7 @@ transformSetOperationTree_internal(ParseState *pstate, SelectStmt *stmt,
{ {
Assert(stmt->larg != NULL && stmt->rarg != NULL); Assert(stmt->larg != NULL && stmt->rarg != NULL);
if (stmt->sortClause || stmt->limitOffset || stmt->limitCount || if (stmt->sortClause || stmt->limitOffset || stmt->limitCount ||
stmt->lockingClause) stmt->lockingClause || stmt->withClause)
isLeaf = true; isLeaf = true;
else else
isLeaf = false; isLeaf = false;
......
...@@ -677,6 +677,18 @@ checkWellFormedRecursion(CteState *cstate) ...@@ -677,6 +677,18 @@ checkWellFormedRecursion(CteState *cstate)
if (cstate->selfrefcount != 1) /* shouldn't happen */ if (cstate->selfrefcount != 1) /* shouldn't happen */
elog(ERROR, "missing recursive reference"); 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. * Disallow ORDER BY and similar decoration atop the UNION ALL.
* These don't make sense because it's impossible to figure out what * These don't make sense because it's impossible to figure out what
......
...@@ -788,3 +788,20 @@ from int4_tbl; ...@@ -788,3 +788,20 @@ from int4_tbl;
-2147483647 -2147483647
(5 rows) (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; ...@@ -457,3 +457,14 @@ from int4_tbl;
select ( with cte(foo) as ( values(f1) ) select ( with cte(foo) as ( values(f1) )
values((select foo from cte)) ) values((select foo from cte)) )
from int4_tbl; 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.
先完成此消息的编辑!
想要评论请 注册