优化了修复rownum的4个bug的代码

This commit is contained in:
zhouxiongjia
2020-10-27 15:52:23 +08:00
parent 307db7f772
commit 1b439d8718
4 changed files with 40 additions and 18 deletions

View File

@ -56,6 +56,7 @@ static void finalize_grouping_exprs(
static bool finalize_grouping_exprs_walker(Node* node, check_ungrouped_columns_context* context);
static List* expand_groupingset_node(GroupingSet* gs);
static void find_rownum_in_groupby_clauses(Rownum *rownumVar, check_ungrouped_columns_context* context);
/*
* transformAggregateCall -
@ -742,23 +743,7 @@ static bool check_ungrouped_columns_walker(Node* node, check_ungrouped_columns_c
/* If There is ROWNUM, it must appear in the GROUP BY clause or be used in an aggregate function. */
if (IsA(node, Rownum)) {
Rownum *rownumVar = (Rownum *)node;
bool haveRownum = false;
if (!context->have_non_var_grouping || context->sublevels_up != 0) {
foreach (gl, context->groupClauses) {
Node *gnode = (Node *)((TargetEntry *)lfirst(gl))->expr;
if (IsA(gnode, Rownum)) {
haveRownum = true;
break;
}
}
if (haveRownum == false) {
ereport(ERROR, (errcode(ERRCODE_GROUPING_ERROR),
errmsg("ROWNUM must appear in the GROUP BY clause or be used in an aggregate function"),
parser_errposition(context->pstate, rownumVar->location)));
}
}
find_rownum_in_groupby_clauses((Rownum *)node, context);
}
/*
* If we have an ungrouped Var of the original query level, we have a
@ -1493,3 +1478,25 @@ Oid resolve_aggregate_transtype(Oid aggfuncid, Oid aggtranstype, Oid* inputTypes
}
return aggtranstype;
}
static void find_rownum_in_groupby_clauses(Rownum *rownumVar, check_ungrouped_columns_context *context)
{
bool haveRownum = false;
ListCell *gl = NULL;
if (!context->have_non_var_grouping || context->sublevels_up != 0) {
foreach (gl, context->groupClauses) {
Node *gnode = (Node *)((TargetEntry *)lfirst(gl))->expr;
if (IsA(gnode, Rownum)) {
haveRownum = true;
break;
}
}
if (haveRownum == false) {
ereport(ERROR, (errcode(ERRCODE_GROUPING_ERROR),
errmsg("ROWNUM must appear in the GROUP BY clause or be used in an aggregate function"),
parser_errposition(context->pstate, rownumVar->location)));
}
}
}

View File

@ -1941,7 +1941,11 @@ static void reduce_orderby_recurse(Query* query, Node* jtnode, bool reduce)
/* Reduce orderby clause in subquery for join or from clause of more than one rte */
reduce_orderby_final(rte, reduce);
} else if (IsA(jtnode, FromExpr)) {
/* If there is ROWNUM, can not reduce orderby clause in subquery */
/* If there is ROWNUM, can not reduce orderby clause in subquery from fromlist.
* For example, If there is a SQL {select * from table_name where rownum < n union
* select * from (select * from table_name order by column_name desc) where rownum < n;},
* can not reduce orderby clause here.
*/
if (contain_rownum_walker(jtnode, NULL)) {
return;
}

View File

@ -1640,5 +1640,15 @@ explain select id from student where rownum < 3 union select id from (select id
-> Seq Scan on student (cost=0.00..21.34 rows=1134 width=4)
(9 rows)
select * from test where id < 2 union select * from (select * from test order by id desc) where rownum < 5;
id | testchar
----+----------
8 | test8
7 | test7
9 | test9
1 | test1
10 | test10
(5 rows)
drop table student;
drop table test;

View File

@ -460,6 +460,7 @@ explain select id from test where rownum < 5 group by id;
-- ROWNUM with UNION and ORDER BY
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;
drop table student;
drop table test;