Fix breakage of MV column name list usage.
Per bug report from Tomonari Katsumata. Back-patch to 9.3.
This commit is contained in:
parent
dddc34408a
commit
732758db4c
|
@ -44,7 +44,7 @@
|
||||||
|
|
||||||
|
|
||||||
static void checkRuleResultList(List *targetList, TupleDesc resultDesc,
|
static void checkRuleResultList(List *targetList, TupleDesc resultDesc,
|
||||||
bool isSelect);
|
bool isSelect, bool requireColumnNameMatch);
|
||||||
static bool setRuleCheckAsUser_walker(Node *node, Oid *context);
|
static bool setRuleCheckAsUser_walker(Node *node, Oid *context);
|
||||||
static void setRuleCheckAsUser_Query(Query *qry, Oid userid);
|
static void setRuleCheckAsUser_Query(Query *qry, Oid userid);
|
||||||
|
|
||||||
|
@ -355,7 +355,9 @@ DefineQueryRewrite(char *rulename,
|
||||||
*/
|
*/
|
||||||
checkRuleResultList(query->targetList,
|
checkRuleResultList(query->targetList,
|
||||||
RelationGetDescr(event_relation),
|
RelationGetDescr(event_relation),
|
||||||
true);
|
true,
|
||||||
|
event_relation->rd_rel->relkind !=
|
||||||
|
RELKIND_MATVIEW);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ... there must not be another ON SELECT rule already ...
|
* ... 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")));
|
errmsg("RETURNING lists are not supported in non-INSTEAD rules")));
|
||||||
checkRuleResultList(query->returningList,
|
checkRuleResultList(query->returningList,
|
||||||
RelationGetDescr(event_relation),
|
RelationGetDescr(event_relation),
|
||||||
false);
|
false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -613,15 +615,20 @@ DefineQueryRewrite(char *rulename,
|
||||||
* Verify that targetList produces output compatible with a tupledesc
|
* Verify that targetList produces output compatible with a tupledesc
|
||||||
*
|
*
|
||||||
* The targetList might be either a SELECT targetlist, or a RETURNING list;
|
* The targetList might be either a SELECT targetlist, or a RETURNING list;
|
||||||
* isSelect tells which. (This is mostly used for choosing error messages,
|
* isSelect tells which. This is used for choosing error messages.
|
||||||
* but also we don't enforce column name matching for RETURNING.)
|
*
|
||||||
|
* A SELECT targetlist may optionally require that column names match.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
checkRuleResultList(List *targetList, TupleDesc resultDesc, bool isSelect)
|
checkRuleResultList(List *targetList, TupleDesc resultDesc, bool isSelect,
|
||||||
|
bool requireColumnNameMatch)
|
||||||
{
|
{
|
||||||
ListCell *tllist;
|
ListCell *tllist;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
/* Only a SELECT may require a column name match. */
|
||||||
|
Assert(isSelect || !requireColumnNameMatch);
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
foreach(tllist, targetList)
|
foreach(tllist, targetList)
|
||||||
{
|
{
|
||||||
|
@ -657,7 +664,7 @@ checkRuleResultList(List *targetList, TupleDesc resultDesc, bool isSelect)
|
||||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
errmsg("cannot convert relation containing dropped columns to view")));
|
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,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
||||||
errmsg("SELECT rule's target entry %d has different column name from \"%s\"", i, attname)));
|
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;
|
DROP TABLE boxes CASCADE;
|
||||||
NOTICE: drop cascades to materialized view boxmv
|
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;
|
REFRESH MATERIALIZED VIEW CONCURRENTLY boxmv;
|
||||||
SELECT * FROM boxmv ORDER BY id;
|
SELECT * FROM boxmv ORDER BY id;
|
||||||
DROP TABLE boxes CASCADE;
|
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;
|
||||||
|
|
Loading…
Reference in New Issue