diff --git a/src/gausskernel/optimizer/plan/planstartwith.cpp b/src/gausskernel/optimizer/plan/planstartwith.cpp index c773e9be9..086ed2dff 100644 --- a/src/gausskernel/optimizer/plan/planstartwith.cpp +++ b/src/gausskernel/optimizer/plan/planstartwith.cpp @@ -422,6 +422,54 @@ static char* GetSiblingsColNameFromFunc(Node* node) return NULL; } +static bool raw_unsupported_func_walker(Node *node, Node *context_node) +{ + if (node == NULL) { + return false; + } + + if (IsA(node, FuncCall)) { + FuncCall* fcall = (FuncCall*)node; + Value *val = (Value *)linitial(fcall->funcname); + char* name = strVal(val); + if (strcmp(name, "connect_by_root") == 0) { + ereport(ERROR, + (errmodule(MOD_OPT_PLANNER), + errmsg("CONNECT BY ROOT operator is not supported in the " + "START WITH or in the CONNECT BY condition"))); + } else if (strcmp(name, "sys_connect_by_path") == 0) { + ereport(ERROR, + (errmodule(MOD_OPT_PLANNER), + errmsg("SYS_CONNECT_BY_PATH function is not allowed here"))); + } + } + + return raw_expression_tree_walker(node, (bool (*)()) raw_unsupported_func_walker, context_node); +} + +static bool unsupported_func_walker(Node *node, Node *context_node) +{ + if (node == NULL) { + return false; + } + + if (IsA(node, FuncExpr)) { + FuncExpr* expr = (FuncExpr*)node; + if (expr->funcid == CONNECT_BY_ROOT_FUNCOID) { + ereport(ERROR, + (errmodule(MOD_OPT_PLANNER), + errmsg("CONNECT BY ROOT operator is not supported in the " + "START WITH or in the CONNECT BY condition"))); + } else if (expr->funcid == SYS_CONNECT_BY_PATH_FUNCOID) { + ereport(ERROR, + (errmodule(MOD_OPT_PLANNER), + errmsg("SYS_CONNECT_BY_PATH function is not allowed here"))); + } + } + + return expression_tree_walker(node, (bool (*)()) unsupported_func_walker, context_node); +} + /* * @Brief: check fix order-siblings columns, normally we can find sort-key from from * basePlan's targetlist, but some special case we need additional process: @@ -477,6 +525,7 @@ static char *CheckAndFixSiblingsColName(PlannerInfo *root, Plan *basePlan, /* te->resname may be null, so check it first */ if (te->resname && strcmp(te->resname, colname) == 0) { + unsupported_func_walker((Node*)te->expr, NULL); found = true; break; } @@ -529,6 +578,9 @@ static char *GetOrderSiblingsColName(PlannerInfo* root, SortBy *sb, Plan *basePl char *colname = NULL; TargetEntry *te = NULL; + /* check whether connect_by_root and sys_connect_by_path exist in sortBy */ + raw_unsupported_func_walker(sb->node, NULL); + if (IsA(sb->node, ColumnRef)) { ColumnRef *cr = (ColumnRef *)sb->node; int len = list_length(cr->fields); @@ -558,11 +610,7 @@ static char *GetOrderSiblingsColName(PlannerInfo* root, SortBy *sb, Plan *basePl te = (TargetEntry *)list_nth(root->parse->targetList, siblingIdx - 1); - if (IsA(te->expr, FuncExpr) && IsStartWithFunction((FuncExpr *)te->expr)) { - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("Not support refer startwithfunc column in order siblings by."))); - } + unsupported_func_walker((Node*)te->expr, NULL); if (te->resname != NULL && IsPseudoReturnColumn(te->resname)) { ereport(ERROR, diff --git a/src/test/regress/expected/sw_icbc.out b/src/test/regress/expected/sw_icbc.out old mode 100755 new mode 100644 index d8c19bc73..99513488d --- a/src/test/regress/expected/sw_icbc.out +++ b/src/test/regress/expected/sw_icbc.out @@ -588,7 +588,11 @@ ERROR: START WITH CONNECT BY clauses must have at least one prior key. explain (costs off) select *, level from t1 start with id = 1 connect by prior id = pid order siblings by 4; ERROR: Not support refer startwith Pseudo column in order siblings by. explain (costs off) select *, connect_by_root id from t1 start with id = 1 connect by prior id = pid order siblings by 4; -ERROR: Not support refer startwithfunc column in order siblings by. +ERROR: CONNECT BY ROOT operator is not supported in the START WITH or in the CONNECT BY condition +explain (costs off) select *, sys_connect_by_path(name, '/') from t1 start with id = 1 connect by prior id = pid order siblings by 4; +ERROR: SYS_CONNECT_BY_PATH function is not allowed here +explain (costs off) select *, sys_connect_by_path(name, '/') from t1 start with id = 1 connect by prior id = pid order siblings by sys_connect_by_path(name, '/'); +ERROR: SYS_CONNECT_BY_PATH function is not allowed here --unsupport case select prior id cc from t1 start with id = 1 connect by prior id = pid; ERROR: Not Support prior column in TargetList in case swcb. diff --git a/src/test/regress/sql/sw_icbc.sql b/src/test/regress/sql/sw_icbc.sql index bf2b59a3b..7128b6039 100644 --- a/src/test/regress/sql/sw_icbc.sql +++ b/src/test/regress/sql/sw_icbc.sql @@ -96,6 +96,8 @@ explain (costs off) select id, (select id from t2 start with t2.id = t1.id conne --not support pseudo column in order siblings by explain (costs off) select *, level from t1 start with id = 1 connect by prior id = pid order siblings by 4; explain (costs off) select *, connect_by_root id from t1 start with id = 1 connect by prior id = pid order siblings by 4; +explain (costs off) select *, sys_connect_by_path(name, '/') from t1 start with id = 1 connect by prior id = pid order siblings by 4; +explain (costs off) select *, sys_connect_by_path(name, '/') from t1 start with id = 1 connect by prior id = pid order siblings by sys_connect_by_path(name, '/'); --unsupport case select prior id cc from t1 start with id = 1 connect by prior id = pid;