diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index 24b7fc1d33b..2c3246a8069 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -165,6 +165,21 @@ CREATE VIEW pg_matviews AS LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace) WHERE C.relkind = 'm'; +CREATE VIEW gp_matviews AS + SELECT + A.mvoid, + N.nspname AS mvschema, + C.relname AS mvname, + A.has_foreign, + A.datastatus + FROM gp_matview_aux A + JOIN pg_class C ON (C.oid = A.mvoid) + LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace); + +COMMENT ON VIEW gp_matviews IS 'Schema-qualified view of gp_matview_aux, resolving mvname live from pg_class/pg_namespace instead of a stored copy. Prefer this over gp_matview_aux.mvname, which is not schema-qualified (see https://github.com/apache/cloudberry/issues/726).'; + +COMMENT ON COLUMN gp_matview_aux.mvname IS 'Deprecated: bare, non-schema-qualified materialized view name, retained for backward compatibility only. Two materialized views with the same name in different schemas are indistinguishable via this column. Use gp_matviews.mvname (with gp_matviews.mvschema) instead. See https://github.com/apache/cloudberry/issues/726.'; + CREATE VIEW pg_dynamic_tables AS SELECT N.nspname AS schemaname, diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 851e58debc3..483a3a02f18 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -60,6 +60,6 @@ */ /* 3yyymmddN */ -#define CATALOG_VERSION_NO 302606111 +#define CATALOG_VERSION_NO 302609031 #endif diff --git a/src/test/regress/expected/matview_data.out b/src/test/regress/expected/matview_data.out index 9a9074cd2d5..8cafa4192ec 100644 --- a/src/test/regress/expected/matview_data.out +++ b/src/test/regress/expected/matview_data.out @@ -2826,6 +2826,72 @@ select mvname, datastatus from gp_matview_aux where mvname = 'mv_par_normal_oid' mv_par_normal_oid | i (1 row) +-- +-- Test https://github.com/apache/cloudberry/issues/726: gp_matview_aux.mvname +-- is not schema-qualified, so two materialized views with the same bare name +-- in different schemas are indistinguishable through it. gp_matviews (added +-- above) resolves the name live from pg_class/pg_namespace instead, so it +-- distinguishes them correctly; mvname itself is unchanged (kept, deprecated, +-- for backward compatibility -- see the COMMENT ON in system_views.sql). +-- +create schema mv_schema_test_s1; +create schema mv_schema_test_s2; +create table mv_schema_test_s1.t0(a int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +create table mv_schema_test_s2.t0(a int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into mv_schema_test_s1.t0 values (1), (2); +insert into mv_schema_test_s2.t0 values (10), (20), (30); +create materialized view mv_schema_test_s1.mv0 as select * from mv_schema_test_s1.t0; +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +create materialized view mv_schema_test_s2.mv0 as select * from mv_schema_test_s2.t0; +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +-- gp_matview_aux.mvname alone cannot tell these two mv0's apart (both rows +-- show mvname = 'mv0' with no schema information) -- this is the deprecated, +-- pre-existing behavior, kept for backward compatibility, not the fix. +select mvname, datastatus from gp_matview_aux where mvname = 'mv0' order by mvoid; + mvname | datastatus +--------+------------ + mv0 | u + mv0 | u +(2 rows) + +-- gp_matviews distinguishes them via mvschema. +select mvschema, mvname, has_foreign, datastatus from gp_matviews + where mvschema in ('mv_schema_test_s1', 'mv_schema_test_s2') and mvname = 'mv0' + order by mvschema; + mvschema | mvname | has_foreign | datastatus +-------------------+--------+-------------+------------ + mv_schema_test_s1 | mv0 | f | u + mv_schema_test_s2 | mv0 | f | u +(2 rows) + +-- rename in one schema; the other schema's mv0 must be unaffected and +-- gp_matviews must reflect the new name immediately (it's resolved live, +-- not synced). +alter materialized view mv_schema_test_s1.mv0 rename to mv0_renamed; +select mvschema, mvname, has_foreign, datastatus from gp_matviews + where mvschema in ('mv_schema_test_s1', 'mv_schema_test_s2') + and mvname in ('mv0', 'mv0_renamed') + order by mvschema; + mvschema | mvname | has_foreign | datastatus +-------------------+-------------+-------------+------------ + mv_schema_test_s1 | mv0_renamed | f | u + mv_schema_test_s2 | mv0 | f | u +(2 rows) + +drop schema mv_schema_test_s1 cascade; +NOTICE: drop cascades to 2 other objects +DETAIL: drop cascades to table mv_schema_test_s1.t0 +drop cascades to materialized view mv_schema_test_s1.mv0_renamed +drop schema mv_schema_test_s2 cascade; +NOTICE: drop cascades to 2 other objects +DETAIL: drop cascades to table mv_schema_test_s2.t0 +drop cascades to materialized view mv_schema_test_s2.mv0 --start_ignore drop schema matview_data_schema cascade; NOTICE: drop cascades to 13 other objects diff --git a/src/test/regress/sql/matview_data.sql b/src/test/regress/sql/matview_data.sql index 65de9dd5c9b..0356d042116 100644 --- a/src/test/regress/sql/matview_data.sql +++ b/src/test/regress/sql/matview_data.sql @@ -1177,6 +1177,41 @@ 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'; +-- +-- Test https://github.com/apache/cloudberry/issues/726: gp_matview_aux.mvname +-- is not schema-qualified, so two materialized views with the same bare name +-- in different schemas are indistinguishable through it. gp_matviews (added +-- above) resolves the name live from pg_class/pg_namespace instead, so it +-- distinguishes them correctly; mvname itself is unchanged (kept, deprecated, +-- for backward compatibility -- see the COMMENT ON in system_views.sql). +-- +create schema mv_schema_test_s1; +create schema mv_schema_test_s2; +create table mv_schema_test_s1.t0(a int); +create table mv_schema_test_s2.t0(a int); +insert into mv_schema_test_s1.t0 values (1), (2); +insert into mv_schema_test_s2.t0 values (10), (20), (30); +create materialized view mv_schema_test_s1.mv0 as select * from mv_schema_test_s1.t0; +create materialized view mv_schema_test_s2.mv0 as select * from mv_schema_test_s2.t0; +-- gp_matview_aux.mvname alone cannot tell these two mv0's apart (both rows +-- show mvname = 'mv0' with no schema information) -- this is the deprecated, +-- pre-existing behavior, kept for backward compatibility, not the fix. +select mvname, datastatus from gp_matview_aux where mvname = 'mv0' order by mvoid; +-- gp_matviews distinguishes them via mvschema. +select mvschema, mvname, has_foreign, datastatus from gp_matviews + where mvschema in ('mv_schema_test_s1', 'mv_schema_test_s2') and mvname = 'mv0' + order by mvschema; +-- rename in one schema; the other schema's mv0 must be unaffected and +-- gp_matviews must reflect the new name immediately (it's resolved live, +-- not synced). +alter materialized view mv_schema_test_s1.mv0 rename to mv0_renamed; +select mvschema, mvname, has_foreign, datastatus from gp_matviews + where mvschema in ('mv_schema_test_s1', 'mv_schema_test_s2') + and mvname in ('mv0', 'mv0_renamed') + order by mvschema; +drop schema mv_schema_test_s1 cascade; +drop schema mv_schema_test_s2 cascade; + --start_ignore drop schema matview_data_schema cascade; --end_ignore