diff --git a/src/gausskernel/runtime/vecexecutor/vecexpression.cpp b/src/gausskernel/runtime/vecexecutor/vecexpression.cpp index 4ce0a80ea..cd4b68a82 100644 --- a/src/gausskernel/runtime/vecexecutor/vecexpression.cpp +++ b/src/gausskernel/runtime/vecexecutor/vecexpression.cpp @@ -228,6 +228,22 @@ static ScalarVector* ExecEvalVecNot( return pVector; } +static ScalarVector* ExecEvalVecRownum( + RownumState* exprstate, ExprContext* econtext, bool* pSelection, ScalarVector* pVector, ExprDoneCond* isDone) +{ + Assert(pSelection != NULL); + ScalarValue* pDest = pVector->m_vals; + int64 ps_rownum = exprstate->ps->ps_rownum; + + for (int i = 0; i < econtext->align_rows; i++) { + SET_NOTNULL(pVector->m_flag[i]); + pDest[i] = ++ps_rownum ; + } + + pVector->m_rows = econtext->align_rows; + + return pVector; +} // TRUE means we deal with or // false means we deal with and template @@ -3158,6 +3174,12 @@ ExprState* ExecInitVecExpr(Expr* node, PlanState* parent) (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmodule(MOD_VEC_EXECUTOR), errmsg("Unsupported array coerce expression in vector engine"))); + case T_Rownum: { + RownumState* rnstate = (RownumState*)makeNode(RownumState); + rnstate->ps = parent; + state = (ExprState*)rnstate; + state->vecExprFun = (VectorExprFun)ExecEvalVecRownum; + } break; default: ereport(ERROR, (errcode(ERRCODE_UNRECOGNIZED_NODE_TYPE), diff --git a/src/gausskernel/runtime/vecexecutor/vecnode/vectortorow.cpp b/src/gausskernel/runtime/vecexecutor/vecnode/vectortorow.cpp index 504dcf352..aae6f7c78 100644 --- a/src/gausskernel/runtime/vecexecutor/vecnode/vectortorow.cpp +++ b/src/gausskernel/runtime/vecexecutor/vecnode/vectortorow.cpp @@ -154,6 +154,7 @@ TupleTableSlot* ExecVecToRow(VecToRowState* state) /* return: a tuple or NULL */ state->m_currentRow = 0; // Convert the batch into row based tuple DevectorizeOneBatch(state); + outer_plan->ps_rownum += current_batch->m_rows; } // retrieve rows from current batch diff --git a/src/test/regress/expected/xc_rownum.out b/src/test/regress/expected/xc_rownum.out index 0353f029b..3fc872912 100644 --- a/src/test/regress/expected/xc_rownum.out +++ b/src/test/regress/expected/xc_rownum.out @@ -1638,6 +1638,109 @@ select * from test where id < 2 union select * from (select * from test order by 10 | test10 (5 rows) +-- ROWNUM for Column-Oriented +create table student_cstore1(id int, stuname varchar(10) ) WITH (orientation=column) ; +create table student_cstore2(id int, stuname varchar(10) ) WITH (orientation=column) ; +insert into student_cstore1 select * from student; +-- test rownum for cstorescan +select * from student_cstore1 where rownum < 5; + id | stuname +----+--------- + 1 | stu1 + 2 | stu2 + 3 | stu3 + 4 | stu4 +(4 rows) + +select rownum, * from student_cstore1 where rownum < 1; + rownum | id | stuname +--------+----+--------- +(0 rows) + +select rownum, * from student_cstore1 where rownum <= 1; + rownum | id | stuname +--------+----+--------- + 1 | 1 | stu1 +(1 row) + +select rownum, * from student_cstore1 where rownum <= 10; + rownum | id | stuname +--------+----+--------- + 1 | 1 | stu1 + 2 | 2 | stu2 + 3 | 3 | stu3 + 4 | 4 | stu4 + 5 | 5 | stu5 + 6 | 6 | stu6 + 7 | 7 | stu7 + 8 | 8 | stu8 + 9 | 9 | stu9 + 10 | 10 | stu10 +(10 rows) + +select rownum, * from student_cstore1 where stuname = 'stu5' and rownum < 4; + rownum | id | stuname +--------+----+--------- + 1 | 5 | stu5 +(1 row) + +select rownum, stuname from student_cstore1 where stuname = 'stu5' or rownum < 8; + rownum | stuname +--------+--------- + 1 | stu1 + 2 | stu2 + 3 | stu3 + 4 | stu4 + 5 | stu5 + 6 | stu6 + 7 | stu7 +(7 rows) + +-- test rownum for join +insert into student_cstore2 select * from student; +select * from student_cstore2 where rownum > 2; + id | stuname +----+--------- +(0 rows) + +select * from student_cstore2 where rownum = 2; + id | stuname +----+--------- +(0 rows) + +select rownum, sc1.stuname, sc2.id from student_cstore2 as sc1, student_cstore2 as sc2 where sc1.id = sc2.id; + rownum | stuname | id +--------+---------+---- + 1 | stu1 | 1 + 2 | stu2 | 2 + 3 | stu3 | 3 + 4 | stu4 | 4 + 5 | stu5 | 5 + 6 | stu6 | 6 + 7 | stu7 | 7 + 8 | stu8 | 8 + 9 | stu9 | 9 + 10 | stu10 | 10 +(10 rows) + +-- test rownum for agg +select * from (select rownum, max(id) as max_id from student_cstore1 group by rownum) as t order by max_id; + rownum | max_id +--------+-------- + 1 | 1 + 2 | 2 + 3 | 3 + 4 | 4 + 5 | 5 + 6 | 6 + 7 | 7 + 8 | 8 + 9 | 9 + 10 | 10 +(10 rows) + +drop table student_cstore1; +drop table student_cstore2; drop table student; drop table test; --test partition table diff --git a/src/test/regress/sql/xc_rownum.sql b/src/test/regress/sql/xc_rownum.sql index 6194183f3..141c4d671 100644 --- a/src/test/regress/sql/xc_rownum.sql +++ b/src/test/regress/sql/xc_rownum.sql @@ -460,6 +460,28 @@ explain select id from test where rownum < 5 group by id; explain select id from student where rownum < 3 union select id from (select id from student order by 1) where rownum < 5; select * from test where id < 2 union select * from (select * from test order by id desc) where rownum < 5; +-- ROWNUM for Column-Oriented +create table student_cstore1(id int, stuname varchar(10) ) WITH (orientation=column) ; +create table student_cstore2(id int, stuname varchar(10) ) WITH (orientation=column) ; +insert into student_cstore1 select * from student; +-- test rownum for cstorescan +select * from student_cstore1 where rownum < 5; +select rownum, * from student_cstore1 where rownum < 1; +select rownum, * from student_cstore1 where rownum <= 1; +select rownum, * from student_cstore1 where rownum <= 10; +select rownum, * from student_cstore1 where stuname = 'stu5' and rownum < 4; +select rownum, stuname from student_cstore1 where stuname = 'stu5' or rownum < 8; +-- test rownum for join +insert into student_cstore2 select * from student; +select * from student_cstore2 where rownum > 2; +select * from student_cstore2 where rownum = 2; +select rownum, sc1.stuname, sc2.id from student_cstore2 as sc1, student_cstore2 as sc2 where sc1.id = sc2.id; + +-- test rownum for agg +select * from (select rownum, max(id) as max_id from student_cstore1 group by rownum) as t order by max_id; + +drop table student_cstore1; +drop table student_cstore2; drop table student; drop table test;