Skip to content

Commit e03740b

Browse files
avaminglimy-ship-it
authored andcommitted
Fix writable CTE cause wrong matview data status.
CTE is not well supported in GPDB, if a writable operation inside CTE is actually executed, it may cause matview data status fail to catch up with the underlying relation. create table t_cte_issue_582(i int, j int); create materialized view mv_t_cte_issue_582 as select j from t_cte_issue_582 where i = 1; with mod1 as (insert into t_cte_issue_582 values(1, 1) returning *) select * from mod1; The CTE sql will insert data into t_cte_issue_582, and the data status of matviews have that relation should be updated. Fix CTE part issue of #582 Authored-by: Zhang Mingli avamingli@gmail.com
1 parent f038fbf commit e03740b

3 files changed

Lines changed: 70 additions & 27 deletions

File tree

src/backend/executor/execMain.c

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,39 +1045,40 @@ standard_ExecutorRun(QueryDesc *queryDesc,
10451045
* after that.
10461046
*/
10471047
if (IS_QD_OR_SINGLENODE() &&
1048-
((es_processed > 0 || estate->es_processed > 0) ||
1049-
!queryDesc->plannedstmt->canSetTag))
1048+
(operation == CMD_INSERT || operation == CMD_UPDATE || operation == CMD_DELETE ||
1049+
queryDesc->plannedstmt->hasModifyingCTE) &&
1050+
((es_processed > 0 || estate->es_processed > 0) || !queryDesc->plannedstmt->canSetTag))
10501051
{
1051-
if (operation == CMD_INSERT ||
1052-
operation == CMD_UPDATE ||
1053-
operation == CMD_DELETE)
1052+
List *rtable = queryDesc->plannedstmt->rtable;
1053+
int length = list_length(rtable);
1054+
ListCell *lc;
1055+
foreach(lc, queryDesc->plannedstmt->resultRelations)
10541056
{
1055-
List *rtable =queryDesc->plannedstmt->rtable;
1056-
int length = list_length(rtable);
1057-
ListCell *lc;
1058-
foreach(lc, queryDesc->plannedstmt->resultRelations)
1059-
{
1060-
int varno = lfirst_int(lc);
1057+
int varno = lfirst_int(lc);
10611058

1062-
/* Avoid crash in case we don't find a rte. */
1063-
if (varno > length + 1)
1064-
{
1065-
ereport(WARNING, (errmsg("could not find rte of varno: %u ", varno)));
1066-
continue;
1067-
}
1059+
/* Avoid crash in case we don't find a rte. */
1060+
if (varno > length + 1)
1061+
{
1062+
ereport(WARNING, (errmsg("could not find rte of varno: %u ", varno)));
1063+
continue;
1064+
}
10681065

1069-
RangeTblEntry *rte = rt_fetch(varno, rtable);
1070-
switch (operation)
1066+
RangeTblEntry *rte = rt_fetch(varno, rtable);
1067+
switch (operation)
1068+
{
1069+
case CMD_INSERT:
1070+
SetRelativeMatviewAuxStatus(rte->relid, MV_DATA_STATUS_EXPIRED_INSERT_ONLY);
1071+
break;
1072+
case CMD_UPDATE:
1073+
case CMD_DELETE:
1074+
SetRelativeMatviewAuxStatus(rte->relid, MV_DATA_STATUS_EXPIRED);
1075+
break;
1076+
default:
10711077
{
1072-
case CMD_INSERT:
1073-
SetRelativeMatviewAuxStatus(rte->relid, MV_DATA_STATUS_EXPIRED_INSERT_ONLY);
1074-
break;
1075-
case CMD_UPDATE:
1076-
case CMD_DELETE:
1078+
/* If there were writable CTE, just mark it as expired. */
1079+
if (queryDesc->plannedstmt->hasModifyingCTE)
10771080
SetRelativeMatviewAuxStatus(rte->relid, MV_DATA_STATUS_EXPIRED);
1078-
break;
1079-
default:
1080-
break;
1081+
break;
10811082
}
10821083
}
10831084
}

src/test/regress/expected/matview_data.out

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,36 @@ select mvname, datastatus from gp_matview_aux where mvname = 'mv_t2_issue_582';
401401
mv_t2_issue_582 | i
402402
(1 row)
403403

404+
abort;
405+
--
406+
-- test issue https://github.com/cloudberrydb/cloudberrydb/issues/582
407+
-- test writable CTE
408+
--
409+
begin;
410+
create table t_cte_issue_582(i int, j int);
411+
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Cloudberry Database data distribution key for this table.
412+
HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.
413+
create materialized view mv_t_cte_issue_582 as select j from t_cte_issue_582 where i = 1;
414+
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'j' as the Cloudberry Database data distribution key for this table.
415+
HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.
416+
select mvname, datastatus from gp_matview_aux where mvname = 'mv_t_cte_issue_582';
417+
mvname | datastatus
418+
--------------------+------------
419+
mv_t_cte_issue_582 | u
420+
(1 row)
421+
422+
with mod1 as (insert into t_cte_issue_582 values(1, 1) returning *) select * from mod1;
423+
i | j
424+
---+---
425+
1 | 1
426+
(1 row)
427+
428+
select mvname, datastatus from gp_matview_aux where mvname = 'mv_t_cte_issue_582';
429+
mvname | datastatus
430+
--------------------+------------
431+
mv_t_cte_issue_582 | e
432+
(1 row)
433+
404434
abort;
405435
drop schema matview_data_schema cascade;
406436
NOTICE: drop cascades to 3 other objects

src/test/regress/sql/matview_data.sql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,18 @@ select count(*) from t2_issue_582;
146146
select mvname, datastatus from gp_matview_aux where mvname = 'mv_t2_issue_582';
147147
abort;
148148

149+
--
150+
-- test issue https://github.com/cloudberrydb/cloudberrydb/issues/582
151+
-- test writable CTE
152+
--
153+
begin;
154+
create table t_cte_issue_582(i int, j int);
155+
create materialized view mv_t_cte_issue_582 as select j from t_cte_issue_582 where i = 1;
156+
select mvname, datastatus from gp_matview_aux where mvname = 'mv_t_cte_issue_582';
157+
with mod1 as (insert into t_cte_issue_582 values(1, 1) returning *) select * from mod1;
158+
select mvname, datastatus from gp_matview_aux where mvname = 'mv_t_cte_issue_582';
159+
abort;
160+
149161
drop schema matview_data_schema cascade;
150162
reset enable_answer_query_using_materialized_views;
151163
reset optimizer;

0 commit comments

Comments
 (0)