!6319 处理issue:select …… connect by子句,出现rownum条件,未正常生效
Merge pull request !6319 from lukeman/oss
This commit is contained in:
@ -472,6 +472,23 @@ static List* peekNextLevel(TupleTableSlot* startSlot, PlanState* outerNode, int
|
||||
return queue;
|
||||
}
|
||||
|
||||
static TupleTableSlot* updateTuplePseudoColumnValue(TupleTableSlot* slot, StartWithOpState *node,
|
||||
StartWithOpColumnType type, Datum value)
|
||||
{
|
||||
AttrNumber attnum = node->sw_pseudoCols[type]->resno;
|
||||
int attcount = slot->tts_tupleDescriptor->natts;
|
||||
bool nulls[attcount] = {false};
|
||||
Datum values[attcount] = {0};
|
||||
bool replaces[attcount] = {false};
|
||||
HeapTuple oldtup = (HeapTuple)slot->tts_tuple;
|
||||
replaces[attnum - 1] = true;
|
||||
nulls[attnum - 1] = false;
|
||||
values[attnum - 1] = value;
|
||||
HeapTuple newtup = heap_modify_tuple(oldtup, slot->tts_tupleDescriptor, values, nulls, replaces);
|
||||
slot->tts_tuple = newtup;
|
||||
heap_freetuple_ext(oldtup);
|
||||
}
|
||||
|
||||
/*
|
||||
* Construct CONNECT BY result set by depth-first order.
|
||||
*
|
||||
@ -508,24 +525,27 @@ static bool depth_first_connect(int currentLevel, StartWithOpState *node, List*
|
||||
isCycle = true;
|
||||
continue;
|
||||
}
|
||||
updateTuplePseudoColumnValue(dstSlot, node, SWCOL_ROWNUM, *dfsRowCount + 1);
|
||||
RecursiveUnionState* runode = castNode(RecursiveUnionState, outerNode);
|
||||
if (currentLevel == 1 || ExecStartWithRowLevelQual(runode, dstSlot)) {
|
||||
tuplestore_puttupleslot(outputStore, dstSlot);
|
||||
(*dfsRowCount)++;
|
||||
int rowCountBefore = *dfsRowCount;
|
||||
|
||||
tuplestore_puttupleslot(outputStore, dstSlot);
|
||||
(*dfsRowCount)++;
|
||||
int rowCountBefore = *dfsRowCount;
|
||||
/* Go into the depth NOW: sibling tuples won't get processed
|
||||
* until all children are done */
|
||||
node->sw_rownum = rowCountBefore;
|
||||
List* children = peekNextLevel(leader, outerNode, currentLevel);
|
||||
bool expectCycle = depth_first_connect(currentLevel + 1, node,
|
||||
children,
|
||||
dfsRowCount);
|
||||
if (expectCycle) {
|
||||
node->sw_cycle_rowmarks = lappend_int(node->sw_cycle_rowmarks, rowCountBefore);
|
||||
}
|
||||
|
||||
/* Go into the depth NOW: sibling tuples won't get processed
|
||||
* until all children are done */
|
||||
node->sw_rownum = rowCountBefore;
|
||||
List* children = peekNextLevel(leader, outerNode, currentLevel);
|
||||
bool expectCycle = depth_first_connect(currentLevel + 1, node,
|
||||
children,
|
||||
dfsRowCount);
|
||||
if (expectCycle) {
|
||||
node->sw_cycle_rowmarks = lappend_int(node->sw_cycle_rowmarks, rowCountBefore);
|
||||
}
|
||||
|
||||
if (!children) {
|
||||
node->sw_leaf_rowmarks = lappend_int(node->sw_leaf_rowmarks, rowCountBefore);
|
||||
if (!children) {
|
||||
node->sw_leaf_rowmarks = lappend_int(node->sw_leaf_rowmarks, rowCountBefore);
|
||||
}
|
||||
}
|
||||
}
|
||||
return isCycle;
|
||||
|
||||
@ -1507,22 +1507,7 @@ SELECT start AS connect, prior AS start FROM CONNECT CONNECT CONNECT BY ROWNUM <
|
||||
3 | 5
|
||||
5 | 6
|
||||
6 | 7
|
||||
1 | 3
|
||||
3 | 4
|
||||
3 | 5
|
||||
5 | 6
|
||||
6 | 7
|
||||
1 | 3
|
||||
3 | 4
|
||||
3 | 5
|
||||
5 | 6
|
||||
6 | 7
|
||||
1 | 3
|
||||
3 | 4
|
||||
3 | 5
|
||||
5 | 6
|
||||
6 | 7
|
||||
(24 rows)
|
||||
(9 rows)
|
||||
|
||||
DROP TABLE IF EXISTS start;
|
||||
DROP TABLE IF EXISTS connect;
|
||||
@ -1589,13 +1574,7 @@ select c_int from t_test_array_base connect by c_int[1:2]=array[1,2] and rownum
|
||||
{1,2,NULL,10,11}
|
||||
{1,2,2,10}
|
||||
{1,2,2,10}
|
||||
{1,2,2,10}
|
||||
{1,2,2,10}
|
||||
{1,2,2,10}
|
||||
{1,2,2,10}
|
||||
{1,2,2,10}
|
||||
{1,2,2,10}
|
||||
(12 rows)
|
||||
(6 rows)
|
||||
|
||||
drop table t_test_array_base;
|
||||
-- test invalid columnref
|
||||
|
||||
@ -1440,47 +1440,7 @@ SELECT id,pid,name,rownum,level FROM test_hcb_ptb START WITH id=1 CONNECT BY NOC
|
||||
121 | 111 | 江宁区 | 4 | 4
|
||||
131 | 121 | 东山街 | 5 | 5
|
||||
141 | 131 | 江南摩卡 | 6 | 6
|
||||
142 | 131 | 四季云顶 | 7 | 6
|
||||
143 | 131 | 盛世江南 | 8 | 6
|
||||
144 | 131 | 七里香都 | 9 | 6
|
||||
145 | 131 | 西山枫林 | 10 | 6
|
||||
146 | 131 | 醉墨小镇 | 11 | 6
|
||||
147 | 131 | 布拉格调 | 12 | 6
|
||||
148 | 131 | 清幽别院 | 13 | 6
|
||||
149 | 131 | 璀璨天城 | 14 | 6
|
||||
132 | 121 | 秣陵街 | 15 | 5
|
||||
133 | 121 | 汤山街 | 16 | 5
|
||||
135 | 121 | 禄口街 | 17 | 5
|
||||
134 | 121 | 淳化街 | 18 | 5
|
||||
136 | 121 | 江宁街 | 19 | 5
|
||||
137 | 121 | 谷里街 | 20 | 5
|
||||
138 | 121 | 湖熟街 | 21 | 5
|
||||
139 | 121 | 横溪街 | 22 | 5
|
||||
122 | 111 | 雨花台 | 23 | 4
|
||||
123 | 111 | 鼓楼区 | 24 | 4
|
||||
124 | 111 | 玄武区 | 25 | 4
|
||||
125 | 111 | 建邺区 | 26 | 4
|
||||
126 | 111 | 秦淮区 | 27 | 4
|
||||
127 | 111 | 浦口区 | 28 | 4
|
||||
128 | 111 | 浦口区 | 29 | 4
|
||||
129 | 111 | 六合区 | 30 | 4
|
||||
112 | 11 | 宿迁市 | 31 | 3
|
||||
113 | 11 | 徐州市 | 32 | 3
|
||||
114 | 11 | 苏州市 | 33 | 3
|
||||
115 | 11 | 盐城市 | 34 | 3
|
||||
117 | 11 | 常州市 | 35 | 3
|
||||
116 | 11 | 无锡市 | 36 | 3
|
||||
118 | 11 | 连云港 | 37 | 3
|
||||
119 | 11 | 泰州市 | 38 | 3
|
||||
12 | 1 | 山东省 | 39 | 2
|
||||
13 | 1 | 安徽省 | 40 | 2
|
||||
14 | 1 | 河南省 | 41 | 2
|
||||
15 | 1 | 河北省 | 42 | 2
|
||||
16 | 1 | 湖南省 | 43 | 2
|
||||
17 | 1 | 湖北省 | 44 | 2
|
||||
18 | 1 | 贵州省 | 45 | 2
|
||||
19 | 1 | 武汉省 | 46 | 2
|
||||
(46 rows)
|
||||
(6 rows)
|
||||
|
||||
--test subquery pushdown
|
||||
SELECT subq_0.c1 as c0
|
||||
@ -2358,4 +2318,55 @@ select child, level, lpad(' ', level*3, ' ')||child c1 from hier start with pare
|
||||
ERROR: Not support refer startwith Pseudo column in order siblings by.
|
||||
select child, level, lpad(' ', level*3, ' ')||child c1, level c2 from hier start with parent is null connect by prior child = parent ORDER SIBLINGS BY c2;
|
||||
ERROR: Not support refer startwith Pseudo column in order siblings by.
|
||||
drop table hier;
|
||||
drop table hier;
|
||||
-- test connect by rownum clause
|
||||
drop table if exists t_test_connect_by_rownum;
|
||||
create table t_test_connect_by_rownum(id char(1));
|
||||
insert into t_test_connect_by_rownum values('a'),('b'),('c');
|
||||
select id, rownum, level from t_test_connect_by_rownum connect by rownum < 1;
|
||||
id | rownum | level
|
||||
----+--------+-------
|
||||
a | 1 | 1
|
||||
b | 2 | 1
|
||||
c | 3 | 1
|
||||
(3 rows)
|
||||
|
||||
select id, rownum, level from t_test_connect_by_rownum connect by rownum < 2;
|
||||
id | rownum | level
|
||||
----+--------+-------
|
||||
a | 1 | 1
|
||||
b | 2 | 1
|
||||
c | 3 | 1
|
||||
(3 rows)
|
||||
|
||||
select id, rownum, level from t_test_connect_by_rownum connect by rownum < 3;
|
||||
id | rownum | level
|
||||
----+--------+-------
|
||||
a | 1 | 1
|
||||
a | 2 | 2
|
||||
b | 3 | 1
|
||||
c | 4 | 1
|
||||
(4 rows)
|
||||
|
||||
select id, rownum, level from t_test_connect_by_rownum connect by rownum < 4;
|
||||
id | rownum | level
|
||||
----+--------+-------
|
||||
a | 1 | 1
|
||||
a | 2 | 2
|
||||
a | 3 | 3
|
||||
b | 4 | 1
|
||||
c | 5 | 1
|
||||
(5 rows)
|
||||
|
||||
select id, rownum, level from t_test_connect_by_rownum connect by rownum < 5;
|
||||
id | rownum | level
|
||||
----+--------+-------
|
||||
a | 1 | 1
|
||||
a | 2 | 2
|
||||
a | 3 | 3
|
||||
a | 4 | 4
|
||||
b | 5 | 1
|
||||
c | 6 | 1
|
||||
(6 rows)
|
||||
|
||||
drop table t_test_connect_by_rownum;
|
||||
@ -881,4 +881,15 @@ insert into hier values('China','AK47');
|
||||
insert into hier values('China','天津');
|
||||
select child, level, lpad(' ', level*3, ' ')||child c1 from hier start with parent is null connect by prior child = parent ORDER SIBLINGS BY c1;
|
||||
select child, level, lpad(' ', level*3, ' ')||child c1, level c2 from hier start with parent is null connect by prior child = parent ORDER SIBLINGS BY c2;
|
||||
drop table hier;
|
||||
drop table hier;
|
||||
|
||||
-- test connect by rownum clause
|
||||
drop table if exists t_test_connect_by_rownum;
|
||||
create table t_test_connect_by_rownum(id char(1));
|
||||
insert into t_test_connect_by_rownum values('a'),('b'),('c');
|
||||
select id, rownum, level from t_test_connect_by_rownum connect by rownum < 1;
|
||||
select id, rownum, level from t_test_connect_by_rownum connect by rownum < 2;
|
||||
select id, rownum, level from t_test_connect_by_rownum connect by rownum < 3;
|
||||
select id, rownum, level from t_test_connect_by_rownum connect by rownum < 4;
|
||||
select id, rownum, level from t_test_connect_by_rownum connect by rownum < 5;
|
||||
drop table t_test_connect_by_rownum;
|
||||
Reference in New Issue
Block a user