aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/parser/parse_relation.c17
-rw-r--r--src/backend/rewrite/rewriteHandler.c16
2 files changed, 27 insertions, 6 deletions
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c
index 9524d2810a0..7d40f4ce372 100644
--- a/src/backend/parser/parse_relation.c
+++ b/src/backend/parser/parse_relation.c
@@ -2577,12 +2577,17 @@ expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
Assert(varattno == te->resno);
/*
- * In scenarios where columns have been added to a view
- * since the outer query was originally parsed, there can
- * be more items in the subquery tlist than the outer
- * query expects. We should ignore such extra column(s)
- * --- compare the behavior for composite-returning
- * functions, in the RTE_FUNCTION case below.
+ * In a just-parsed subquery RTE, rte->eref->colnames
+ * should always have exactly as many entries as the
+ * subquery has non-junk output columns. However, if the
+ * subquery RTE was created by expansion of a view,
+ * perhaps the subquery tlist could now have more entries
+ * than existed when the outer query was parsed. Such
+ * cases should now be prevented because ApplyRetrieveRule
+ * will extend the colnames list to match. But out of
+ * caution, we'll keep the code like this in the back
+ * branches: just ignore any columns that lack colnames
+ * entries.
*/
if (!aliasp_item)
break;
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index aef74f7cba9..f187ca7b92f 100644
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -26,6 +26,7 @@
#include "catalog/dependency.h"
#include "catalog/pg_type.h"
#include "commands/trigger.h"
+#include "executor/executor.h"
#include "foreign/fdwapi.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
@@ -1668,6 +1669,7 @@ ApplyRetrieveRule(Query *parsetree,
RangeTblEntry *rte,
*subrte;
RowMarkClause *rc;
+ int numCols;
if (list_length(rule->actions) != 1)
elog(ERROR, "expected just one rule action");
@@ -1827,6 +1829,20 @@ ApplyRetrieveRule(Query *parsetree,
rte->updatedCols = NULL;
rte->extraUpdatedCols = NULL;
+ /*
+ * Since we allow CREATE OR REPLACE VIEW to add columns to a view, the
+ * rule_action might emit more columns than we expected when the current
+ * query was parsed. Various places expect rte->eref->colnames to be
+ * consistent with the non-junk output columns of the subquery, so patch
+ * things up if necessary by adding some dummy column names.
+ */
+ numCols = ExecCleanTargetListLength(rule_action->targetList);
+ while (list_length(rte->eref->colnames) < numCols)
+ {
+ rte->eref->colnames = lappend(rte->eref->colnames,
+ makeString(pstrdup("?column?")));
+ }
+
return parsetree;
}