From 8619fc4745050381480b18ae5c94caa54e1eceb3 Mon Sep 17 00:00:00 2001 From: liujinyu Date: Fri, 7 Mar 2025 14:04:38 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E4=BF=AE=E5=A4=8Drotate=E4=B8=8D=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=81=9A=E5=90=88=E5=87=BD=E6=95=B0=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E5=8C=85=E5=90=AB=E5=B8=B8=E9=87=8F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/backend/parser/parse_clause.cpp | 54 +++++++++++++------ src/include/nodes/parsenodes_common.h | 4 ++ .../expected/gb_ora_rotate_unrotate.out | 8 +++ .../regress/sql/gb_ora_rotate_unrotate.sql | 2 + 4 files changed, 51 insertions(+), 17 deletions(-) diff --git a/src/common/backend/parser/parse_clause.cpp b/src/common/backend/parser/parse_clause.cpp index 160882119a..2929feaac8 100644 --- a/src/common/backend/parser/parse_clause.cpp +++ b/src/common/backend/parser/parse_clause.cpp @@ -89,7 +89,6 @@ static Node* transformGroupingSet(List** flatresult, ParseState* pstate, Groupin static Index transformGroupClauseExpr(List** flatresult, Bitmapset* seen_local, ParseState* pstate, Node* gexpr, List** targetlist, List* sortClause, ParseExprKind exprKind, bool useSQL99, bool toplevel); static void CheckOrderbyColumns(ParseState* pstate, List* targetList, bool isAggregate); -static bool ColNameInFuncParasList(char *colName, List *funcParaList); /* * @Description: append from clause item to the left tree @@ -594,6 +593,40 @@ static RangeTblEntry* transformCTEReference(ParseState* pstate, RangeVar* r, Com return rte; } +bool PullColumnRefWalker(Node* node, PullColumnRefContext* context) +{ + if (node == NULL) { + return false; + } + if (IsA(node, ColumnRef)) { + context->columnRefs = lappend(context->columnRefs, node); + return true; + } + return raw_expression_tree_walker(node, (bool (*)())PullColumnRefWalker, (void*)context); + } + +List* PullColumnRefs(Node* node) +{ + PullColumnRefContext context; + context.columnRefs = NIL; + + PullColumnRefWalker(node, &context); + + return context.columnRefs; + } + +static bool ColNameInFuncParasList(char* colName, List* columnsInAggFunc) +{ + ListCell* cell; + + foreach (cell, columnsInAggFunc) { + ColumnRef* cr = (ColumnRef*)lfirst(cell); + if (strcmp(colName, strVal(lfirst(list_head(cr->fields)))) == 0) + return true; + } + return false; +} + /* * transformRangeSubselect --- transform a sub-SELECT appearing in FROM */ @@ -625,6 +658,7 @@ static RangeTblEntry* transformRangeSubselect(ParseState* pstate, RangeSubselect ColumnRef *cref; ResTarget *resT; List *filterlist; + List *columnsInAggFunc = NIL; subQueryStmt = (SelectStmt *)r->subquery; prev = NULL; if (1 == list_length(subQueryStmt->targetList)) { @@ -658,13 +692,14 @@ static RangeTblEntry* transformRangeSubselect(ParseState* pstate, RangeSubselect } /* remove target */ + columnsInAggFunc = PullColumnRefs((Node*)r->rotate->aggregateFuncCallList); for (targetCell = list_head(subQueryStmt->targetList); targetCell; targetCell = next) { ResTarget *resTarget = (ResTarget *)lfirst(targetCell); next = lnext(targetCell); if (IsA(resTarget->val, ColumnRef)) { char *colName = strVal(lfirst(list_head(((ColumnRef *)resTarget->val)->fields))); if (list_member(r->rotate->forColName, lfirst(list_head(((ColumnRef *)resTarget->val)->fields))) || - ColNameInFuncParasList(colName, r->rotate->aggregateFuncCallList)) + ColNameInFuncParasList(colName, columnsInAggFunc)) subQueryStmt->targetList = list_delete_cell(subQueryStmt->targetList, targetCell, prev); else prev = targetCell; @@ -796,21 +831,6 @@ static RangeTblEntry* transformRangeSubselect(ParseState* pstate, RangeSubselect return rte; } -static bool ColNameInFuncParasList(char *colName, List *funcParaList) -{ - ListCell *cell; - ListCell *paracell; - foreach (cell, funcParaList) { - FuncCall *aggregateFuncCall = (FuncCall *)lfirst(cell); - foreach (paracell, aggregateFuncCall->args) { - ColumnRef *cr = (ColumnRef *)lfirst(paracell); - if (strcmp(colName, strVal(lfirst(list_head(cr->fields)))) == 0) - return true; - } - } - return false; -} - /* * transformRangeFunction --- transform a function call appearing in FROM */ diff --git a/src/include/nodes/parsenodes_common.h b/src/include/nodes/parsenodes_common.h index e678644475..39fd8a96f0 100644 --- a/src/include/nodes/parsenodes_common.h +++ b/src/include/nodes/parsenodes_common.h @@ -1568,6 +1568,10 @@ typedef struct ColumnRef { int location; /* token location, or -1 if unknown */ } ColumnRef; +typedef struct { + List* columnRefs; +}PullColumnRefContext; + /* * TimeCapsuleClause - TIMECAPSULE appearing in a transformed FROM clause * diff --git a/src/test/regress/expected/gb_ora_rotate_unrotate.out b/src/test/regress/expected/gb_ora_rotate_unrotate.out index a23d8ddd24..c67723ef65 100644 --- a/src/test/regress/expected/gb_ora_rotate_unrotate.out +++ b/src/test/regress/expected/gb_ora_rotate_unrotate.out @@ -31,6 +31,14 @@ select * from (select year, order_mode, order_total from original_orders) rotate 2022 | (3 rows) +select * from ( select year, order_mode, order_total from original_orders) rotate (sum(order_total + 100) for order_mode in ('direct' as store, 'online' as internet)) order by year; + year | store | internet +------+-------+---------- + 2020 | 5700 | 1100 + 2021 | 1100 | 1100 + 2022 | 5100 | +(3 rows) + create table rotate_orders as (select * from (select year, order_mode, order_total from original_orders) as t rotate (sum(order_total) for order_mode in ('direct' as store, 'online' as internet)) order by year); -- test not rotate (column transform to row) select * from rotate_orders not rotate ( yearly_total for order_mode in ( store as 'direct', internet as 'online')); diff --git a/src/test/regress/sql/gb_ora_rotate_unrotate.sql b/src/test/regress/sql/gb_ora_rotate_unrotate.sql index ea895c9b2a..8cb15d14c9 100644 --- a/src/test/regress/sql/gb_ora_rotate_unrotate.sql +++ b/src/test/regress/sql/gb_ora_rotate_unrotate.sql @@ -14,6 +14,8 @@ select * from tt rotate (sum(order_total) for order_mode in ('direct' as store, select * from (select year, order_mode, order_total from original_orders) rotate (sum(order_total) for order_mode in ('online' as internet )) order by year; +select * from ( select year, order_mode, order_total from original_orders) rotate (sum(order_total + 100) for order_mode in ('direct' as store, 'online' as internet)) order by year; + create table rotate_orders as (select * from (select year, order_mode, order_total from original_orders) as t rotate (sum(order_total) for order_mode in ('direct' as store, 'online' as internet)) order by year); -- test not rotate (column transform to row) -- Gitee From ff1041161fae05be28849fade00e7c1bfed6daa3 Mon Sep 17 00:00:00 2001 From: liujinyu Date: Fri, 14 Mar 2025 11:38:08 +0800 Subject: [PATCH 2/3] code check --- src/common/backend/parser/parse_clause.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/backend/parser/parse_clause.cpp b/src/common/backend/parser/parse_clause.cpp index 2929feaac8..e192d908f8 100644 --- a/src/common/backend/parser/parse_clause.cpp +++ b/src/common/backend/parser/parse_clause.cpp @@ -603,7 +603,7 @@ bool PullColumnRefWalker(Node* node, PullColumnRefContext* context) return true; } return raw_expression_tree_walker(node, (bool (*)())PullColumnRefWalker, (void*)context); - } +} List* PullColumnRefs(Node* node) { @@ -613,7 +613,7 @@ List* PullColumnRefs(Node* node) PullColumnRefWalker(node, &context); return context.columnRefs; - } +} static bool ColNameInFuncParasList(char* colName, List* columnsInAggFunc) { -- Gitee From 04433042b77c3b3ecafef34ee6c821cad3002157 Mon Sep 17 00:00:00 2001 From: liujinyu Date: Fri, 14 Mar 2025 15:01:26 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/backend/parser/parse_clause.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/backend/parser/parse_clause.cpp b/src/common/backend/parser/parse_clause.cpp index e192d908f8..3b8ae8f9c5 100644 --- a/src/common/backend/parser/parse_clause.cpp +++ b/src/common/backend/parser/parse_clause.cpp @@ -600,7 +600,7 @@ bool PullColumnRefWalker(Node* node, PullColumnRefContext* context) } if (IsA(node, ColumnRef)) { context->columnRefs = lappend(context->columnRefs, node); - return true; + return false; } return raw_expression_tree_walker(node, (bool (*)())PullColumnRefWalker, (void*)context); } -- Gitee