fix connect by nocycle bug

This commit is contained in:
chenxiaobin19
2022-11-21 15:49:28 +08:00
parent 3f37cda306
commit ac3f9ce7e1
3 changed files with 44 additions and 12 deletions

View File

@ -648,16 +648,16 @@ TupleTableSlot* ExecStartWithOp(StartWithOpState *node)
break;
}
tuplestore_puttupleslot(node->sw_workingTable, dstSlot);
/*
* check we need stop infinit recursive iteration if NOCYCLE is specified in
* ConnectByExpr, then return. Also, in case of cycle-report-error the ereport
* is processed inside of CheckCycleException()
*/
if (CheckCycleExeception(node, dstSlot)) {
break;
continue;
}
tuplestore_puttupleslot(node->sw_workingTable, dstSlot);
}
/* report we have done material step for current StartWithOp node */

View File

@ -552,8 +552,7 @@ select *, connect_by_iscycle from t1 start with c1=1 connect by nocycle prior c1
c1 | c2 | c3 | connect_by_iscycle
----+----+----+--------------------
1 | 1 | 1 | 0
1 | 1 | 1 | 1
(2 rows)
(1 row)
insert into t1 values(1,1,1);
insert into t1 values(2,2,2);
@ -562,8 +561,7 @@ select *, connect_by_iscycle from t1 start with c1=1 connect by nocycle prior c1
----+----+----+--------------------
1 | 1 | 1 | 0
1 | 1 | 1 | 0
1 | 1 | 1 | 1
(3 rows)
(2 rows)
insert into t1 values(1,NULL,1);
select *, connect_by_iscycle from t1 start with c1=1 connect by nocycle prior c1=c2 order siblings by 1,2 nulls first;
@ -572,8 +570,7 @@ select *, connect_by_iscycle from t1 start with c1=1 connect by nocycle prior c1
1 | | 1 | 0
1 | 1 | 1 | 0
1 | 1 | 1 | 0
1 | 1 | 1 | 1
(4 rows)
(3 rows)
select *, connect_by_iscycle from t1 start with c1=1 connect by nocycle prior c1=c2 order siblings by 1,2 nulls last;
c1 | c2 | c3 | connect_by_iscycle
@ -581,8 +578,7 @@ select *, connect_by_iscycle from t1 start with c1=1 connect by nocycle prior c1
1 | 1 | 1 | 0
1 | 1 | 1 | 0
1 | | 1 | 0
1 | 1 | 1 | 1
(4 rows)
(3 rows)
delete from t1 where c2 is null;
select *, connect_by_iscycle from t1 start with c1<3 connect by nocycle prior c1<c2 order siblings by NLSSORT (c1, ' NLS_SORT = generic_m_ci ');
@ -1901,3 +1897,33 @@ SELECT * FROM RLTEST CONNECT BY PRIOR B=A OR (MOD(ROWNUM+1,2) = 0);
ERROR: column specified by prior cannot concide with ROWNUM/LEVEL.
DETAIL: Unsupported node type: 900.
DROP TABLE RLTEST;
create table nocycle_tbl(id int, lid int, name text);
insert into nocycle_tbl values (1,3,'A'),(2,1,'B'),(3,2,'C'),(4,2,'D');
select * from nocycle_tbl connect by nocycle prior id=lid start with id=1;
id | lid | name
----+-----+------
1 | 3 | A
2 | 1 | B
3 | 2 | C
4 | 2 | D
(4 rows)
select * from nocycle_tbl connect by nocycle prior id=lid start with id=1 order siblings by id;
id | lid | name
----+-----+------
1 | 3 | A
2 | 1 | B
3 | 2 | C
4 | 2 | D
(4 rows)
select * from nocycle_tbl connect by nocycle prior id=lid start with id=1 order siblings by id desc;
id | lid | name
----+-----+------
1 | 3 | A
2 | 1 | B
4 | 2 | D
3 | 2 | C
(4 rows)
drop table nocycle_tbl;

View File

@ -641,4 +641,10 @@ SELECT * FROM RLTEST CONNECT BY NOCYCLE PRIOR B=A AND (MOD(ROWNUM+1,2) = 0);
SELECT * FROM RLTEST CONNECT BY PRIOR B=A OR (LEVEL < 1 OR ROWNUM < 2);
SELECT * FROM RLTEST CONNECT BY PRIOR B=A AND (LEVEL=1 OR B<10) AND (ROWNUM<3 OR PRIOR A=B);
SELECT * FROM RLTEST CONNECT BY PRIOR B=A OR (MOD(ROWNUM+1,2) = 0);
DROP TABLE RLTEST;
DROP TABLE RLTEST;
create table nocycle_tbl(id int, lid int, name text);
insert into nocycle_tbl values (1,3,'A'),(2,1,'B'),(3,2,'C'),(4,2,'D');
select * from nocycle_tbl connect by nocycle prior id=lid start with id=1;
select * from nocycle_tbl connect by nocycle prior id=lid start with id=1 order siblings by id;
select * from nocycle_tbl connect by nocycle prior id=lid start with id=1 order siblings by id desc;
drop table nocycle_tbl;