aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/ruleutils.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/ruleutils.c')
-rw-r--r--src/backend/utils/adt/ruleutils.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 4c83cae5e92..13685a0a0e4 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -5370,19 +5370,20 @@ get_select_query_def(Query *query, deparse_context *context,
}
/*
- * Detect whether query looks like SELECT ... FROM VALUES();
- * if so, return the VALUES RTE. Otherwise return NULL.
+ * Detect whether query looks like SELECT ... FROM VALUES(),
+ * with no need to rename the output columns of the VALUES RTE.
+ * If so, return the VALUES RTE. Otherwise return NULL.
*/
static RangeTblEntry *
-get_simple_values_rte(Query *query)
+get_simple_values_rte(Query *query, TupleDesc resultDesc)
{
RangeTblEntry *result = NULL;
ListCell *lc;
/*
- * We want to return true even if the Query also contains OLD or NEW rule
- * RTEs. So the idea is to scan the rtable and see if there is only one
- * inFromCl RTE that is a VALUES RTE.
+ * We want to detect a match even if the Query also contains OLD or NEW
+ * rule RTEs. So the idea is to scan the rtable and see if there is only
+ * one inFromCl RTE that is a VALUES RTE.
*/
foreach(lc, query->rtable)
{
@@ -5405,23 +5406,36 @@ get_simple_values_rte(Query *query)
* parser/analyze.c will never generate a "bare" VALUES RTE --- they only
* appear inside auto-generated sub-queries with very restricted
* structure. However, DefineView might have modified the tlist by
- * injecting new column aliases; so compare tlist resnames against the
- * RTE's names to detect that.
+ * injecting new column aliases, or we might have some other column
+ * aliases forced by a resultDesc. We can only simplify if the RTE's
+ * column names match the names that get_target_list() would select.
*/
if (result)
{
ListCell *lcn;
+ int colno;
if (list_length(query->targetList) != list_length(result->eref->colnames))
return NULL; /* this probably cannot happen */
+ colno = 0;
forboth(lc, query->targetList, lcn, result->eref->colnames)
{
TargetEntry *tle = (TargetEntry *) lfirst(lc);
char *cname = strVal(lfirst(lcn));
+ char *colname;
if (tle->resjunk)
return NULL; /* this probably cannot happen */
- if (tle->resname == NULL || strcmp(tle->resname, cname) != 0)
+
+ /* compute name that get_target_list would use for column */
+ colno++;
+ if (resultDesc && colno <= resultDesc->natts)
+ colname = NameStr(TupleDescAttr(resultDesc, colno - 1)->attname);
+ else
+ colname = tle->resname;
+
+ /* does it match the VALUES RTE? */
+ if (colname == NULL || strcmp(colname, cname) != 0)
return NULL; /* column name has been changed */
}
}
@@ -5449,7 +5463,7 @@ get_basic_select_query(Query *query, deparse_context *context,
* VALUES part. This reverses what transformValuesClause() did at parse
* time.
*/
- values_rte = get_simple_values_rte(query);
+ values_rte = get_simple_values_rte(query, resultDesc);
if (values_rte)
{
get_values_def(values_rte->values_lists, context);