From 2962e03482a9dcab65b211c343c790fc7f5b5df9 Mon Sep 17 00:00:00 2001 From: zhouxiongjia <719216473@qq.com> Date: Fri, 7 Aug 2020 13:06:45 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BA=86group=20by=E5=90=8E?= =?UTF-8?q?=E9=9D=A2=E4=B8=8D=E8=83=BD=E5=8A=A0rownum=EF=BC=88=E6=88=96?= =?UTF-8?q?=E5=88=AB=E5=90=8D=EF=BC=89=E7=9A=84bug=E4=BB=A5=E5=8F=8Awhere?= =?UTF-8?q?=E5=90=8E=E9=9D=A2=E6=8E=A5rownum=E7=9A=84=E5=88=AB=E5=90=8D?= =?UTF-8?q?=E7=9A=84=E6=8A=A5=E9=94=99=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/backend/nodes/equalfuncs.cpp | 11 +++++++ src/common/backend/parser/parse_expr.cpp | 6 +++- src/include/optimizer/clauses.h | 6 ++++ src/test/regress/expected/xc_rownum.out | 40 ++++++++++++++++++++++++ src/test/regress/sql/xc_rownum.sql | 8 +++++ 5 files changed, 70 insertions(+), 1 deletion(-) diff --git a/src/common/backend/nodes/equalfuncs.cpp b/src/common/backend/nodes/equalfuncs.cpp index 11c00244cf..9cc4f26951 100755 --- a/src/common/backend/nodes/equalfuncs.cpp +++ b/src/common/backend/nodes/equalfuncs.cpp @@ -2432,6 +2432,14 @@ static bool _equalDropSynonymStmt(DropSynonymStmt* a, DropSynonymStmt* b) return true; } +static bool _equalRownum(Rownum* a, Rownum* b) +{ + COMPARE_SCALAR_FIELD(rownumcollid); + COMPARE_LOCATION_FIELD(location); + + return true; +} + /* * Stuff from pg_list.h */ @@ -3428,6 +3436,9 @@ bool equal(const void* a, const void* b) case T_DropSynonymStmt: retval = _equalDropSynonymStmt((DropSynonymStmt*)a, (DropSynonymStmt*)b); break; + case T_Rownum: + retval = _equalRownum((Rownum*)a, (Rownum*)b); + break; default: ereport(ERROR, diff --git a/src/common/backend/parser/parse_expr.cpp b/src/common/backend/parser/parse_expr.cpp index e1312395ea..730567722c 100644 --- a/src/common/backend/parser/parse_expr.cpp +++ b/src/common/backend/parser/parse_expr.cpp @@ -444,7 +444,11 @@ static Node* replaceExprAliasIfNecessary(ParseState* pstate, char* colname, Colu (errcode(ERRCODE_UNDEFINED_COLUMN), errmsg("Alias \"%s\" reference with window function included is not supported.", colname), parser_errposition(pstate, cref->location))); - + } else if (contain_rownum_expr((Node*)tle->expr)) { + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_COLUMN), + errmsg("Alias \"%s\" reference with ROWNUM included is invalid.", colname), + parser_errposition(pstate, cref->location))); } else if (contain_volatile_functions((Node*)tle->expr)) { ereport(ERROR, (errcode(ERRCODE_UNDEFINED_COLUMN), diff --git a/src/include/optimizer/clauses.h b/src/include/optimizer/clauses.h index 47c69cc0bf..b37449dce1 100755 --- a/src/include/optimizer/clauses.h +++ b/src/include/optimizer/clauses.h @@ -106,6 +106,12 @@ extern List* extract_function_outarguments(Oid funcid, List* parameters, List* f extern bool need_adjust_agg_inner_func_type(Aggref* aggref); extern bool contain_rownum_walker(Node *node, void *context); + +static inline bool contain_rownum_expr(Node *node) +{ + return contain_rownum_walker(node, NULL); +} + extern List* get_quals_lists(Node *jtnode); #endif /* CLAUSES_H */ diff --git a/src/test/regress/expected/xc_rownum.out b/src/test/regress/expected/xc_rownum.out index 72f0d177c6..ed13b49c4d 100644 --- a/src/test/regress/expected/xc_rownum.out +++ b/src/test/regress/expected/xc_rownum.out @@ -211,7 +211,47 @@ select rownum, name from (select name from distributors where rownum <= 4 inters 2 | westward (2 rows) +--test group by +select rownum from distributors group by rownum; + rownum +-------- + 3 + 1 + 2 + 4 +(4 rows) + +select rownum rn from distributors group by rn; + rn +---- + 3 + 1 + 2 + 4 +(4 rows) + +select rownum + 1 from dual group by rownum; + ?column? +---------- + 2 +(1 row) + +select rownum + 1 rn from dual group by rn; + rn +---- + 2 +(1 row) +--test alias name after where +select rownum rn, name from distributors where rn<3; +ERROR: Alias "rn" reference with ROWNUM included is invalid. +LINE 1: select rownum rn, name from distributors where rn<3; + ^ +select rownum rowno2, * from (select rownum rowno1, * from distributors order by id desc) where rowno2 < 2; +ERROR: Alias "rowno2" reference with ROWNUM included is invalid. +LINE 1: ...wno1, * from distributors order by id desc) where rowno2 < 2... + ^ + --test except and minus --create test table create table except_table (a int, b int); diff --git a/src/test/regress/sql/xc_rownum.sql b/src/test/regress/sql/xc_rownum.sql index becf4892eb..1494a197f1 100644 --- a/src/test/regress/sql/xc_rownum.sql +++ b/src/test/regress/sql/xc_rownum.sql @@ -80,6 +80,14 @@ select rownum, name from (select name from distributors intersect all select nam select rownum, name from (select name from distributors intersect all select name from actors order by 1) as result where rownum < 3; select rownum, name from (select name from distributors intersect all select name from actors order by 1) as result where rownum < 6; select rownum, name from (select name from distributors where rownum <= 4 intersect all select name from actors where rownum <= 4 order by 1) as result; +--test group by +select rownum from distributors group by rownum; +select rownum rn from distributors group by rn; +select rownum + 1 from dual group by rownum; +select rownum + 1 rn from dual group by rn; +--test alias name after where +select rownum rn, name from distributors where rn<3; +select rownum rowno2, * from (select rownum rowno1, * from distributors order by id desc) where rowno2 < 2; --test except and minus --create test table -- Gitee