diff --git a/src/gausskernel/optimizer/plan/streamwalker.cpp b/src/gausskernel/optimizer/plan/streamwalker.cpp index f85b6615d588f1c63d4d27d351b4c30e90903621..fefad0cbc1c7443510d7f09fd967c85f070a238b 100755 --- a/src/gausskernel/optimizer/plan/streamwalker.cpp +++ b/src/gausskernel/optimizer/plan/streamwalker.cpp @@ -53,7 +53,7 @@ static bool table_contain_unsupport_feature(Oid relid, Query* query); static bool contain_unsupport_function(Oid funcId); static bool rel_contain_unshippable_feature(RangeTblEntry* rte, shipping_context* context, CmdType commandType); static void inh_shipping_context(shipping_context *dst, shipping_context *src); -static bool contain_unsupport_expression(Node* expr, void* context); +static bool contain_unsupport_expression(Node* expr, void* context, bool need_recur = true); static uint unsupport_func[] = { @@ -480,10 +480,11 @@ static bool vector_search_func_shippable(Oid funcid) static void stream_walker_func_expr(FuncExpr* func, shipping_context *cxt) { uint32 i = 0; + char* func_name = get_func_name(func->funcid); if (pgxc_is_shippable_func_contain_any(func->funcid)) { /* the args type of concat() and concat_ws() contains ANY, that may cause unshippable */ - if (contain_unsupport_expression((Node*)func->args, (void *)cxt)) { + if (contain_unsupport_expression((Node*)func->args, (void *)cxt), false) { cxt->current_shippable = false; } } @@ -491,7 +492,7 @@ static void stream_walker_func_expr(FuncExpr* func, shipping_context *cxt) errno_t sprintf_rc = sprintf_s(u_sess->opt_cxt.not_shipping_info->not_shipping_reason, NOTPLANSHIPPING_LENGTH, "Function %s() can not be shipped", - get_func_name(func->funcid)); + func_name); securec_check_ss_c(sprintf_rc, "\0", "\0"); cxt->current_shippable = false; } @@ -501,7 +502,7 @@ static void stream_walker_func_expr(FuncExpr* func, shipping_context *cxt) errno_t sprintf_rc = sprintf_s(u_sess->opt_cxt.not_shipping_info->not_shipping_reason, NOTPLANSHIPPING_LENGTH, "Function %s() can not be shipped because return record", - get_func_name(func->funcid)); + func_name); securec_check_ss_c(sprintf_rc, "\0", "\0"); cxt->current_shippable = false; } @@ -510,7 +511,7 @@ static void stream_walker_func_expr(FuncExpr* func, shipping_context *cxt) errno_t sprintf_rc = sprintf_s(u_sess->opt_cxt.not_shipping_info->not_shipping_reason, NOTPLANSHIPPING_LENGTH, "Function %s() can not be shipped", - get_func_name(func->funcid)); + func_name); securec_check_ss_c(sprintf_rc, "\0", "\0"); cxt->current_shippable = false; } @@ -525,6 +526,7 @@ static void stream_walker_func_expr(FuncExpr* func, shipping_context *cxt) securec_check_ss_c(sprintf_rc, "\0", "\0"); cxt->current_shippable = false; } + pfree(func_name); } static void stream_walker_aggref(Aggref* aggref, shipping_context *cxt) @@ -848,7 +850,8 @@ static bool contain_unsupport_function(Oid funcId) return false; } -static bool contain_unsupport_expression(Node* expr, void* context) +#define CHECK_INTER_PER_LOOP (100) +static bool contain_unsupport_expression(Node* expr, void* context, bool need_recur) { if (expr == NULL) { return false; @@ -857,6 +860,13 @@ static bool contain_unsupport_expression(Node* expr, void* context) errno_t sprintf_rc = 0; shipping_context* cxt = (shipping_context *)context; + if (cxt) { + if (cxt->check_count % CHECK_INTER_PER_LOOP == 0) { + CHECK_FOR_INTERRUPTS(); + } + cxt->check_count++; + } + switch (nodeTag(expr)) { case T_RowExpr: { sprintf_rc = sprintf_s(u_sess->opt_cxt.not_shipping_info->not_shipping_reason, @@ -889,7 +899,7 @@ static bool contain_unsupport_expression(Node* expr, void* context) case T_List: { ListCell* temp = NULL; foreach (temp, (List*)expr) { - if (contain_unsupport_expression((Node*)lfirst(temp), context)) { + if (contain_unsupport_expression((Node*)lfirst(temp), context, false)) { cxt->current_shippable = false; } } @@ -923,13 +933,13 @@ static bool contain_unsupport_expression(Node* expr, void* context) } break; case T_OpExpr: { OpExpr* op = (OpExpr*)expr; - if (contain_unsupport_expression((Node*)op->args, context)) { + if (contain_unsupport_expression((Node*)op->args, context, false)) { cxt->current_shippable = false; } } break; case T_BoolExpr: { BoolExpr* be = (BoolExpr*)expr; - if (contain_unsupport_expression((Node*)be->args, context)) { + if (contain_unsupport_expression((Node*)be->args, context, false)) { cxt->current_shippable = false; } } break; @@ -978,5 +988,9 @@ static bool contain_unsupport_expression(Node* expr, void* context) } break; } + + if (!need_recur) { + return false; + } return expression_tree_walker(expr, (bool (*)())stream_walker, context); } diff --git a/src/gausskernel/runtime/executor/execClusterResize.cpp b/src/gausskernel/runtime/executor/execClusterResize.cpp index 4eb0444a5fd2e8005c497fb2937614d7f3501392..16f9ca7f614df5a69f3b8247bdd8bc20a0559831 100644 --- a/src/gausskernel/runtime/executor/execClusterResize.cpp +++ b/src/gausskernel/runtime/executor/execClusterResize.cpp @@ -927,7 +927,7 @@ void BlockUnsupportedDDL(const Node* parsetree) */ bool redis_func_shippable(Oid funcid) { - const char* func_name = get_func_name(funcid); + char* func_name = get_func_name(funcid); Oid* argstype = NULL; int nargs; Oid rettype = InvalidOid; @@ -956,6 +956,7 @@ bool redis_func_shippable(Oid funcid) pfree_ext(argstype); argstype = NULL; } + pfree(func_name); return result; } diff --git a/src/include/optimizer/pgxcship.h b/src/include/optimizer/pgxcship.h index 752571d5b2f05a8fd1e8b1ffd9f1b6a34fb435e4..82b321b32b199e14743a59b31f90e4a76468ab9f 100644 --- a/src/include/optimizer/pgxcship.h +++ b/src/include/optimizer/pgxcship.h @@ -55,6 +55,7 @@ typedef struct { bool query_shippable; /* backward compatible */ bool current_shippable; /* current query can push */ bool global_shippable; /* the whole query can push */ + int check_count; } shipping_context; typedef struct { diff --git a/src/test/regress/expected/smp.out b/src/test/regress/expected/smp.out index 0bea03e687f86ca33d55e583cc4599387db47b4b..4fa92b685d6eea4c5dd6c917e1c45fb660184a0e 100644 --- a/src/test/regress/expected/smp.out +++ b/src/test/regress/expected/smp.out @@ -1576,6 +1576,42 @@ rollback to x; commit; drop table fktable2; drop table pktable2; +create table tb_1262216( +bill_no number(15,0) , +product_id number(15,0) , +accumulate_value number(12,0) , +item_code number(9,0) , +primal_fee number(12,0) , +discount_fee number(12,0) , +accu_measure_id number(9,0) , +measure_id number(9,0) , +billing_type number(4,0) , +tax_include number(4,0) , +tax_fee number(15,0) , +tax_rate number(4,0) , +tax_measure_id number(9,0) , +product_offering_id number(9,0) , +sp_code varchar(20) , +oper_code varchar(32)); +explain (costs off) select concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(bill_no +,'-'),product_id),'-'),accumulate_value), +'-'),item_code +),'-'),primal_fee +),'-'),discount_fee +),'-'),accu_measure_id +),'-'),measure_id +),'-'),billing_type +),'-'),tax_include +),'-'),tax_fee +),'-'),tax_rate +),'-'),tax_measure_id +),'-'),product_offering_id) from tb_1262216; + QUERY PLAN +------------------------ + Seq Scan on tb_1262216 +(1 row) + +drop table tb_1262216; --clean set search_path=public; drop schema test_smp cascade; diff --git a/src/test/regress/sql/smp.sql b/src/test/regress/sql/smp.sql index 3f8979132e614e0ab6a8fb3e7859fd928eb25a7b..24b76c87183fbaf59d30c10b63190f708b163153 100644 --- a/src/test/regress/sql/smp.sql +++ b/src/test/regress/sql/smp.sql @@ -320,6 +320,39 @@ commit; drop table fktable2; drop table pktable2; +create table tb_1262216( +bill_no number(15,0) , +product_id number(15,0) , +accumulate_value number(12,0) , +item_code number(9,0) , +primal_fee number(12,0) , +discount_fee number(12,0) , +accu_measure_id number(9,0) , +measure_id number(9,0) , +billing_type number(4,0) , +tax_include number(4,0) , +tax_fee number(15,0) , +tax_rate number(4,0) , +tax_measure_id number(9,0) , +product_offering_id number(9,0) , +sp_code varchar(20) , +oper_code varchar(32)); + +explain (costs off) select concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(bill_no +,'-'),product_id),'-'),accumulate_value), +'-'),item_code +),'-'),primal_fee +),'-'),discount_fee +),'-'),accu_measure_id +),'-'),measure_id +),'-'),billing_type +),'-'),tax_include +),'-'),tax_fee +),'-'),tax_rate +),'-'),tax_measure_id +),'-'),product_offering_id) from tb_1262216; + +drop table tb_1262216; --clean set search_path=public; drop schema test_smp cascade;