【标题】: 修复I8XXN6所示的数据类型varchar在in(array[])时不走动态分区裁剪的问题
【实现内容】: 修复I8XXN6所示的数据类型varchar在in(array[])时不走动态分区裁剪的问题。 【根因分析】: 因为默认为text类型,如果建表的时候类型为varchar为T_ArrayCoerceExpr,当前只有右节点为T_ArrayExpr才可动分区裁剪。 【实现方案】: 参照T_ArrayExpr实现T_ArrayCoerceExpr。 【关联需求或issue】: https://e.gitee.com/opengaussorg/dashboard?issue=I8XXN6
This commit is contained in:
@ -1172,7 +1172,8 @@ static PruningResult* partitionPruningFromScalarArrayOpExpr
|
||||
larg = ((RelabelType*)larg)->arg;
|
||||
}
|
||||
|
||||
if (T_Var != nodeTag(larg) || (T_ArrayExpr != nodeTag(rarg) && T_Const != nodeTag(rarg))) {
|
||||
if (T_Var != nodeTag(larg) || (T_ArrayExpr != nodeTag(rarg) && T_Const != nodeTag(rarg) &&
|
||||
T_ArrayCoerceExpr != nodeTag(rarg))) {
|
||||
result = makeNode(PruningResult);
|
||||
result->state = PRUNING_RESULT_FULL;
|
||||
result->isPbeSinlePartition = false;
|
||||
@ -1265,6 +1266,37 @@ static PruningResult* partitionPruningFromScalarArrayOpExpr
|
||||
exprList = lappend(exprList, expr);
|
||||
}
|
||||
|
||||
if (arrayExpr->useOr) {
|
||||
result = partitionPruningWalker(
|
||||
(Expr*)makeBoolExpr(OR_EXPR, exprList, 0), pruningCtx);
|
||||
} else {
|
||||
result = partitionPruningWalker(
|
||||
(Expr*)makeBoolExpr(AND_EXPR, exprList, 0), pruningCtx);
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
} else if (T_ArrayCoerceExpr == nodeTag(rarg)) {
|
||||
List* eleList = NULL;
|
||||
ListCell* element = NULL;
|
||||
ArrayCoerceExpr* rargExpr = (ArrayCoerceExpr*)rarg;
|
||||
if (T_ArrayExpr == nodeTag(rargExpr->arg)) {
|
||||
ArrayExpr* rarg_arg = (ArrayExpr*)(rargExpr->arg);
|
||||
eleList = rarg_arg->elements;
|
||||
foreach (element, eleList) {
|
||||
Expr* eleExpr = (Expr*)lfirst(element);
|
||||
List* eleArgs = NULL;
|
||||
eleArgs = list_make2(copyObject(larg), copyObject(eleExpr));
|
||||
expr = (OpExpr*)makeNode(OpExpr);
|
||||
expr->args = eleArgs;
|
||||
expr->inputcollid = arrayExpr->inputcollid;
|
||||
expr->location = 0;
|
||||
expr->opcollid = arrayExpr->opfuncid;
|
||||
expr->opfuncid = arrayExpr->opfuncid;
|
||||
expr->opno = arrayExpr->opno;
|
||||
expr->opresulttype = BOOLOID;
|
||||
expr->opretset = false;
|
||||
exprList = lappend(exprList, expr);
|
||||
}
|
||||
if (arrayExpr->useOr) {
|
||||
result = partitionPruningWalker(
|
||||
(Expr*)makeBoolExpr(OR_EXPR, exprList, 0), pruningCtx);
|
||||
|
||||
@ -107,4 +107,39 @@ execute p1(2001,3001);
|
||||
(0 rows)
|
||||
|
||||
drop table test_range_pt;
|
||||
create table par4_1188069(id int,a1 text,a2 date,a3 varchar(30))
|
||||
partition by range (a3)
|
||||
(
|
||||
partition p1 values less than('d'),
|
||||
partition p2 values less than('k'),
|
||||
partition p3 values less than('q'),
|
||||
partition p4 values less than('z'));
|
||||
insert into par4_1188069 values(generate_series(1,100),'d',generate_series(DATE '2022-01-01', DATE '2022-4-10', '1 day'),chr(65 + (generate_series(1,100)-1)%25));
|
||||
insert into par4_1188069 values(generate_series(101,200),'k',generate_series(DATE '2022-01-01', DATE '2022-4-10', '1 day'),chr(65 + (generate_series(1,100)-1)%25));
|
||||
insert into par4_1188069 values(generate_series(201,300),'q',generate_series(DATE '2022-01-01', DATE '2022-4-10', '1 day'),chr(65 + (generate_series(1,100)-1)%25));
|
||||
insert into par4_1188069 values(generate_series(301,400),null,generate_series(DATE '2022-01-01', DATE '2022-4-10', '1 day'),chr(65 + (generate_series(1,100)-1)%25));
|
||||
prepare l7_1188069(varchar,varchar) as select * from par4_1188069 where a3 in($1,$2) limit 3;
|
||||
explain (analyze,costs off) execute l7_1188069('h','v');
|
||||
QUERY PLAN
|
||||
--------------------------------------------------------------------------------------------
|
||||
--?.*
|
||||
--?.*
|
||||
Iterations: PART
|
||||
--?.*
|
||||
Filter: ((a3)::text = ANY ((ARRAY[$1, $2])::text[]))
|
||||
Rows Removed by Filter: 256
|
||||
Selected Partitions: PART
|
||||
--?.*
|
||||
(8 rows)
|
||||
|
||||
execute l7_1188069('H','V');
|
||||
id | a1 | a2 | a3
|
||||
----+----+--------------------------+----
|
||||
--?.*
|
||||
--?.*
|
||||
--?.*
|
||||
(3 rows)
|
||||
|
||||
deallocate l7_1188069;
|
||||
drop table par4_1188069;
|
||||
DROP SCHEMA partition_pruning;
|
||||
|
||||
@ -48,4 +48,25 @@ explain (costs off)execute p1(2001,3001);
|
||||
execute p1(2001,3001);
|
||||
drop table test_range_pt;
|
||||
|
||||
create table par4_1188069(id int,a1 text,a2 date,a3 varchar(30))
|
||||
partition by range (a3)
|
||||
(
|
||||
partition p1 values less than('d'),
|
||||
partition p2 values less than('k'),
|
||||
partition p3 values less than('q'),
|
||||
partition p4 values less than('z'));
|
||||
|
||||
insert into par4_1188069 values(generate_series(1,100),'d',generate_series(DATE '2022-01-01', DATE '2022-4-10', '1 day'),chr(65 + (generate_series(1,100)-1)%25));
|
||||
insert into par4_1188069 values(generate_series(101,200),'k',generate_series(DATE '2022-01-01', DATE '2022-4-10', '1 day'),chr(65 + (generate_series(1,100)-1)%25));
|
||||
insert into par4_1188069 values(generate_series(201,300),'q',generate_series(DATE '2022-01-01', DATE '2022-4-10', '1 day'),chr(65 + (generate_series(1,100)-1)%25));
|
||||
insert into par4_1188069 values(generate_series(301,400),null,generate_series(DATE '2022-01-01', DATE '2022-4-10', '1 day'),chr(65 + (generate_series(1,100)-1)%25));
|
||||
|
||||
prepare l7_1188069(varchar,varchar) as select * from par4_1188069 where a3 in($1,$2) limit 3;
|
||||
explain (analyze,costs off) execute l7_1188069('h','v');
|
||||
|
||||
execute l7_1188069('H','V');
|
||||
|
||||
deallocate l7_1188069;
|
||||
drop table par4_1188069;
|
||||
|
||||
DROP SCHEMA partition_pruning;
|
||||
|
||||
Reference in New Issue
Block a user