Skip to content
Snippets Groups Projects
Commit 732758db authored by Kevin Grittner's avatar Kevin Grittner
Browse files

Fix breakage of MV column name list usage.

Per bug report from Tomonari Katsumata.

Back-patch to 9.3.
parent dddc3440
Branches
Tags
No related merge requests found
......@@ -44,7 +44,7 @@
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);
......@@ -355,7 +355,9 @@ DefineQueryRewrite(char *rulename,
*/
checkRuleResultList(query->targetList,
RelationGetDescr(event_relation),
true);
true,
event_relation->rd_rel->relkind !=
RELKIND_MATVIEW);
/*
* ... there must not be another ON SELECT rule already ...
......@@ -484,7 +486,7 @@ DefineQueryRewrite(char *rulename,
errmsg("RETURNING lists are not supported in non-INSTEAD rules")));
checkRuleResultList(query->returningList,
RelationGetDescr(event_relation),
false);
false, false);
}
}
......@@ -613,15 +615,20 @@ DefineQueryRewrite(char *rulename,
* 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)
{
......@@ -657,7 +664,7 @@ checkRuleResultList(List *targetList, TupleDesc resultDesc, bool isSelect)
(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)));
......
......@@ -450,3 +450,26 @@ SELECT * FROM boxmv ORDER BY id;
DROP TABLE boxes CASCADE;
NOTICE: drop cascades to materialized view boxmv
-- 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;
UPDATE v SET j = 3 WHERE x = 1;
REFRESH MATERIALIZED VIEW CONCURRENTLY mv_v;
SELECT * FROM v;
x | j
---+---
1 | 3
(1 row)
SELECT * FROM mv_v;
ii | jj
----+----
1 | 3
(1 row)
DROP TABLE v CASCADE;
NOTICE: drop cascades to materialized view mv_v
......@@ -173,3 +173,16 @@ UPDATE boxes SET b = '(2,2),(1,1)' WHERE id = 2;
REFRESH MATERIALIZED VIEW CONCURRENTLY boxmv;
SELECT * FROM boxmv ORDER BY id;
DROP TABLE boxes 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;
UPDATE v SET j = 3 WHERE x = 1;
REFRESH MATERIALIZED VIEW CONCURRENTLY mv_v;
SELECT * FROM v;
SELECT * FROM mv_v;
DROP TABLE v CASCADE;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment