diff --git a/src/gausskernel/optimizer/util/pruning.cpp b/src/gausskernel/optimizer/util/pruning.cpp index 47c86ce14..eb7fb8dfe 100644 --- a/src/gausskernel/optimizer/util/pruning.cpp +++ b/src/gausskernel/optimizer/util/pruning.cpp @@ -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); diff --git a/src/test/regress/expected/partition_pruning.out b/src/test/regress/expected/partition_pruning.out index 977d8bbcf..25170d3c7 100644 --- a/src/test/regress/expected/partition_pruning.out +++ b/src/test/regress/expected/partition_pruning.out @@ -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; diff --git a/src/test/regress/sql/partition_pruning.sql b/src/test/regress/sql/partition_pruning.sql index 4772021af..43236db24 100644 --- a/src/test/regress/sql/partition_pruning.sql +++ b/src/test/regress/sql/partition_pruning.sql @@ -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;