From efb1577d060407076c548f8d2b2f62e1fa5bf165 Mon Sep 17 00:00:00 2001 From: Onder Kalaci Date: Wed, 11 Dec 2019 10:23:57 +0100 Subject: [PATCH] Handle CTE aliases accurately Basically, make sure to update the column name with the CTEs alias if we need to do so. --- src/backend/distributed/planner/cte_inline.c | 25 ++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/backend/distributed/planner/cte_inline.c b/src/backend/distributed/planner/cte_inline.c index f45c68fb2..a9ce33f0e 100644 --- a/src/backend/distributed/planner/cte_inline.c +++ b/src/backend/distributed/planner/cte_inline.c @@ -46,6 +46,8 @@ typedef struct inline_cte_walker_context int levelsup; int refcount; /* number of remaining references */ Query *ctequery; /* query to substitute */ + + List *aliascolnames; /* citus addition to Postgres' inline_cte_walker_context */ } inline_cte_walker_context; /* copy & paste from Postgres source, moved into a function for readability */ @@ -265,6 +267,7 @@ inline_cte(Query *mainQuery, CommonTableExpr *cte) context.levelsup = -1; context.refcount = cte->cterefcount; context.ctequery = castNode(Query, cte->ctequery); + context.aliascolnames = cte->aliascolnames; (void) inline_cte_walker((Node *) mainQuery, &context); @@ -333,6 +336,28 @@ inline_cte_walker(Node *node, inline_cte_walker_context *context) rte->subquery = newquery; rte->security_barrier = false; + List *columnAliasList = context->aliascolnames; + int columnAliasCount = list_length(columnAliasList); + int columnIndex = 1; + for (; columnIndex < list_length(rte->subquery->targetList) + 1; ++columnIndex) + { + /* + * Rename the column only if a column alias is defined. + * Notice that column alias count could be less than actual + * column count. We only use provided aliases and keep the + * original column names if no alias is defined. + */ + if (columnAliasCount >= columnIndex) + { + Value *columnAlias = (Value *) list_nth(columnAliasList, columnIndex - 1); + Assert(IsA(columnAlias, String)); + TargetEntry *targetEntry = + list_nth(rte->subquery->targetList, columnIndex - 1); + Assert(IsA(columnAlias, String)); + targetEntry->resname = strVal(columnAlias); + } + } + /* Zero out CTE-specific fields */ rte->ctename = NULL; rte->ctelevelsup = 0;