static void checkRuleResultList(List *targetList, TupleDesc resultDesc,
- bool isSelect);
+ bool isSelect, bool requireColumnNameMatch);
static bool setRuleCheckAsUser_walker(Node *node, Oid *context);
static void setRuleCheckAsUser_Query(Query *qry, Oid userid);
*/
checkRuleResultList(query->targetList,
RelationGetDescr(event_relation),
- true);
+ true,
+ event_relation->rd_rel->relkind !=
+ RELKIND_MATVIEW);
/*
* ... there must not be another ON SELECT rule already ...
errmsg("RETURNING lists are not supported in non-INSTEAD rules")));
checkRuleResultList(query->returningList,
RelationGetDescr(event_relation),
- false);
+ false, false);
}
}
* Verify that targetList produces output compatible with a tupledesc
*
* The targetList might be either a SELECT targetlist, or a RETURNING list;
- * isSelect tells which. (This is mostly used for choosing error messages,
- * but also we don't enforce column name matching for RETURNING.)
+ * isSelect tells which. This is used for choosing error messages.
+ *
+ * A SELECT targetlist may optionally require that column names match.
*/
static void
-checkRuleResultList(List *targetList, TupleDesc resultDesc, bool isSelect)
+checkRuleResultList(List *targetList, TupleDesc resultDesc, bool isSelect,
+ bool requireColumnNameMatch)
{
ListCell *tllist;
int i;
+ /* Only a SELECT may require a column name match. */
+ Assert(isSelect || !requireColumnNameMatch);
+
i = 0;
foreach(tllist, targetList)
{
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot convert relation containing dropped columns to view")));
- if (isSelect && strcmp(tle->resname, attname) != 0)
+ if (requireColumnNameMatch && strcmp(tle->resname, attname) != 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("SELECT rule's target entry %d has different column name from \"%s\"", i, attname)));
WHERE col1 = (SELECT LEAST(col1) FROM mv1) WITH NO DATA;
DROP MATERIALIZED VIEW mv1 CASCADE;
NOTICE: drop cascades to materialized view mv2
+-- make sure that column names are handled correctly
+CREATE TABLE v (i int, j int);
+CREATE MATERIALIZED VIEW mv_v (ii) AS SELECT i, j AS jj FROM v;
+ALTER TABLE v RENAME COLUMN i TO x;
+INSERT INTO v values (1, 2);
+CREATE UNIQUE INDEX mv_v_ii ON mv_v (ii);
+REFRESH MATERIALIZED VIEW mv_v;
+SELECT * FROM v;
+ x | j
+---+---
+ 1 | 2
+(1 row)
+
+SELECT * FROM mv_v;
+ ii | jj
+----+----
+ 1 | 2
+(1 row)
+
+DROP TABLE v CASCADE;
+NOTICE: drop cascades to materialized view mv_v
CREATE MATERIALIZED VIEW mv2 AS SELECT * FROM mv1
WHERE col1 = (SELECT LEAST(col1) FROM mv1) WITH NO DATA;
DROP MATERIALIZED VIEW mv1 CASCADE;
+
+-- make sure that column names are handled correctly
+CREATE TABLE v (i int, j int);
+CREATE MATERIALIZED VIEW mv_v (ii) AS SELECT i, j AS jj FROM v;
+ALTER TABLE v RENAME COLUMN i TO x;
+INSERT INTO v values (1, 2);
+CREATE UNIQUE INDEX mv_v_ii ON mv_v (ii);
+REFRESH MATERIALIZED VIEW mv_v;
+SELECT * FROM v;
+SELECT * FROM mv_v;
+DROP TABLE v CASCADE;