Handle CTE aliases accurately

Basically, make sure to update the column name with the CTEs alias
if we need to do so.
pull/3161/head
Onder Kalaci 2019-12-11 10:23:57 +01:00 committed by Jelte Fennema
parent 05d600dd8f
commit efb1577d06
1 changed files with 25 additions and 0 deletions

View File

@ -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;