diff --git a/src/common/backend/nodes/equalfuncs.cpp b/src/common/backend/nodes/equalfuncs.cpp index 11c00244c..9cc4f2695 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 e1312395e..730567722 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 47c69cc0b..b37449dce 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 72f0d177c..ed13b49c4 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 becf4892e..1494a197f 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