From 7a848eddcee901d219b29d82372932756d7b8bb0 Mon Sep 17 00:00:00 2001 From: Mijamind Date: Mon, 20 Nov 2023 15:16:08 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E8=B5=84=E6=BA=90=E6=B1=A0=E5=8C=96?= =?UTF-8?q?=E3=80=91=E4=BF=AE=E5=A4=8D=E5=8C=85=E5=90=ABwindow=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E6=89=A7=E8=A1=8C=E8=AE=A1=E5=88=92=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/backend/utils/adt/ruleutils.cpp | 173 +++++++++++++++++---- src/gausskernel/optimizer/util/tlist.cpp | 25 +++ src/include/nodes/parsenodes.h | 4 + src/include/optimizer/tlist.h | 1 + 4 files changed, 169 insertions(+), 34 deletions(-) diff --git a/src/common/backend/utils/adt/ruleutils.cpp b/src/common/backend/utils/adt/ruleutils.cpp index c36411461..7c8ca4ab9 100644 --- a/src/common/backend/utils/adt/ruleutils.cpp +++ b/src/common/backend/utils/adt/ruleutils.cpp @@ -276,6 +276,9 @@ static void get_basic_select_query(Query* query, deparse_context* context, Tuple static void get_target_list(Query* query, List* targetList, deparse_context* context, TupleDesc resultDesc); static void get_setop_query(Node* setOp, Query* query, deparse_context* context, TupleDesc resultDesc); static Node* get_rule_sortgroupclause(Index ref, List* tlist, bool force_colno, deparse_context* context); +#ifdef USE_SPQ +static Node* get_rule_sortgroupclause_spq(Index ref, bool force_colno, deparse_context* context); +#endif static void get_rule_groupingset(GroupingSet* gset, List* targetlist, deparse_context* context); static void get_rule_orderby(List* orderList, List* targetList, bool force_colno, deparse_context* context); static void get_rule_windowclause(Query* query, deparse_context* context); @@ -6784,6 +6787,59 @@ static Node* get_rule_sortgroupclause(Index ref, List* tlist, bool force_colno, return expr; } +#ifdef USE_SPQ +/* + * Display a sort/group clause. + * + * Also returns the expression tree, so caller need not find it again. + */ + +static Node* get_rule_sortgroupclause_spq(Index ref, bool force_colno, deparse_context* context) +{ + StringInfo buf = context->buf; + TargetEntry* tle = NULL; + Node* expr = NULL; + List* tlist; + + deparse_namespace* dpns_spq = (deparse_namespace*)linitial(context->namespaces); + PlanState* ps = dpns_spq->planstate; + WindowAgg* node = NULL; + node = (WindowAgg*)ps->plan; + tlist = node->plan.lefttree->targetlist; + + if (tlist == NULL){ + return expr; + } + + tle = get_sortgroupref_tle_spq(ref, tlist); + expr = (Node*)tle->expr; + + deparse_namespace* dpns = NULL; + deparse_namespace save_dpns; + + dpns = (deparse_namespace*)list_nth(context->namespaces, ((Var*)expr)->varlevelsup); + push_child_plan(dpns, dpns->outer_planstate, &save_dpns); + + + /* + * Use column-number form if requested by caller. Otherwise, if + * expression is a constant, force it to be dumped with an explicit cast + * as decoration --- this is because a simple integer constant is + * ambiguous (and will be misinterpreted by findTargetlistEntry()) if we + * dump it without any decoration. Otherwise, just dump the expression + * normally. + */ + if (force_colno || context->sortgroup_colno) { + Assert(!tle->resjunk); + appendStringInfo(buf, "%d", tle->resno); + } else if (expr && IsA(expr, Var)) + get_rule_expr(expr, context, true); + + pop_child_plan(dpns, &save_dpns); + + return expr; +} +#endif /* * @Description: Display a GroupingSet. @@ -6860,7 +6916,15 @@ static void get_rule_orderby(List* orderList, List* targetList, bool force_colno TypeCacheEntry* typentry = NULL; appendStringInfoString(buf, sep); - sortexpr = get_rule_sortgroupclause(srt->tleSortGroupRef, targetList, force_colno, context); +#ifdef USE_SPQ + if (IS_SPQ_COORDINATOR && (list_length(context->windowClause) > 0) && + lfirst(list_head(context->windowClause)) != NULL && + ((WindowClause *)lfirst(list_head(context->windowClause)))->reOrderSPQ) { + sortexpr = get_rule_sortgroupclause_spq(srt->tleSortGroupRef, force_colno, context); + } else +#endif + sortexpr = get_rule_sortgroupclause(srt->tleSortGroupRef, targetList, force_colno, context); + sortcoltype = exprType(sortexpr); /* See whether operator is default < or > for datatype */ typentry = lookup_type_cache(sortcoltype, TYPECACHE_LT_OPR | TYPECACHE_GT_OPR); @@ -6942,7 +7006,12 @@ static void get_rule_windowspec(WindowClause* wc, List* targetList, deparse_cont SortGroupClause* grp = (SortGroupClause*)lfirst(l); appendStringInfoString(buf, sep); - get_rule_sortgroupclause(grp->tleSortGroupRef, targetList, false, context); +#ifdef USE_SPQ + if (IS_SPQ_COORDINATOR && wc->rePartitionSPQ) { + get_rule_sortgroupclause_spq(grp->tleSortGroupRef, false, context); + } else +#endif + get_rule_sortgroupclause(grp->tleSortGroupRef, targetList, false, context); sep = ", "; } needspace = true; @@ -7041,7 +7110,13 @@ static void get_rule_windowspec_listagg(WindowClause* wc, List* targetList, depa SortGroupClause* grp = (SortGroupClause*)lfirst(l); appendStringInfoString(buf, sep); - get_rule_sortgroupclause(grp->tleSortGroupRef, targetList, false, context); +#ifdef USE_SPQ + if (IS_SPQ_COORDINATOR && wc->rePartitionSPQ) { + get_rule_sortgroupclause_spq(grp->tleSortGroupRef, false, context); + } else +#endif + get_rule_sortgroupclause(grp->tleSortGroupRef, targetList, false, context); + sep = ", "; } needspace = true; @@ -10701,23 +10776,38 @@ static bool construct_partitionClause(WindowAgg* node, WindowClause* wc) * ressortgroupref refers to windowagg's tlist * partColIdx refers to subplan's tlist */ - ListCell *lc = NULL; - foreach(lc, node->plan.targetlist) { - TargetEntry *window_agg_te = (TargetEntry *)lfirst(lc); - if (IsA(tle->expr, Var) && IsA(window_agg_te->expr, Var) && - _equalSimpleVar(tle->expr, window_agg_te->expr)) { - if (window_agg_te->ressortgroupref > 0) { - partcl->tleSortGroupRef = window_agg_te->ressortgroupref; - /* found it */ - break; +#ifdef USE_SPQ + wc->rePartitionSPQ = false; + if (IS_SPQ_COORDINATOR) { + if (IsA(tle->expr, Var)) { + Var* tle_expr = (Var*)tle->expr; + partcl->tleSortGroupRef = tle_expr->varattno; + wc->rePartitionSPQ = true; + } else { + list_free_ext(partitionClause); + return false; + } + } else +#endif + { + ListCell *lc = NULL; + foreach(lc, node->plan.targetlist) { + TargetEntry *window_agg_te = (TargetEntry *)lfirst(lc); + if (IsA(tle->expr, Var) && IsA(window_agg_te->expr, Var) && + _equalSimpleVar(tle->expr, window_agg_te->expr)) { + if (window_agg_te->ressortgroupref > 0) { + partcl->tleSortGroupRef = window_agg_te->ressortgroupref; + /* found it */ + break; + } } } - } - if (lc == NULL) { - /* not found */ - list_free_ext(partitionClause); - return false; + if (lc == NULL) { + /* not found */ + list_free_ext(partitionClause); + return false; + } } partcl->eqop = node->partOperators[i]; @@ -10764,26 +10854,41 @@ static void construct_windowClause(deparse_context* context) } /* - * ressortgroupref refers to windowagg's tlist - * partColIdx refers to subplan's tlist - */ - ListCell *lc = NULL; - foreach(lc, node->plan.targetlist) { - TargetEntry *window_agg_te = (TargetEntry *)lfirst(lc); - if (IsA(tle->expr, Var) && IsA(window_agg_te->expr, Var) && - _equalSimpleVar(tle->expr, window_agg_te->expr)) { - if (window_agg_te->ressortgroupref > 0) { - sortcl->tleSortGroupRef = window_agg_te->ressortgroupref; - /* found it */ - break; + * ressortgroupref refers to windowagg's tlist + * partColIdx refers to subplan's tlist + */ +#ifdef USE_SPQ + wc->reOrderSPQ = false; + if (IS_SPQ_COORDINATOR) { + if (IsA(tle->expr, Var)) { + Var* tle_expr = (Var*)tle->expr; + sortcl->tleSortGroupRef = tle_expr->varattno; + wc->reOrderSPQ = true; + } else { + list_free_ext(orderClause); + return; + } + } else +#endif + { + ListCell *lc = NULL; + foreach(lc, node->plan.targetlist) { + TargetEntry *window_agg_te = (TargetEntry *)lfirst(lc); + if (IsA(tle->expr, Var) && IsA(window_agg_te->expr, Var) && + _equalSimpleVar(tle->expr, window_agg_te->expr)) { + if (window_agg_te->ressortgroupref > 0) { + sortcl->tleSortGroupRef = window_agg_te->ressortgroupref; + /* found it */ + break; + } } } - } - if (lc == NULL) { - list_free_ext(orderClause); - /* not found */ - return; + if (lc == NULL) { + list_free_ext(orderClause); + /* not found */ + return; + } } sortcl->sortop = node->ordOperators[i]; diff --git a/src/gausskernel/optimizer/util/tlist.cpp b/src/gausskernel/optimizer/util/tlist.cpp index 6006c2d9f..c3cd04ec9 100644 --- a/src/gausskernel/optimizer/util/tlist.cpp +++ b/src/gausskernel/optimizer/util/tlist.cpp @@ -1539,4 +1539,29 @@ Index maxSortGroupRef(List *targetlist, bool include_orderedagg) return context.maxsgr; } + +/* + * get_sortgroupref_tle_spq + * Find the targetlist entry matching the given SortGroupRef index, + * and return it. + */ +TargetEntry* get_sortgroupref_tle_spq(Index sortref, List* targetList, bool report_error) +{ + ListCell* l = NULL; + + foreach (l, targetList) { + TargetEntry* tle = (TargetEntry*)lfirst(l); + + if (IS_SPQ_COORDINATOR && tle->resno == sortref && tle->ressortgroupref == 0) { + return tle; + } + } + + if (report_error) + ereport(ERROR, + (errmodule(MOD_OPT), + errcode(ERRCODE_GROUPING_ERROR), + errmsg("ORDER/GROUP BY expression not found in targetlist"))); + return NULL; +} #endif diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 633d0aa89..cef077333 100755 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -496,6 +496,10 @@ typedef struct WindowClause { Node* endOffset; /* expression for ending bound, if any */ Index winref; /* ID referenced by window functions */ bool copiedOrder; /* did we copy orderClause from refname? */ +#ifdef USE_SPQ + bool rePartitionSPQ; /* did we reassign the tleSortGroupRef when constructing partition Clause */ + bool reOrderSPQ; /* did we reassign the tleSortGroupRef when constructing order Clause */ +#endif } WindowClause; /* diff --git a/src/include/optimizer/tlist.h b/src/include/optimizer/tlist.h index 5db0e244b..8c77b8789 100644 --- a/src/include/optimizer/tlist.h +++ b/src/include/optimizer/tlist.h @@ -71,6 +71,7 @@ extern bool split_pathtarget_at_srfs(PlannerInfo *root, PathTarget *target, Path extern List* tlist_members(Node* node, List* targetlist); extern void get_sortgroupclauses_tles(List *clauses, List *targetList, List **tles, List **sortops, List **eqops); extern Index maxSortGroupRef(List *targetlist, bool include_orderedagg); +extern TargetEntry* get_sortgroupref_tle_spq(Index sortref, List* targetList, bool report_error = true); #endif #endif /* TLIST_H */