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.c39
1 files changed, 35 insertions, 4 deletions
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index c1d860ceffd..2fa30be401f 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -4498,10 +4498,7 @@ get_simple_values_rte(Query *query)
/*
* 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 don't look at the targetlist at
- * all. This is okay because parser/analyze.c will never generate a
- * "bare" VALUES RTE --- they only appear inside auto-generated
- * sub-queries with very restricted structure.
+ * inFromCl RTE that is a VALUES RTE.
*/
foreach(lc, query->rtable)
{
@@ -4518,6 +4515,33 @@ get_simple_values_rte(Query *query)
else
return NULL; /* something else -> not simple VALUES */
}
+
+ /*
+ * We don't need to check the targetlist in any great detail, because
+ * 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.
+ */
+ if (result)
+ {
+ ListCell *lcn;
+
+ if (list_length(query->targetList) != list_length(result->eref->colnames))
+ return NULL; /* this probably cannot happen */
+ forboth(lc, query->targetList, lcn, result->eref->colnames)
+ {
+ TargetEntry *tle = (TargetEntry *) lfirst(lc);
+ char *cname = strVal(lfirst(lcn));
+
+ if (tle->resjunk)
+ return NULL; /* this probably cannot happen */
+ if (tle->resname == NULL || strcmp(tle->resname, cname) != 0)
+ return NULL; /* column name has been changed */
+ }
+ }
+
return result;
}
@@ -8517,7 +8541,9 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
break;
case RTE_VALUES:
/* Values list RTE */
+ appendStringInfoChar(buf, '(');
get_values_def(rte->values_lists, context);
+ appendStringInfoChar(buf, ')');
break;
case RTE_CTE:
appendStringInfoString(buf, quote_identifier(rte->ctename));
@@ -8559,6 +8585,11 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
*/
printalias = true;
}
+ else if (rte->rtekind == RTE_VALUES)
+ {
+ /* Alias is syntactically required for VALUES */
+ printalias = true;
+ }
else if (rte->rtekind == RTE_CTE)
{
/*