Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 732758d

Browse files
committed
Fix breakage of MV column name list usage.
Per bug report from Tomonari Katsumata. Back-patch to 9.3.
1 parent dddc344 commit 732758d

File tree

3 files changed

+50
-7
lines changed

3 files changed

+50
-7
lines changed

src/backend/rewrite/rewriteDefine.c

+14-7
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444

4545

4646
static void checkRuleResultList(List *targetList, TupleDesc resultDesc,
47-
bool isSelect);
47+
bool isSelect, bool requireColumnNameMatch);
4848
static bool setRuleCheckAsUser_walker(Node *node, Oid *context);
4949
static void setRuleCheckAsUser_Query(Query *qry, Oid userid);
5050

@@ -355,7 +355,9 @@ DefineQueryRewrite(char *rulename,
355355
*/
356356
checkRuleResultList(query->targetList,
357357
RelationGetDescr(event_relation),
358-
true);
358+
true,
359+
event_relation->rd_rel->relkind !=
360+
RELKIND_MATVIEW);
359361

360362
/*
361363
* ... there must not be another ON SELECT rule already ...
@@ -484,7 +486,7 @@ DefineQueryRewrite(char *rulename,
484486
errmsg("RETURNING lists are not supported in non-INSTEAD rules")));
485487
checkRuleResultList(query->returningList,
486488
RelationGetDescr(event_relation),
487-
false);
489+
false, false);
488490
}
489491
}
490492

@@ -613,15 +615,20 @@ DefineQueryRewrite(char *rulename,
613615
* Verify that targetList produces output compatible with a tupledesc
614616
*
615617
* The targetList might be either a SELECT targetlist, or a RETURNING list;
616-
* isSelect tells which. (This is mostly used for choosing error messages,
617-
* but also we don't enforce column name matching for RETURNING.)
618+
* isSelect tells which. This is used for choosing error messages.
619+
*
620+
* A SELECT targetlist may optionally require that column names match.
618621
*/
619622
static void
620-
checkRuleResultList(List *targetList, TupleDesc resultDesc, bool isSelect)
623+
checkRuleResultList(List *targetList, TupleDesc resultDesc, bool isSelect,
624+
bool requireColumnNameMatch)
621625
{
622626
ListCell *tllist;
623627
int i;
624628

629+
/* Only a SELECT may require a column name match. */
630+
Assert(isSelect || !requireColumnNameMatch);
631+
625632
i = 0;
626633
foreach(tllist, targetList)
627634
{
@@ -657,7 +664,7 @@ checkRuleResultList(List *targetList, TupleDesc resultDesc, bool isSelect)
657664
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
658665
errmsg("cannot convert relation containing dropped columns to view")));
659666

660-
if (isSelect && strcmp(tle->resname, attname) != 0)
667+
if (requireColumnNameMatch && strcmp(tle->resname, attname) != 0)
661668
ereport(ERROR,
662669
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
663670
errmsg("SELECT rule's target entry %d has different column name from \"%s\"", i, attname)));

src/test/regress/expected/matview.out

+23
Original file line numberDiff line numberDiff line change
@@ -450,3 +450,26 @@ SELECT * FROM boxmv ORDER BY id;
450450

451451
DROP TABLE boxes CASCADE;
452452
NOTICE: drop cascades to materialized view boxmv
453+
-- make sure that column names are handled correctly
454+
CREATE TABLE v (i int, j int);
455+
CREATE MATERIALIZED VIEW mv_v (ii) AS SELECT i, j AS jj FROM v;
456+
ALTER TABLE v RENAME COLUMN i TO x;
457+
INSERT INTO v values (1, 2);
458+
CREATE UNIQUE INDEX mv_v_ii ON mv_v (ii);
459+
REFRESH MATERIALIZED VIEW mv_v;
460+
UPDATE v SET j = 3 WHERE x = 1;
461+
REFRESH MATERIALIZED VIEW CONCURRENTLY mv_v;
462+
SELECT * FROM v;
463+
x | j
464+
---+---
465+
1 | 3
466+
(1 row)
467+
468+
SELECT * FROM mv_v;
469+
ii | jj
470+
----+----
471+
1 | 3
472+
(1 row)
473+
474+
DROP TABLE v CASCADE;
475+
NOTICE: drop cascades to materialized view mv_v

src/test/regress/sql/matview.sql

+13
Original file line numberDiff line numberDiff line change
@@ -173,3 +173,16 @@ UPDATE boxes SET b = '(2,2),(1,1)' WHERE id = 2;
173173
REFRESH MATERIALIZED VIEW CONCURRENTLY boxmv;
174174
SELECT * FROM boxmv ORDER BY id;
175175
DROP TABLE boxes CASCADE;
176+
177+
-- make sure that column names are handled correctly
178+
CREATE TABLE v (i int, j int);
179+
CREATE MATERIALIZED VIEW mv_v (ii) AS SELECT i, j AS jj FROM v;
180+
ALTER TABLE v RENAME COLUMN i TO x;
181+
INSERT INTO v values (1, 2);
182+
CREATE UNIQUE INDEX mv_v_ii ON mv_v (ii);
183+
REFRESH MATERIALIZED VIEW mv_v;
184+
UPDATE v SET j = 3 WHERE x = 1;
185+
REFRESH MATERIALIZED VIEW CONCURRENTLY mv_v;
186+
SELECT * FROM v;
187+
SELECT * FROM mv_v;
188+
DROP TABLE v CASCADE;

0 commit comments

Comments
 (0)