优化了修复rownum的4个bug的代码
This commit is contained in:
@ -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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
Reference in New Issue
Block a user