Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5b6ee03

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

File tree

3 files changed

+46
-7
lines changed

3 files changed

+46
-7
lines changed

src/backend/rewrite/rewriteDefine.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343

4444

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

@@ -358,7 +358,9 @@ DefineQueryRewrite(char *rulename,
358358
*/
359359
checkRuleResultList(query->targetList,
360360
RelationGetDescr(event_relation),
361-
true);
361+
true,
362+
event_relation->rd_rel->relkind !=
363+
RELKIND_MATVIEW);
362364

363365
/*
364366
* ... 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

@@ -616,15 +618,20 @@ DefineQueryRewrite(char *rulename,
616618
* Verify that targetList produces output compatible with a tupledesc
617619
*
618620
* The targetList might be either a SELECT targetlist, or a RETURNING list;
619-
* isSelect tells which. (This is mostly used for choosing error messages,
620-
* but also we don't enforce column name matching for RETURNING.)
621+
* isSelect tells which. This is used for choosing error messages.
622+
*
623+
* A SELECT targetlist may optionally require that column names match.
621624
*/
622625
static void
623-
checkRuleResultList(List *targetList, TupleDesc resultDesc, bool isSelect)
626+
checkRuleResultList(List *targetList, TupleDesc resultDesc, bool isSelect,
627+
bool requireColumnNameMatch)
624628
{
625629
ListCell *tllist;
626630
int i;
627631

632+
/* Only a SELECT may require a column name match. */
633+
Assert(isSelect || !requireColumnNameMatch);
634+
628635
i = 0;
629636
foreach(tllist, targetList)
630637
{
@@ -660,7 +667,7 @@ checkRuleResultList(List *targetList, TupleDesc resultDesc, bool isSelect)
660667
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
661668
errmsg("cannot convert relation containing dropped columns to view")));
662669

663-
if (isSelect && strcmp(tle->resname, attname) != 0)
670+
if (requireColumnNameMatch && strcmp(tle->resname, attname) != 0)
664671
ereport(ERROR,
665672
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
666673
errmsg("SELECT rule's target entry %d has different column name from \"%s\"", i, attname)));

src/test/regress/expected/matview.out

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,3 +391,24 @@ CREATE MATERIALIZED VIEW mv2 AS SELECT * FROM mv1
391391
WHERE col1 = (SELECT LEAST(col1) FROM mv1) WITH NO DATA;
392392
DROP MATERIALIZED VIEW mv1 CASCADE;
393393
NOTICE: drop cascades to materialized view mv2
394+
-- make sure that column names are handled correctly
395+
CREATE TABLE v (i int, j int);
396+
CREATE MATERIALIZED VIEW mv_v (ii) AS SELECT i, j AS jj FROM v;
397+
ALTER TABLE v RENAME COLUMN i TO x;
398+
INSERT INTO v values (1, 2);
399+
CREATE UNIQUE INDEX mv_v_ii ON mv_v (ii);
400+
REFRESH MATERIALIZED VIEW mv_v;
401+
SELECT * FROM v;
402+
x | j
403+
---+---
404+
1 | 2
405+
(1 row)
406+
407+
SELECT * FROM mv_v;
408+
ii | jj
409+
----+----
410+
1 | 2
411+
(1 row)
412+
413+
DROP TABLE v CASCADE;
414+
NOTICE: drop cascades to materialized view mv_v

src/test/regress/sql/matview.sql

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,14 @@ CREATE MATERIALIZED VIEW mv1 AS SELECT 1 AS col1 WITH NO DATA;
130130
CREATE MATERIALIZED VIEW mv2 AS SELECT * FROM mv1
131131
WHERE col1 = (SELECT LEAST(col1) FROM mv1) WITH NO DATA;
132132
DROP MATERIALIZED VIEW mv1 CASCADE;
133+
134+
-- make sure that column names are handled correctly
135+
CREATE TABLE v (i int, j int);
136+
CREATE MATERIALIZED VIEW mv_v (ii) AS SELECT i, j AS jj FROM v;
137+
ALTER TABLE v RENAME COLUMN i TO x;
138+
INSERT INTO v values (1, 2);
139+
CREATE UNIQUE INDEX mv_v_ii ON mv_v (ii);
140+
REFRESH MATERIALIZED VIEW mv_v;
141+
SELECT * FROM v;
142+
SELECT * FROM mv_v;
143+
DROP TABLE v CASCADE;

0 commit comments

Comments
 (0)