blob: 65de9dd5c9ba8d059123d7ab0b23279f8e34e77b [file]
-- disable ORCA
SET optimizer TO off;
create schema matview_data_schema;
set search_path to matview_data_schema;
create table t1(a int, b int);
create table t2(a int, b int);
insert into t1 select i, i+1 from generate_series(1, 5) i;
insert into t1 select i, i+1 from generate_series(1, 3) i;
create materialized view mv0 as select * from t1;
create materialized view mv1 as select a, count(*), sum(b) from t1 group by a;
create materialized view mv2 as select * from t2;
-- all mv are up to date
select mvname, datastatus from gp_matview_aux where mvname in ('mv0','mv1', 'mv2');
-- truncate in self transaction
begin;
create table t3(a int, b int);
create materialized view mv3 as select * from t3;
select datastatus from gp_matview_aux where mvname = 'mv3';
truncate t3;
select datastatus from gp_matview_aux where mvname = 'mv3';
end;
-- trcuncate
refresh materialized view mv3;
select datastatus from gp_matview_aux where mvname = 'mv3';
truncate t3;
select datastatus from gp_matview_aux where mvname = 'mv3';
-- insert and refresh
select datastatus from gp_matview_aux where mvname = 'mv0';
select datastatus from gp_matview_aux where mvname = 'mv1';
insert into t1 values (1, 2);
select datastatus from gp_matview_aux where mvname = 'mv0';
select datastatus from gp_matview_aux where mvname = 'mv1';
-- insert but no rows changes
refresh materialized view mv0;
refresh materialized view mv1;
select datastatus from gp_matview_aux where mvname = 'mv0';
select datastatus from gp_matview_aux where mvname = 'mv1';
insert into t1 select * from t3;
select datastatus from gp_matview_aux where mvname = 'mv0';
select datastatus from gp_matview_aux where mvname = 'mv1';
-- update
refresh materialized view mv0;
refresh materialized view mv1;
select datastatus from gp_matview_aux where mvname = 'mv0';
select datastatus from gp_matview_aux where mvname = 'mv1';
update t1 set a = 10 where a = 1;
select datastatus from gp_matview_aux where mvname = 'mv0';
select datastatus from gp_matview_aux where mvname = 'mv1';
-- delete
refresh materialized view mv0;
refresh materialized view mv1;
select datastatus from gp_matview_aux where mvname = 'mv0';
select datastatus from gp_matview_aux where mvname = 'mv1';
delete from t1 where a = 10;
select datastatus from gp_matview_aux where mvname = 'mv0';
select datastatus from gp_matview_aux where mvname = 'mv1';
-- vacuum
refresh materialized view mv0;
refresh materialized view mv1;
select datastatus from gp_matview_aux where mvname = 'mv0';
select datastatus from gp_matview_aux where mvname = 'mv1';
vacuum t1;
select datastatus from gp_matview_aux where mvname = 'mv0';
select datastatus from gp_matview_aux where mvname = 'mv1';
vacuum full t1;
select datastatus from gp_matview_aux where mvname = 'mv0';
select datastatus from gp_matview_aux where mvname = 'mv1';
-- insert after vacuum full
insert into t1 values(1, 2);
select datastatus from gp_matview_aux where mvname = 'mv0';
select datastatus from gp_matview_aux where mvname = 'mv1';
-- vacuum full after insert
refresh materialized view mv0;
refresh materialized view mv1;
select datastatus from gp_matview_aux where mvname = 'mv0';
select datastatus from gp_matview_aux where mvname = 'mv1';
insert into t1 values(1, 2);
select datastatus from gp_matview_aux where mvname = 'mv0';
select datastatus from gp_matview_aux where mvname = 'mv1';
vacuum full t1;
select datastatus from gp_matview_aux where mvname = 'mv0';
select datastatus from gp_matview_aux where mvname = 'mv1';
-- Refresh With No Data
refresh materialized view mv2;
select datastatus from gp_matview_aux where mvname = 'mv2';
refresh materialized view mv2 with no data;
select datastatus from gp_matview_aux where mvname = 'mv2';
-- Copy
refresh materialized view mv2;
select datastatus from gp_matview_aux where mvname = 'mv2';
-- 0 rows
COPY t2 from stdin;
\.
select datastatus from gp_matview_aux where mvname = 'mv2';
COPY t2 from stdin;
1 1
\.
select datastatus from gp_matview_aux where mvname = 'mv2';
--
-- test issue https://github.com/apache/cloudberry/issues/582
-- test inherits
--
begin;
create table tp_issue_582(i int, j int);
create table tc_issue_582(i int) inherits (tp_issue_582);
insert into tp_issue_582 values(1, 1), (2, 2);
insert into tc_issue_582 values(1, 1);
create materialized view mv_tp_issue_582 as select * from tp_issue_582;
-- should be null.
select mvname, datastatus from gp_matview_aux where mvname = 'mv_tp_issue_582';
abort;
--
-- Test multi-table JOIN materialized views
--
create table jt1(id int, val int);
create table jt2(id int, val int);
create table jt3(id int, val int);
insert into jt1 select i, i*10 from generate_series(1,5) i;
insert into jt2 select i, i*100 from generate_series(1,5) i;
insert into jt3 select i, i*1000 from generate_series(1,5) i;
-- Two-table INNER JOIN: verify registration
create materialized view mv_join2 as
select jt1.id, jt1.val as v1, jt2.val as v2
from jt1 join jt2 on jt1.id = jt2.id;
select mvname, datastatus from gp_matview_aux where mvname = 'mv_join2';
select count(*) from gp_matview_tables mt
join pg_class c on mt.relid = c.oid
where mt.mvoid = 'mv_join2'::regclass;
-- INSERT on table A: status -> 'i'
insert into jt1 values(6, 60);
select mvname, datastatus from gp_matview_aux where mvname = 'mv_join2';
-- REFRESH: status -> 'u'
refresh materialized view mv_join2;
select mvname, datastatus from gp_matview_aux where mvname = 'mv_join2';
-- INSERT on table B: status -> 'i'
insert into jt2 values(7, 700);
select mvname, datastatus from gp_matview_aux where mvname = 'mv_join2';
-- UPDATE on table A: status -> 'e'
refresh materialized view mv_join2;
update jt1 set val = 99 where id = 1;
select mvname, datastatus from gp_matview_aux where mvname = 'mv_join2';
-- DELETE on table B: status -> 'e'
refresh materialized view mv_join2;
delete from jt2 where id = 7;
select mvname, datastatus from gp_matview_aux where mvname = 'mv_join2';
-- Implicit join (FROM t1, t2 WHERE ...): verify registration
refresh materialized view mv_join2;
create materialized view mv_implicit_join as
select jt1.id, jt1.val as v1, jt2.val as v2
from jt1, jt2 where jt1.id = jt2.id;
select mvname, datastatus from gp_matview_aux where mvname = 'mv_implicit_join';
select count(*) from gp_matview_tables mt
join pg_class c on mt.relid = c.oid
where mt.mvoid = 'mv_implicit_join'::regclass;
-- Three-table join: verify 3 entries in gp_matview_tables
create materialized view mv_join3 as
select jt1.id, jt1.val as v1, jt2.val as v2, jt3.val as v3
from jt1 join jt2 on jt1.id = jt2.id join jt3 on jt2.id = jt3.id;
select mvname, datastatus from gp_matview_aux where mvname = 'mv_join3';
select count(*) from gp_matview_tables mt
join pg_class c on mt.relid = c.oid
where mt.mvoid = 'mv_join3'::regclass;
-- DML on middle table expires mv_join3
insert into jt2 values(8, 800);
select mvname, datastatus from gp_matview_aux where mvname = 'mv_join3';
-- Self-join: verify only 1 entry in gp_matview_tables
create materialized view mv_selfjoin as
select a.id as aid, b.id as bid
from jt1 a join jt1 b on a.id = b.id;
select mvname, datastatus from gp_matview_aux where mvname = 'mv_selfjoin';
select count(*) from gp_matview_tables mt
join pg_class c on mt.relid = c.oid
where mt.mvoid = 'mv_selfjoin'::regclass;
-- LEFT/RIGHT/FULL OUTER JOIN: verify all register correctly
create materialized view mv_left_join as
select jt1.id, jt1.val as v1, jt2.val as v2
from jt1 left join jt2 on jt1.id = jt2.id;
select mvname, datastatus from gp_matview_aux where mvname = 'mv_left_join';
create materialized view mv_right_join as
select jt1.id, jt2.val as v2
from jt1 right join jt2 on jt1.id = jt2.id;
select mvname, datastatus from gp_matview_aux where mvname = 'mv_right_join';
create materialized view mv_full_join as
select jt1.id as id1, jt2.id as id2
from jt1 full join jt2 on jt1.id = jt2.id;
select mvname, datastatus from gp_matview_aux where mvname = 'mv_full_join';
-- Partitioned table in join: verify partition DML propagates
create table jt_par(a int, b int) partition by range(a)
(start(1) end(3) every(1));
insert into jt_par values(1, 10), (2, 20);
create materialized view mv_join_par as
select jt1.id, jt1.val as v1, jt_par.a, jt_par.b
from jt1 join jt_par on jt1.id = jt_par.a;
select mvname, datastatus from gp_matview_aux where mvname = 'mv_join_par';
insert into jt_par values(1, 11);
select mvname, datastatus from gp_matview_aux where mvname = 'mv_join_par';
refresh materialized view mv_join_par;
insert into jt1 values(9, 90);
select mvname, datastatus from gp_matview_aux where mvname = 'mv_join_par';
-- VACUUM FULL on one base table of a join MV: status -> 'r'
refresh materialized view mv_join2;
select mvname, datastatus from gp_matview_aux where mvname = 'mv_join2';
vacuum full jt1;
select mvname, datastatus from gp_matview_aux where mvname = 'mv_join2';
-- TRUNCATE on one base table of a join MV: status -> 'e'
refresh materialized view mv_join2;
truncate jt2;
select mvname, datastatus from gp_matview_aux where mvname = 'mv_join2';
-- CREATE WITH NO DATA: status -> 'e'
create materialized view mv_join_nodata as
select jt1.id, jt3.val from jt1 join jt3 on jt1.id = jt3.id
with no data;
select mvname, datastatus from gp_matview_aux where mvname = 'mv_join_nodata';
-- DROP CASCADE: matview and aux entries removed
drop materialized view mv_join_nodata;
select count(*) from gp_matview_aux where mvname = 'mv_join_nodata';
-- Mixed join types in one view (INNER + LEFT)
create materialized view mv_mixed_join as
select jt1.id, jt2.val as v2, jt3.val as v3
from jt1 join jt2 on jt1.id = jt2.id left join jt3 on jt2.id = jt3.id;
select mvname, datastatus from gp_matview_aux where mvname = 'mv_mixed_join';
select count(*) from gp_matview_tables mt
join pg_class c on mt.relid = c.oid
where mt.mvoid = 'mv_mixed_join'::regclass;
-- Join with GROUP BY and aggregates
create materialized view mv_join_agg as
select jt1.id, count(*) as cnt, sum(jt2.val) as total
from jt1 join jt2 on jt1.id = jt2.id group by jt1.id;
select mvname, datastatus from gp_matview_aux where mvname = 'mv_join_agg';
select count(*) from gp_matview_tables mt
join pg_class c on mt.relid = c.oid
where mt.mvoid = 'mv_join_agg'::regclass;
-- Multiple MVs sharing base tables: DML on one table affects all dependent MVs
refresh materialized view mv_join2;
refresh materialized view mv_join3;
refresh materialized view mv_mixed_join;
refresh materialized view mv_join_agg;
select mvname, datastatus from gp_matview_aux
where mvname in ('mv_join2', 'mv_join3', 'mv_mixed_join', 'mv_join_agg')
order by mvname;
insert into jt2 values(10, 1000);
-- all four share jt2 as a base table
select mvname, datastatus from gp_matview_aux
where mvname in ('mv_join2', 'mv_join3', 'mv_mixed_join', 'mv_join_agg')
order by mvname;
-- Transaction: multiple DML on different base tables
refresh materialized view mv_join3;
begin;
select mvname, datastatus from gp_matview_aux where mvname = 'mv_join3';
insert into jt1 values(20, 200);
-- after insert: 'i' (insert-only)
select mvname, datastatus from gp_matview_aux where mvname = 'mv_join3';
delete from jt2 where id = 10;
-- after delete: escalates to 'e' (expired)
select mvname, datastatus from gp_matview_aux where mvname = 'mv_join3';
end;
-- committed: status persists as 'e'
select mvname, datastatus from gp_matview_aux where mvname = 'mv_join3';
-- Transaction rollback: status should revert
refresh materialized view mv_join3;
select mvname, datastatus from gp_matview_aux where mvname = 'mv_join3';
begin;
update jt1 set val = 999 where id = 1;
select mvname, datastatus from gp_matview_aux where mvname = 'mv_join3';
abort;
-- after rollback: back to 'u'
select mvname, datastatus from gp_matview_aux where mvname = 'mv_join3';
-- Transaction: insert then insert on different tables stays 'i'
refresh materialized view mv_join2;
begin;
insert into jt1 values(30, 300);
select mvname, datastatus from gp_matview_aux where mvname = 'mv_join2';
insert into jt2 values(31, 3100);
-- still 'i' since both are inserts
select mvname, datastatus from gp_matview_aux where mvname = 'mv_join2';
abort;
-- Cross join (FROM t1, t2 with no WHERE): verify registration
create materialized view mv_cross_join as
select jt1.id as id1, jt2.id as id2 from jt1, jt2;
select mvname, datastatus from gp_matview_aux where mvname = 'mv_cross_join';
select count(*) from gp_matview_tables mt
join pg_class c on mt.relid = c.oid
where mt.mvoid = 'mv_cross_join'::regclass;
-- Drop base table CASCADE removes dependent join MVs and aux entries
create table jt_drop(id int, val int);
insert into jt_drop values(1, 10);
create materialized view mv_join_drop as
select jt1.id, jt_drop.val from jt1 join jt_drop on jt1.id = jt_drop.id;
select mvname, datastatus from gp_matview_aux where mvname = 'mv_join_drop';
drop table jt_drop cascade;
select count(*) from gp_matview_aux where mvname = 'mv_join_drop';
-- Clean up join test objects
drop materialized view mv_cross_join;
drop materialized view mv_join_agg;
drop materialized view mv_mixed_join;
drop materialized view mv_join_par;
drop table jt_par cascade;
drop materialized view mv_full_join;
drop materialized view mv_right_join;
drop materialized view mv_left_join;
drop materialized view mv_selfjoin;
drop materialized view mv_join3;
drop materialized view mv_implicit_join;
drop materialized view mv_join2;
drop table jt3;
drop table jt2;
drop table jt1;
--
-- Test AQUMV (Answer Query Using Materialized Views) with join queries.
-- Each matching test shows EXPLAIN + SELECT with GUC off (original plan),
-- then EXPLAIN + SELECT with GUC on (MV rewrite). Results must match.
--
create table aqj_t1(a int, b int) distributed by (a);
create table aqj_t2(a int, b int) distributed by (a);
create table aqj_t3(a int, b int) distributed by (a);
insert into aqj_t1 select i, i*10 from generate_series(1, 100) i;
insert into aqj_t2 select i, i*100 from generate_series(1, 100) i;
insert into aqj_t3 select i, i*1000 from generate_series(1, 100) i;
analyze aqj_t1;
analyze aqj_t2;
analyze aqj_t3;
-- 1. Two-table INNER JOIN exact match
create materialized view mv_aqj_join2 as
select aqj_t1.a, aqj_t2.b from aqj_t1 join aqj_t2 on aqj_t1.a = aqj_t2.a;
analyze mv_aqj_join2;
set enable_answer_query_using_materialized_views = off;
explain(costs off) select aqj_t1.a, aqj_t2.b from aqj_t1 join aqj_t2 on aqj_t1.a = aqj_t2.a;
select aqj_t1.a, aqj_t2.b from aqj_t1 join aqj_t2 on aqj_t1.a = aqj_t2.a order by 1 limit 5;
set enable_answer_query_using_materialized_views = on;
explain(costs off) select aqj_t1.a, aqj_t2.b from aqj_t1 join aqj_t2 on aqj_t1.a = aqj_t2.a;
select aqj_t1.a, aqj_t2.b from aqj_t1 join aqj_t2 on aqj_t1.a = aqj_t2.a order by 1 limit 5;
-- 2. Join with WHERE clause
create materialized view mv_aqj_where as
select aqj_t1.a, aqj_t2.b from aqj_t1 join aqj_t2 on aqj_t1.a = aqj_t2.a where aqj_t1.a > 5;
analyze mv_aqj_where;
set enable_answer_query_using_materialized_views = off;
explain(costs off) select aqj_t1.a, aqj_t2.b from aqj_t1 join aqj_t2 on aqj_t1.a = aqj_t2.a where aqj_t1.a > 5;
select aqj_t1.a, aqj_t2.b from aqj_t1 join aqj_t2 on aqj_t1.a = aqj_t2.a where aqj_t1.a > 5 order by 1 limit 5;
set enable_answer_query_using_materialized_views = on;
explain(costs off) select aqj_t1.a, aqj_t2.b from aqj_t1 join aqj_t2 on aqj_t1.a = aqj_t2.a where aqj_t1.a > 5;
select aqj_t1.a, aqj_t2.b from aqj_t1 join aqj_t2 on aqj_t1.a = aqj_t2.a where aqj_t1.a > 5 order by 1 limit 5;
-- 3. Join with GROUP BY + aggregate
create materialized view mv_aqj_agg as
select aqj_t1.a, count(*) as cnt from aqj_t1 join aqj_t2 on aqj_t1.a = aqj_t2.a group by aqj_t1.a;
analyze mv_aqj_agg;
set enable_answer_query_using_materialized_views = off;
explain(costs off) select aqj_t1.a, count(*) as cnt from aqj_t1 join aqj_t2 on aqj_t1.a = aqj_t2.a group by aqj_t1.a;
select aqj_t1.a, count(*) as cnt from aqj_t1 join aqj_t2 on aqj_t1.a = aqj_t2.a group by aqj_t1.a order by 1 limit 5;
set enable_answer_query_using_materialized_views = on;
explain(costs off) select aqj_t1.a, count(*) as cnt from aqj_t1 join aqj_t2 on aqj_t1.a = aqj_t2.a group by aqj_t1.a;
select aqj_t1.a, count(*) as cnt from aqj_t1 join aqj_t2 on aqj_t1.a = aqj_t2.a group by aqj_t1.a order by 1 limit 5;
-- 4. Non-match: different WHERE clause (should show Hash Join, not MV)
set enable_answer_query_using_materialized_views = on;
explain(costs off) select aqj_t1.a, aqj_t2.b from aqj_t1 join aqj_t2 on aqj_t1.a = aqj_t2.a where aqj_t1.a > 10;
-- 5. Non-match: different target list
explain(costs off) select aqj_t1.b, aqj_t2.a from aqj_t1 join aqj_t2 on aqj_t1.a = aqj_t2.a;
-- 6. Non-match: different join type (INNER vs LEFT)
explain(costs off) select aqj_t1.a, aqj_t2.b from aqj_t1 left join aqj_t2 on aqj_t1.a = aqj_t2.a;
-- 7. Three-table join
create materialized view mv_aqj_join3 as
select aqj_t1.a, aqj_t2.b, aqj_t3.b as c
from aqj_t1 join aqj_t2 on aqj_t1.a = aqj_t2.a join aqj_t3 on aqj_t2.a = aqj_t3.a;
analyze mv_aqj_join3;
set enable_answer_query_using_materialized_views = off;
explain(costs off) select aqj_t1.a, aqj_t2.b, aqj_t3.b as c
from aqj_t1 join aqj_t2 on aqj_t1.a = aqj_t2.a join aqj_t3 on aqj_t2.a = aqj_t3.a;
select aqj_t1.a, aqj_t2.b, aqj_t3.b as c
from aqj_t1 join aqj_t2 on aqj_t1.a = aqj_t2.a join aqj_t3 on aqj_t2.a = aqj_t3.a
order by 1 limit 5;
set enable_answer_query_using_materialized_views = on;
explain(costs off) select aqj_t1.a, aqj_t2.b, aqj_t3.b as c
from aqj_t1 join aqj_t2 on aqj_t1.a = aqj_t2.a join aqj_t3 on aqj_t2.a = aqj_t3.a;
select aqj_t1.a, aqj_t2.b, aqj_t3.b as c
from aqj_t1 join aqj_t2 on aqj_t1.a = aqj_t2.a join aqj_t3 on aqj_t2.a = aqj_t3.a
order by 1 limit 5;
-- 8. Implicit join (FROM t1, t2 WHERE ...)
create materialized view mv_aqj_implicit as
select aqj_t1.a, aqj_t2.b from aqj_t1, aqj_t2 where aqj_t1.a = aqj_t2.a;
analyze mv_aqj_implicit;
set enable_answer_query_using_materialized_views = off;
explain(costs off) select aqj_t1.a, aqj_t2.b from aqj_t1, aqj_t2 where aqj_t1.a = aqj_t2.a;
select aqj_t1.a, aqj_t2.b from aqj_t1, aqj_t2 where aqj_t1.a = aqj_t2.a order by 1 limit 5;
set enable_answer_query_using_materialized_views = on;
explain(costs off) select aqj_t1.a, aqj_t2.b from aqj_t1, aqj_t2 where aqj_t1.a = aqj_t2.a;
select aqj_t1.a, aqj_t2.b from aqj_t1, aqj_t2 where aqj_t1.a = aqj_t2.a order by 1 limit 5;
-- 9. MV not up-to-date: after INSERT on base table
insert into aqj_t1 values(999, 9990);
set enable_answer_query_using_materialized_views = on;
-- Should NOT use mv_aqj_join2 (status is 'i')
explain(costs off) select aqj_t1.a, aqj_t2.b from aqj_t1 join aqj_t2 on aqj_t1.a = aqj_t2.a;
-- 10. After REFRESH: should use MV again
refresh materialized view mv_aqj_join2;
analyze mv_aqj_join2;
explain(costs off) select aqj_t1.a, aqj_t2.b from aqj_t1 join aqj_t2 on aqj_t1.a = aqj_t2.a;
-- 11. GUC off: should NOT use MV
set enable_answer_query_using_materialized_views = off;
explain(costs off) select aqj_t1.a, aqj_t2.b from aqj_t1 join aqj_t2 on aqj_t1.a = aqj_t2.a;
--
-- More complex join AQUMV test cases with richer schemas
--
create table aqj_orders(
order_id int,
customer_id int,
amount numeric(10,2),
status text,
order_date date
) distributed by (order_id);
create table aqj_customers(
customer_id int,
name text,
region text,
credit_limit numeric(10,2)
) distributed by (customer_id);
create table aqj_products(
product_id int,
name text,
category text,
price numeric(10,2)
) distributed by (product_id);
create table aqj_order_items(
item_id int,
order_id int,
product_id int,
quantity int
) distributed by (item_id);
insert into aqj_customers select i, 'cust_' || i, case when i % 3 = 0 then 'east' when i % 3 = 1 then 'west' else 'north' end, (i * 100)::numeric(10,2) from generate_series(1, 50) i;
insert into aqj_orders select i, (i % 50) + 1, (i * 10.5)::numeric(10,2), case when i % 4 = 0 then 'shipped' when i % 4 = 1 then 'pending' when i % 4 = 2 then 'delivered' else 'cancelled' end, '2024-01-01'::date + (i % 365) from generate_series(1, 200) i;
insert into aqj_products select i, 'prod_' || i, case when i % 5 = 0 then 'electronics' when i % 5 = 1 then 'books' when i % 5 = 2 then 'clothing' when i % 5 = 3 then 'food' else 'toys' end, (i * 5.99)::numeric(10,2) from generate_series(1, 30) i;
insert into aqj_order_items select i, (i % 200) + 1, (i % 30) + 1, (i % 10) + 1 from generate_series(1, 500) i;
analyze aqj_customers;
analyze aqj_orders;
analyze aqj_products;
analyze aqj_order_items;
-- 12. Join with multiple columns + WHERE on text column
create materialized view mv_aqj_orders_cust as
select o.order_id, o.amount, c.name, c.region
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
where o.status = 'shipped';
analyze mv_aqj_orders_cust;
set enable_answer_query_using_materialized_views = off;
explain(costs off) select o.order_id, o.amount, c.name, c.region
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
where o.status = 'shipped';
select o.order_id, o.amount, c.name, c.region
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
where o.status = 'shipped'
order by o.order_id limit 5;
set enable_answer_query_using_materialized_views = on;
explain(costs off) select o.order_id, o.amount, c.name, c.region
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
where o.status = 'shipped';
select o.order_id, o.amount, c.name, c.region
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
where o.status = 'shipped'
order by o.order_id limit 5;
-- 13. Four-table join
create materialized view mv_aqj_order_details as
select o.order_id, c.name as customer_name, p.name as product_name, oi.quantity, p.price
from aqj_orders o
join aqj_customers c on o.customer_id = c.customer_id
join aqj_order_items oi on o.order_id = oi.order_id
join aqj_products p on oi.product_id = p.product_id;
analyze mv_aqj_order_details;
set enable_answer_query_using_materialized_views = off;
explain(costs off)
select o.order_id, c.name as customer_name, p.name as product_name, oi.quantity, p.price
from aqj_orders o
join aqj_customers c on o.customer_id = c.customer_id
join aqj_order_items oi on o.order_id = oi.order_id
join aqj_products p on oi.product_id = p.product_id;
select o.order_id, c.name as customer_name, p.name as product_name, oi.quantity, p.price
from aqj_orders o
join aqj_customers c on o.customer_id = c.customer_id
join aqj_order_items oi on o.order_id = oi.order_id
join aqj_products p on oi.product_id = p.product_id
order by o.order_id, p.name limit 5;
set enable_answer_query_using_materialized_views = on;
explain(costs off)
select o.order_id, c.name as customer_name, p.name as product_name, oi.quantity, p.price
from aqj_orders o
join aqj_customers c on o.customer_id = c.customer_id
join aqj_order_items oi on o.order_id = oi.order_id
join aqj_products p on oi.product_id = p.product_id;
select o.order_id, c.name as customer_name, p.name as product_name, oi.quantity, p.price
from aqj_orders o
join aqj_customers c on o.customer_id = c.customer_id
join aqj_order_items oi on o.order_id = oi.order_id
join aqj_products p on oi.product_id = p.product_id
order by o.order_id, p.name limit 5;
-- 14. GROUP BY on join with multiple aggregates: sum, count, avg
create materialized view mv_aqj_cust_summary as
select c.region, count(*) as order_count, sum(o.amount) as total_amount, avg(o.amount) as avg_amount
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
group by c.region;
analyze mv_aqj_cust_summary;
set enable_answer_query_using_materialized_views = off;
explain(costs off)
select c.region, count(*) as order_count, sum(o.amount) as total_amount, avg(o.amount) as avg_amount
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
group by c.region;
select c.region, count(*) as order_count, sum(o.amount) as total_amount, avg(o.amount) as avg_amount
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
group by c.region
order by c.region;
set enable_answer_query_using_materialized_views = on;
explain(costs off)
select c.region, count(*) as order_count, sum(o.amount) as total_amount, avg(o.amount) as avg_amount
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
group by c.region;
select c.region, count(*) as order_count, sum(o.amount) as total_amount, avg(o.amount) as avg_amount
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
group by c.region
order by c.region;
-- 15. Join with expression in target list (arithmetic + function)
create materialized view mv_aqj_expr as
select o.order_id, o.amount * 1.1 as amount_with_tax, c.name, upper(c.region) as region_upper
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id;
analyze mv_aqj_expr;
set enable_answer_query_using_materialized_views = off;
explain(costs off) select o.order_id, o.amount * 1.1 as amount_with_tax, c.name, upper(c.region) as region_upper
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id;
select o.order_id, o.amount * 1.1 as amount_with_tax, c.name, upper(c.region) as region_upper
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
order by o.order_id limit 5;
set enable_answer_query_using_materialized_views = on;
explain(costs off) select o.order_id, o.amount * 1.1 as amount_with_tax, c.name, upper(c.region) as region_upper
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id;
select o.order_id, o.amount * 1.1 as amount_with_tax, c.name, upper(c.region) as region_upper
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
order by o.order_id limit 5;
-- 16. Non-match: same tables + expressions, but extra WHERE (should NOT match mv_aqj_expr)
set enable_answer_query_using_materialized_views = on;
explain(costs off) select o.order_id, o.amount * 1.1 as amount_with_tax, c.name, upper(c.region) as region_upper
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
where c.region = 'east';
-- 17. Non-match: same tables but different aggregate target list
explain(costs off)
select c.region, sum(o.amount) as total_amount
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
group by c.region;
-- 18. Non-match: different join order (o JOIN c vs c JOIN o)
explain(costs off) select o.order_id, o.amount, c.name, c.region
from aqj_customers c join aqj_orders o on o.customer_id = c.customer_id
where o.status = 'shipped';
-- 19. Join with compound WHERE (multiple AND conditions)
create materialized view mv_aqj_compound_where as
select o.order_id, o.amount, c.name
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
where o.status = 'pending' and c.region = 'west' and o.amount > 50;
analyze mv_aqj_compound_where;
set enable_answer_query_using_materialized_views = off;
explain(costs off) select o.order_id, o.amount, c.name
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
where o.status = 'pending' and c.region = 'west' and o.amount > 50;
select o.order_id, o.amount, c.name
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
where o.status = 'pending' and c.region = 'west' and o.amount > 50
order by o.order_id limit 5;
set enable_answer_query_using_materialized_views = on;
explain(costs off) select o.order_id, o.amount, c.name
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
where o.status = 'pending' and c.region = 'west' and o.amount > 50;
select o.order_id, o.amount, c.name
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
where o.status = 'pending' and c.region = 'west' and o.amount > 50
order by o.order_id limit 5;
-- 20. Self-join
create materialized view mv_aqj_selfjoin as
select o1.order_id as id1, o2.order_id as id2, o1.amount as amt1, o2.amount as amt2
from aqj_orders o1 join aqj_orders o2 on o1.customer_id = o2.customer_id
where o1.order_id < o2.order_id;
analyze mv_aqj_selfjoin;
set enable_answer_query_using_materialized_views = off;
explain(costs off)
select o1.order_id as id1, o2.order_id as id2, o1.amount as amt1, o2.amount as amt2
from aqj_orders o1 join aqj_orders o2 on o1.customer_id = o2.customer_id
where o1.order_id < o2.order_id;
select o1.order_id as id1, o2.order_id as id2, o1.amount as amt1, o2.amount as amt2
from aqj_orders o1 join aqj_orders o2 on o1.customer_id = o2.customer_id
where o1.order_id < o2.order_id
order by o1.order_id, o2.order_id limit 5;
set enable_answer_query_using_materialized_views = on;
explain(costs off)
select o1.order_id as id1, o2.order_id as id2, o1.amount as amt1, o2.amount as amt2
from aqj_orders o1 join aqj_orders o2 on o1.customer_id = o2.customer_id
where o1.order_id < o2.order_id;
select o1.order_id as id1, o2.order_id as id2, o1.amount as amt1, o2.amount as amt2
from aqj_orders o1 join aqj_orders o2 on o1.customer_id = o2.customer_id
where o1.order_id < o2.order_id
order by o1.order_id, o2.order_id limit 5;
-- 21. GROUP BY with multi-column key on join
create materialized view mv_aqj_grp_multi as
select c.region, o.status, count(*) as cnt, sum(o.amount) as total
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
group by c.region, o.status;
analyze mv_aqj_grp_multi;
set enable_answer_query_using_materialized_views = off;
explain(costs off)
select c.region, o.status, count(*) as cnt, sum(o.amount) as total
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
group by c.region, o.status;
select c.region, o.status, count(*) as cnt, sum(o.amount) as total
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
group by c.region, o.status
order by c.region, o.status limit 6;
set enable_answer_query_using_materialized_views = on;
explain(costs off)
select c.region, o.status, count(*) as cnt, sum(o.amount) as total
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
group by c.region, o.status;
select c.region, o.status, count(*) as cnt, sum(o.amount) as total
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
group by c.region, o.status
order by c.region, o.status limit 6;
-- 22. Four-table join with WHERE and aggregate
create materialized view mv_aqj_3way_agg as
select c.region, p.category, sum(oi.quantity) as total_qty, count(*) as line_count
from aqj_orders o
join aqj_customers c on o.customer_id = c.customer_id
join aqj_order_items oi on o.order_id = oi.order_id
join aqj_products p on oi.product_id = p.product_id
where o.status = 'delivered'
group by c.region, p.category;
analyze mv_aqj_3way_agg;
set enable_answer_query_using_materialized_views = off;
explain(costs off)
select c.region, p.category, sum(oi.quantity) as total_qty, count(*) as line_count
from aqj_orders o
join aqj_customers c on o.customer_id = c.customer_id
join aqj_order_items oi on o.order_id = oi.order_id
join aqj_products p on oi.product_id = p.product_id
where o.status = 'delivered'
group by c.region, p.category;
select c.region, p.category, sum(oi.quantity) as total_qty, count(*) as line_count
from aqj_orders o
join aqj_customers c on o.customer_id = c.customer_id
join aqj_order_items oi on o.order_id = oi.order_id
join aqj_products p on oi.product_id = p.product_id
where o.status = 'delivered'
group by c.region, p.category
order by c.region, p.category limit 6;
set enable_answer_query_using_materialized_views = on;
explain(costs off)
select c.region, p.category, sum(oi.quantity) as total_qty, count(*) as line_count
from aqj_orders o
join aqj_customers c on o.customer_id = c.customer_id
join aqj_order_items oi on o.order_id = oi.order_id
join aqj_products p on oi.product_id = p.product_id
where o.status = 'delivered'
group by c.region, p.category;
select c.region, p.category, sum(oi.quantity) as total_qty, count(*) as line_count
from aqj_orders o
join aqj_customers c on o.customer_id = c.customer_id
join aqj_order_items oi on o.order_id = oi.order_id
join aqj_products p on oi.product_id = p.product_id
where o.status = 'delivered'
group by c.region, p.category
order by c.region, p.category limit 6;
-- 23. Implicit four-table join (comma style)
create materialized view mv_aqj_implicit3 as
select o.order_id, c.name, p.name as product_name
from aqj_orders o, aqj_customers c, aqj_order_items oi, aqj_products p
where o.customer_id = c.customer_id and o.order_id = oi.order_id and oi.product_id = p.product_id
and o.status = 'pending';
analyze mv_aqj_implicit3;
set enable_answer_query_using_materialized_views = off;
explain(costs off)
select o.order_id, c.name, p.name as product_name
from aqj_orders o, aqj_customers c, aqj_order_items oi, aqj_products p
where o.customer_id = c.customer_id and o.order_id = oi.order_id and oi.product_id = p.product_id
and o.status = 'pending';
select o.order_id, c.name, p.name as product_name
from aqj_orders o, aqj_customers c, aqj_order_items oi, aqj_products p
where o.customer_id = c.customer_id and o.order_id = oi.order_id and oi.product_id = p.product_id
and o.status = 'pending'
order by o.order_id, p.name limit 5;
set enable_answer_query_using_materialized_views = on;
explain(costs off)
select o.order_id, c.name, p.name as product_name
from aqj_orders o, aqj_customers c, aqj_order_items oi, aqj_products p
where o.customer_id = c.customer_id and o.order_id = oi.order_id and oi.product_id = p.product_id
and o.status = 'pending';
select o.order_id, c.name, p.name as product_name
from aqj_orders o, aqj_customers c, aqj_order_items oi, aqj_products p
where o.customer_id = c.customer_id and o.order_id = oi.order_id and oi.product_id = p.product_id
and o.status = 'pending'
order by o.order_id, p.name limit 5;
-- 24. Result correctness across DML + REFRESH cycle
insert into aqj_orders values(201, 1, 9999.99, 'shipped', '2025-12-31');
set enable_answer_query_using_materialized_views = on;
-- Stale: should NOT use MV
explain(costs off) select o.order_id, o.amount, c.name, c.region
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
where o.status = 'shipped';
-- Refresh and verify MV is used again
refresh materialized view mv_aqj_orders_cust;
analyze mv_aqj_orders_cust;
explain(costs off) select o.order_id, o.amount, c.name, c.region
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
where o.status = 'shipped';
-- The new row should appear in results via MV scan
select o.order_id, o.amount, c.name, c.region
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
where o.status = 'shipped' and o.order_id = 201;
-- 25. Post-DML comprehensive: refresh all, then verify GUC off vs on results
refresh materialized view mv_aqj_order_details;
refresh materialized view mv_aqj_expr;
refresh materialized view mv_aqj_selfjoin;
refresh materialized view mv_aqj_grp_multi;
refresh materialized view mv_aqj_3way_agg;
refresh materialized view mv_aqj_implicit3;
analyze mv_aqj_order_details;
analyze mv_aqj_expr;
analyze mv_aqj_selfjoin;
analyze mv_aqj_grp_multi;
analyze mv_aqj_3way_agg;
analyze mv_aqj_implicit3;
-- Verify four-table join results after DML+refresh
set enable_answer_query_using_materialized_views = off;
select o.order_id, c.name as customer_name, p.name as product_name, oi.quantity, p.price
from aqj_orders o
join aqj_customers c on o.customer_id = c.customer_id
join aqj_order_items oi on o.order_id = oi.order_id
join aqj_products p on oi.product_id = p.product_id
order by o.order_id, p.name limit 5;
set enable_answer_query_using_materialized_views = on;
select o.order_id, c.name as customer_name, p.name as product_name, oi.quantity, p.price
from aqj_orders o
join aqj_customers c on o.customer_id = c.customer_id
join aqj_order_items oi on o.order_id = oi.order_id
join aqj_products p on oi.product_id = p.product_id
order by o.order_id, p.name limit 5;
-- Verify expression MV results after DML+refresh
set enable_answer_query_using_materialized_views = off;
select o.order_id, o.amount * 1.1 as amount_with_tax, c.name, upper(c.region) as region_upper
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
order by o.order_id limit 5;
set enable_answer_query_using_materialized_views = on;
select o.order_id, o.amount * 1.1 as amount_with_tax, c.name, upper(c.region) as region_upper
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
order by o.order_id limit 5;
-- Verify multi-key GROUP BY results after DML+refresh
set enable_answer_query_using_materialized_views = off;
select c.region, o.status, count(*) as cnt, sum(o.amount) as total
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
group by c.region, o.status
order by c.region, o.status limit 6;
set enable_answer_query_using_materialized_views = on;
select c.region, o.status, count(*) as cnt, sum(o.amount) as total
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
group by c.region, o.status
order by c.region, o.status limit 6;
-- 26. Non-match: LIMIT vs FETCH FIRST WITH TIES (limitOption differs)
create materialized view mv_aqj_limit_test as
select o.order_id, o.amount
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
where o.status = 'shipped'
order by o.order_id limit 5;
analyze mv_aqj_limit_test;
set enable_answer_query_using_materialized_views = on;
-- Same tables/WHERE/ORDER BY but FETCH FIRST WITH TIES: should NOT match
explain(costs off)
select o.order_id, o.amount
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
where o.status = 'shipped'
order by o.order_id fetch first 5 rows with ties;
-- Identical LIMIT query: should match
explain(costs off)
select o.order_id, o.amount
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
where o.status = 'shipped'
order by o.order_id limit 5;
-- 27. Match: FETCH FIRST WITH TIES exact match
create materialized view mv_aqj_with_ties as
select o.order_id, o.amount
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
where o.status = 'pending'
order by o.order_id fetch first 5 rows with ties;
analyze mv_aqj_with_ties;
set enable_answer_query_using_materialized_views = off;
explain(costs off)
select o.order_id, o.amount
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
where o.status = 'pending'
order by o.order_id fetch first 5 rows with ties;
select o.order_id, o.amount
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
where o.status = 'pending'
order by o.order_id fetch first 5 rows with ties;
set enable_answer_query_using_materialized_views = on;
explain(costs off)
select o.order_id, o.amount
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
where o.status = 'pending'
order by o.order_id fetch first 5 rows with ties;
select o.order_id, o.amount
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
where o.status = 'pending'
order by o.order_id fetch first 5 rows with ties;
-- 28. Non-match: GROUP BY vs GROUP BY DISTINCT (groupDistinct differs)
-- MV mv_aqj_grp_multi uses GROUP BY (groupDistinct=false, registered in catalog)
-- Query uses GROUP BY DISTINCT — should NOT match
set enable_answer_query_using_materialized_views = on;
explain(costs off)
select c.region, o.status, count(*) as cnt, sum(o.amount) as total
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
group by distinct c.region, o.status;
-- Clean up AQUMV join test objects
drop materialized view mv_aqj_with_ties;
drop materialized view mv_aqj_limit_test;
drop materialized view mv_aqj_implicit3;
drop materialized view mv_aqj_3way_agg;
drop materialized view mv_aqj_grp_multi;
drop materialized view mv_aqj_selfjoin;
drop materialized view mv_aqj_compound_where;
drop materialized view mv_aqj_expr;
drop materialized view mv_aqj_cust_summary;
drop materialized view mv_aqj_order_details;
drop materialized view mv_aqj_orders_cust;
drop materialized view mv_aqj_implicit;
drop materialized view mv_aqj_join3;
drop materialized view mv_aqj_agg;
drop materialized view mv_aqj_where;
drop materialized view mv_aqj_join2;
drop table aqj_order_items;
drop table aqj_products;
drop table aqj_customers;
drop table aqj_orders;
drop table aqj_t3;
drop table aqj_t2;
drop table aqj_t1;
-- test drop table
select mvname, datastatus from gp_matview_aux where mvname in ('mv0','mv1', 'mv2', 'mv3');
drop materialized view mv2;
drop table t1 cascade;
select mvname, datastatus from gp_matview_aux where mvname in ('mv0','mv1', 'mv2', 'mv3');
--
-- test issue https://github.com/apache/cloudberry/issues/582
-- test rules
begin;
create table t1_issue_582(i int, j int);
create table t2_issue_582(i int, j int);
create table t3_issue_582(i int, j int);
create materialized view mv_t2_issue_582 as select j from t2_issue_582 where i = 1;
create rule r1 as on insert TO t1_issue_582 do also insert into t2_issue_582 values(1,1);
select count(*) from t1_issue_582;
select count(*) from t2_issue_582;
select mvname, datastatus from gp_matview_aux where mvname = 'mv_t2_issue_582';
insert into t1_issue_582 values(1,1);
select count(*) from t1_issue_582;
select count(*) from t2_issue_582;
select mvname, datastatus from gp_matview_aux where mvname = 'mv_t2_issue_582';
abort;
--
-- test issue https://github.com/apache/cloudberry/issues/582
-- test writable CTE
--
begin;
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;
select mvname, datastatus from gp_matview_aux where mvname = 'mv_t_cte_issue_582';
with mod1 as (insert into t_cte_issue_582 values(1, 1) returning *) select * from mod1;
select mvname, datastatus from gp_matview_aux where mvname = 'mv_t_cte_issue_582';
abort;
-- test partitioned tables
create table par(a int, b int, c int) partition by range(b)
subpartition by range(c) subpartition template (start (1) end (3) every (1))
(start(1) end(3) every(1));
insert into par values(1, 1, 1), (1, 1, 2), (2, 2, 1), (2, 2, 2);
create materialized view mv_par as select * from par;
create materialized view mv_par1 as select * from par_1_prt_1;
create materialized view mv_par1_1 as select * from par_1_prt_1_2_prt_1;
create materialized view mv_par1_2 as select * from par_1_prt_1_2_prt_2;
create materialized view mv_par2 as select * from par_1_prt_2;
create materialized view mv_par2_1 as select * from par_1_prt_2_2_prt_1;
select mvname, datastatus from gp_matview_aux where mvname like 'mv_par%';
insert into par_1_prt_1 values (1, 1, 1);
-- mv_par1* shoud be updated
select mvname, datastatus from gp_matview_aux where mvname like 'mv_par%';
insert into par values (1, 2, 2);
-- mv_par* should be updated
select mvname, datastatus from gp_matview_aux where mvname like 'mv_par%';
refresh materialized view mv_par;
refresh materialized view mv_par1;
refresh materialized view mv_par1_1;
refresh materialized view mv_par1_2;
refresh materialized view mv_par2;
refresh materialized view mv_par2_1;
begin;
insert into par_1_prt_2_2_prt_1 values (1, 2, 1);
-- mv_par1* should not be updated
select mvname, datastatus from gp_matview_aux where mvname like 'mv_par%';
abort;
begin;
truncate par_1_prt_2;
-- mv_par1* should not be updated
select mvname, datastatus from gp_matview_aux where mvname like 'mv_par%';
abort;
truncate par_1_prt_2;
-- mv_par1* should not be updated
select mvname, datastatus from gp_matview_aux where mvname like 'mv_par%';
refresh materialized view mv_par;
refresh materialized view mv_par1;
refresh materialized view mv_par1_1;
refresh materialized view mv_par1_2;
refresh materialized view mv_par2;
refresh materialized view mv_par2_1;
vacuum full par_1_prt_1_2_prt_1;
select mvname, datastatus from gp_matview_aux where mvname like 'mv_par%';
refresh materialized view mv_par;
refresh materialized view mv_par1;
refresh materialized view mv_par1_1;
refresh materialized view mv_par1_2;
refresh materialized view mv_par2;
refresh materialized view mv_par2_1;
vacuum full par;
-- all should be updated.
select mvname, datastatus from gp_matview_aux where mvname like 'mv_par%';
refresh materialized view mv_par;
refresh materialized view mv_par1;
refresh materialized view mv_par1_1;
refresh materialized view mv_par1_2;
refresh materialized view mv_par2;
refresh materialized view mv_par2_1;
begin;
create table par_1_prt_1_2_prt_3 partition of par_1_prt_1 for values from (3) to (4);
-- update status when partition of
select mvname, datastatus from gp_matview_aux where mvname like 'mv_par%';
abort;
begin;
drop table par_1_prt_1 cascade;
-- update status when drop table
select mvname, datastatus from gp_matview_aux where mvname like 'mv_par%';
abort;
begin;
alter table par_1_prt_1 detach partition par_1_prt_1_2_prt_1;
-- update status when detach
select mvname, datastatus from gp_matview_aux where mvname like 'mv_par%';
abort;
begin;
create table new_par(a int, b int, c int);
-- update status when attach
alter table par_1_prt_1 attach partition new_par for values from (4) to (5);
select mvname, datastatus from gp_matview_aux where mvname like 'mv_par%';
abort;
--
-- Maintain materialized views on partitioned tables from bottom to up.
--
insert into par values(1, 1, 1), (1, 1, 2), (2, 2, 1), (2, 2, 2);
refresh materialized view mv_par;
refresh materialized view mv_par1;
refresh materialized view mv_par1_1;
refresh materialized view mv_par1_2;
refresh materialized view mv_par2;
refresh materialized view mv_par2_1;
begin;
select mvname, datastatus from gp_matview_aux where mvname like 'mv_par%';
insert into par values(1, 1, 1), (1, 1, 2);
select mvname, datastatus from gp_matview_aux where mvname like 'mv_par%';
abort;
begin;
select mvname, datastatus from gp_matview_aux where mvname like 'mv_par%';
insert into par_1_prt_2_2_prt_1 values(2, 2, 1);
select mvname, datastatus from gp_matview_aux where mvname like 'mv_par%';
abort;
begin;
select mvname, datastatus from gp_matview_aux where mvname like 'mv_par%';
delete from par where b = 2 and c = 1;
select mvname, datastatus from gp_matview_aux where mvname like 'mv_par%';
abort;
begin;
select mvname, datastatus from gp_matview_aux where mvname like 'mv_par%';
delete from par_1_prt_1_2_prt_2;
select mvname, datastatus from gp_matview_aux where mvname like 'mv_par%';
abort;
-- Across partition update.
begin;
select mvname, datastatus from gp_matview_aux where mvname like 'mv_par%';
update par set c = 2 where b = 1 and c = 1;
select mvname, datastatus from gp_matview_aux where mvname like 'mv_par%';
abort;
-- Split Update with acrosss partition update.
begin;
select mvname, datastatus from gp_matview_aux where mvname like 'mv_par%';
update par set c = 2, a = 2 where b = 1 and c = 1;
select mvname, datastatus from gp_matview_aux where mvname like 'mv_par%';
abort;
-- Test report warning if extend protocol data is not consumed.
--start_ignore
drop extension gp_inject_fault;
create extension gp_inject_fault;
--end_ignore
select gp_inject_fault_infinite('consume_extend_protocol_data', 'skip', dbid)
from gp_segment_configuration where role = 'p' and content = -1;
begin;
update par set c = 2 where b = 1 and c = 1;
end;
begin;
insert into par values(1, 1, 1), (1, 1, 2);
end;
begin;
update par set c = 2, a = 2 where b = 1 and c = 1;
end;
begin;
insert into par values(1, 1, 1), (1, 1, 2), (2, 2, 1), (2, 2, 2);
delete from par_1_prt_1_2_prt_2;
end;
begin;
insert into par values(1, 1, 1), (1, 1, 2), (2, 2, 1), (2, 2, 2);
update par set c = 2, a = 2 where b = 1 and c = 1;
end;
select gp_inject_fault('consume_extend_protocol_data', 'reset', dbid)
from gp_segment_configuration where role = 'p' and content = -1;
--
-- End of Maintain materialized views on partitioned tables from bottom to up.
--
-- Test Rename matview.
begin;
create materialized view mv_name1 as
select * from par with no data;
select count(*) from gp_matview_aux where mvname = 'mv_name1';
alter materialized view mv_name1 rename to mv_name2;
select count(*) from gp_matview_aux where mvname = 'mv_name1';
select count(*) from gp_matview_aux where mvname = 'mv_name2';
abort;
-- start_ignore
CREATE EXTENSION IF NOT EXISTS gp_inject_fault;
-- end_ignore
create table par_normal_oid(a int, b int) partition by range(a) using ao_row distributed randomly;
select gp_inject_fault('bump_oid', 'skip', dbid) from gp_segment_configuration where role = 'p' and content = -1;
create table sub_par1_large_oid partition of par_normal_oid for values from (1) to (2) using ao_row;
select 'sub_par1_large_oid'::regclass::oid > x'7FFFFFFF'::bigint;
select gp_inject_fault('bump_oid', 'reset', dbid) from gp_segment_configuration where role = 'p' and content = -1;
create materialized view mv_par_normal_oid as
select count(*) from par_normal_oid;
select mvname, datastatus from gp_matview_aux where mvname = 'mv_par_normal_oid';
insert into par_normal_oid values(1, 2);
select mvname, datastatus from gp_matview_aux where mvname = 'mv_par_normal_oid';
--start_ignore
drop schema matview_data_schema cascade;
--end_ignore
reset enable_answer_query_using_materialized_views;
reset optimizer;