diff --git a/src/backend/distributed/commands/alter_table.c b/src/backend/distributed/commands/alter_table.c index 52dc23a51..f1c05734c 100644 --- a/src/backend/distributed/commands/alter_table.c +++ b/src/backend/distributed/commands/alter_table.c @@ -1077,8 +1077,11 @@ GetViewCreationCommandsOfTable(Oid relationId) char *viewName = get_rel_name(viewOid); char *schemaName = get_namespace_name(get_rel_namespace(viewOid)); char *qualifiedViewName = quote_qualified_identifier(schemaName, viewName); + bool isMatView = get_rel_relkind(viewOid) == RELKIND_MATVIEW; + appendStringInfo(query, - "CREATE VIEW %s AS %s", + "CREATE %s VIEW %s AS %s", + isMatView ? "MATERIALIZED" : "", qualifiedViewName, viewDefinition); commands = lappend(commands, makeTableDDLCommandString(query->data)); diff --git a/src/backend/distributed/metadata/dependency.c b/src/backend/distributed/metadata/dependency.c index b92f316dc..b3fbd2364 100644 --- a/src/backend/distributed/metadata/dependency.c +++ b/src/backend/distributed/metadata/dependency.c @@ -1207,12 +1207,13 @@ GetDependingView(Form_pg_depend pg_depend) Form_pg_rewrite pg_rewrite = (Form_pg_rewrite) GETSTRUCT(rewriteTup); bool isView = get_rel_relkind(pg_rewrite->ev_class) == RELKIND_VIEW; + bool isMatView = get_rel_relkind(pg_rewrite->ev_class) == RELKIND_MATVIEW; bool isDifferentThanRef = pg_rewrite->ev_class != pg_depend->refobjid; systable_endscan(rscan); relation_close(rewriteRel, AccessShareLock); - if (isView && isDifferentThanRef) + if ((isView || isMatView) && isDifferentThanRef) { return pg_rewrite->ev_class; } diff --git a/src/test/regress/expected/alter_distributed_table.out b/src/test/regress/expected/alter_distributed_table.out index 6c9708e7c..d8e5bb3fc 100644 --- a/src/test/regress/expected/alter_distributed_table.out +++ b/src/test/regress/expected/alter_distributed_table.out @@ -808,5 +808,34 @@ SELECT create_distributed_table('append_table', 'a', 'append'); SELECT alter_distributed_table('append_table', shard_count:=6); ERROR: relation append_table should be a hash distributed table +-- test keeping dependent materialized views +CREATE TABLE mat_view_test (a int, b int); +SELECT create_distributed_table('mat_view_test', 'a'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +INSERT INTO mat_view_test VALUES (1,1), (2,2); +CREATE MATERIALIZED VIEW mat_view AS SELECT * FROM mat_view_test; +SELECT alter_distributed_table('mat_view_test', shard_count := 5, cascade_to_colocated := false); +NOTICE: creating a new table for alter_distributed_table.mat_view_test +NOTICE: Moving the data of alter_distributed_table.mat_view_test +NOTICE: Dropping the old alter_distributed_table.mat_view_test +NOTICE: drop cascades to materialized view mat_view +CONTEXT: SQL statement "DROP TABLE alter_distributed_table.mat_view_test CASCADE" +NOTICE: Renaming the new table to alter_distributed_table.mat_view_test + alter_distributed_table +--------------------------------------------------------------------- + +(1 row) + +SELECT * FROM mat_view ORDER BY a; + a | b +--------------------------------------------------------------------- + 1 | 1 + 2 | 2 +(2 rows) + SET client_min_messages TO WARNING; DROP SCHEMA alter_distributed_table CASCADE; diff --git a/src/test/regress/expected/alter_distributed_table_0.out b/src/test/regress/expected/alter_distributed_table_0.out index 3805e7926..19ae993d0 100644 --- a/src/test/regress/expected/alter_distributed_table_0.out +++ b/src/test/regress/expected/alter_distributed_table_0.out @@ -787,5 +787,34 @@ SELECT create_distributed_table('append_table', 'a', 'append'); SELECT alter_distributed_table('append_table', shard_count:=6); ERROR: relation append_table should be a hash distributed table +-- test keeping dependent materialized views +CREATE TABLE mat_view_test (a int, b int); +SELECT create_distributed_table('mat_view_test', 'a'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +INSERT INTO mat_view_test VALUES (1,1), (2,2); +CREATE MATERIALIZED VIEW mat_view AS SELECT * FROM mat_view_test; +SELECT alter_distributed_table('mat_view_test', shard_count := 5, cascade_to_colocated := false); +NOTICE: creating a new table for alter_distributed_table.mat_view_test +NOTICE: Moving the data of alter_distributed_table.mat_view_test +NOTICE: Dropping the old alter_distributed_table.mat_view_test +NOTICE: drop cascades to materialized view mat_view +CONTEXT: SQL statement "DROP TABLE alter_distributed_table.mat_view_test CASCADE" +NOTICE: Renaming the new table to alter_distributed_table.mat_view_test + alter_distributed_table +--------------------------------------------------------------------- + +(1 row) + +SELECT * FROM mat_view ORDER BY a; + a | b +--------------------------------------------------------------------- + 1 | 1 + 2 | 2 +(2 rows) + SET client_min_messages TO WARNING; DROP SCHEMA alter_distributed_table CASCADE; diff --git a/src/test/regress/expected/alter_table_set_access_method.out b/src/test/regress/expected/alter_table_set_access_method.out index e0d6884b7..3b6fa1079 100644 --- a/src/test/regress/expected/alter_table_set_access_method.out +++ b/src/test/regress/expected/alter_table_set_access_method.out @@ -455,6 +455,212 @@ CONTEXT: SQL statement "ALTER TABLE alter_table_set_access_method.test_fk_p ATT CREATE TABLE same_access_method (a INT); SELECT alter_table_set_access_method('same_access_method', 'heap'); ERROR: the access method of alter_table_set_access_method.same_access_method is already heap +-- test keeping dependent materialized views +CREATE TABLE mat_view_test (a int); +INSERT INTO mat_view_test VALUES (1), (2); +CREATE MATERIALIZED VIEW mat_view AS SELECT * FROM mat_view_test; +SELECT alter_table_set_access_method('mat_view_test','columnar'); +NOTICE: creating a new table for alter_table_set_access_method.mat_view_test +NOTICE: Moving the data of alter_table_set_access_method.mat_view_test +NOTICE: Dropping the old alter_table_set_access_method.mat_view_test +NOTICE: drop cascades to materialized view mat_view +CONTEXT: SQL statement "DROP TABLE alter_table_set_access_method.mat_view_test CASCADE" +NOTICE: Renaming the new table to alter_table_set_access_method.mat_view_test + alter_table_set_access_method +--------------------------------------------------------------------- + +(1 row) + +SELECT * FROM mat_view ORDER BY a; + a +--------------------------------------------------------------------- + 1 + 2 +(2 rows) + +CREATE TABLE local(a int); +INSERT INTO local VALUES (3); +create materialized view m_local as select * from local; +create view v_local as select * from local; +CREATE TABLE ref(a int); +SELECT create_Reference_table('ref'); + create_reference_table +--------------------------------------------------------------------- + +(1 row) + +INSERT INTO ref VALUES (4),(5); +create materialized view m_ref as select * from ref; +create view v_ref as select * from ref; +CREATE TABLE dist(a int); +SELECT create_distributed_table('dist', 'a'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +INSERT INTO dist VALUES (7),(9); +create materialized view m_dist as select * from dist; +create view v_dist as select * from dist; +select alter_table_set_access_method('local','columnar'); +NOTICE: creating a new table for alter_table_set_access_method.local +NOTICE: Moving the data of alter_table_set_access_method.local +NOTICE: Dropping the old alter_table_set_access_method.local +NOTICE: drop cascades to 2 other objects +DETAIL: drop cascades to materialized view m_local +drop cascades to view v_local +CONTEXT: SQL statement "DROP TABLE alter_table_set_access_method.local CASCADE" +NOTICE: Renaming the new table to alter_table_set_access_method.local + alter_table_set_access_method +--------------------------------------------------------------------- + +(1 row) + +select alter_table_set_access_method('ref','columnar'); +NOTICE: creating a new table for alter_table_set_access_method.ref +NOTICE: Moving the data of alter_table_set_access_method.ref +NOTICE: Dropping the old alter_table_set_access_method.ref +NOTICE: drop cascades to 2 other objects +DETAIL: drop cascades to materialized view m_ref +drop cascades to view v_ref +CONTEXT: SQL statement "DROP TABLE alter_table_set_access_method.ref CASCADE" +NOTICE: Renaming the new table to alter_table_set_access_method.ref + alter_table_set_access_method +--------------------------------------------------------------------- + +(1 row) + +select alter_table_set_access_method('dist','columnar'); +NOTICE: creating a new table for alter_table_set_access_method.dist +NOTICE: Moving the data of alter_table_set_access_method.dist +NOTICE: Dropping the old alter_table_set_access_method.dist +NOTICE: drop cascades to 2 other objects +DETAIL: drop cascades to materialized view m_dist +drop cascades to view v_dist +CONTEXT: SQL statement "DROP TABLE alter_table_set_access_method.dist CASCADE" +NOTICE: Renaming the new table to alter_table_set_access_method.dist + alter_table_set_access_method +--------------------------------------------------------------------- + +(1 row) + +SELECT alter_distributed_table('dist', shard_count:=1, cascade_to_colocated:=false); +NOTICE: creating a new table for alter_table_set_access_method.dist +NOTICE: Moving the data of alter_table_set_access_method.dist +NOTICE: Dropping the old alter_table_set_access_method.dist +NOTICE: drop cascades to 2 other objects +DETAIL: drop cascades to materialized view m_dist +drop cascades to view v_dist +CONTEXT: SQL statement "DROP TABLE alter_table_set_access_method.dist CASCADE" +NOTICE: Renaming the new table to alter_table_set_access_method.dist + alter_distributed_table +--------------------------------------------------------------------- + +(1 row) + +select alter_table_set_access_method('local','heap'); +NOTICE: creating a new table for alter_table_set_access_method.local +NOTICE: Moving the data of alter_table_set_access_method.local +NOTICE: Dropping the old alter_table_set_access_method.local +NOTICE: drop cascades to 2 other objects +DETAIL: drop cascades to materialized view m_local +drop cascades to view v_local +CONTEXT: SQL statement "DROP TABLE alter_table_set_access_method.local CASCADE" +NOTICE: Renaming the new table to alter_table_set_access_method.local + alter_table_set_access_method +--------------------------------------------------------------------- + +(1 row) + +select alter_table_set_access_method('ref','heap'); +NOTICE: creating a new table for alter_table_set_access_method.ref +NOTICE: Moving the data of alter_table_set_access_method.ref +NOTICE: Dropping the old alter_table_set_access_method.ref +NOTICE: drop cascades to 2 other objects +DETAIL: drop cascades to materialized view m_ref +drop cascades to view v_ref +CONTEXT: SQL statement "DROP TABLE alter_table_set_access_method.ref CASCADE" +NOTICE: Renaming the new table to alter_table_set_access_method.ref + alter_table_set_access_method +--------------------------------------------------------------------- + +(1 row) + +select alter_table_set_access_method('dist','heap'); +NOTICE: creating a new table for alter_table_set_access_method.dist +NOTICE: Moving the data of alter_table_set_access_method.dist +NOTICE: Dropping the old alter_table_set_access_method.dist +NOTICE: drop cascades to 2 other objects +DETAIL: drop cascades to materialized view m_dist +drop cascades to view v_dist +CONTEXT: SQL statement "DROP TABLE alter_table_set_access_method.dist CASCADE" +NOTICE: Renaming the new table to alter_table_set_access_method.dist + alter_table_set_access_method +--------------------------------------------------------------------- + +(1 row) + +SELECT * FROM m_local; + a +--------------------------------------------------------------------- + 3 +(1 row) + +SELECT * FROM m_ref; + a +--------------------------------------------------------------------- + 4 + 5 +(2 rows) + +SELECT * FROM m_dist; + a +--------------------------------------------------------------------- + 7 + 9 +(2 rows) + +SELECT * FROM v_local; + a +--------------------------------------------------------------------- + 3 +(1 row) + +SELECT * FROM v_ref; + a +--------------------------------------------------------------------- + 4 + 5 +(2 rows) + +SELECT * FROM v_dist; + a +--------------------------------------------------------------------- + 7 + 9 +(2 rows) + +SELECT relname, relkind + FROM pg_class + WHERE relname IN ( + 'v_dist', + 'v_ref', + 'v_local', + 'm_dist', + 'm_ref', + 'm_local' + ) + ORDER BY relname ASC; + relname | relkind +--------------------------------------------------------------------- + m_dist | m + m_local | m + m_ref | m + v_dist | v + v_local | v + v_ref | v +(6 rows) + SET client_min_messages TO WARNING; DROP SCHEMA alter_table_set_access_method CASCADE; SELECT 1 FROM master_remove_node('localhost', :master_port); diff --git a/src/test/regress/sql/alter_distributed_table.sql b/src/test/regress/sql/alter_distributed_table.sql index aea0a7813..99a049441 100644 --- a/src/test/regress/sql/alter_distributed_table.sql +++ b/src/test/regress/sql/alter_distributed_table.sql @@ -272,5 +272,13 @@ CREATE TABLE append_table (a INT); SELECT create_distributed_table('append_table', 'a', 'append'); SELECT alter_distributed_table('append_table', shard_count:=6); +-- test keeping dependent materialized views +CREATE TABLE mat_view_test (a int, b int); +SELECT create_distributed_table('mat_view_test', 'a'); +INSERT INTO mat_view_test VALUES (1,1), (2,2); +CREATE MATERIALIZED VIEW mat_view AS SELECT * FROM mat_view_test; +SELECT alter_distributed_table('mat_view_test', shard_count := 5, cascade_to_colocated := false); +SELECT * FROM mat_view ORDER BY a; + SET client_min_messages TO WARNING; DROP SCHEMA alter_distributed_table CASCADE; diff --git a/src/test/regress/sql/alter_table_set_access_method.sql b/src/test/regress/sql/alter_table_set_access_method.sql index e1577e796..de703f154 100644 --- a/src/test/regress/sql/alter_table_set_access_method.sql +++ b/src/test/regress/sql/alter_table_set_access_method.sql @@ -143,6 +143,65 @@ select alter_table_set_access_method('test_fk_p1', 'columnar'); CREATE TABLE same_access_method (a INT); SELECT alter_table_set_access_method('same_access_method', 'heap'); +-- test keeping dependent materialized views +CREATE TABLE mat_view_test (a int); +INSERT INTO mat_view_test VALUES (1), (2); +CREATE MATERIALIZED VIEW mat_view AS SELECT * FROM mat_view_test; +SELECT alter_table_set_access_method('mat_view_test','columnar'); +SELECT * FROM mat_view ORDER BY a; + +CREATE TABLE local(a int); +INSERT INTO local VALUES (3); +create materialized view m_local as select * from local; +create view v_local as select * from local; + + +CREATE TABLE ref(a int); +SELECT create_Reference_table('ref'); +INSERT INTO ref VALUES (4),(5); +create materialized view m_ref as select * from ref; +create view v_ref as select * from ref; + + +CREATE TABLE dist(a int); +SELECT create_distributed_table('dist', 'a'); +INSERT INTO dist VALUES (7),(9); +create materialized view m_dist as select * from dist; +create view v_dist as select * from dist; + + +select alter_table_set_access_method('local','columnar'); +select alter_table_set_access_method('ref','columnar'); +select alter_table_set_access_method('dist','columnar'); + + +SELECT alter_distributed_table('dist', shard_count:=1, cascade_to_colocated:=false); + +select alter_table_set_access_method('local','heap'); +select alter_table_set_access_method('ref','heap'); +select alter_table_set_access_method('dist','heap'); + +SELECT * FROM m_local; +SELECT * FROM m_ref; +SELECT * FROM m_dist; + + +SELECT * FROM v_local; +SELECT * FROM v_ref; +SELECT * FROM v_dist; + +SELECT relname, relkind + FROM pg_class + WHERE relname IN ( + 'v_dist', + 'v_ref', + 'v_local', + 'm_dist', + 'm_ref', + 'm_local' + ) + ORDER BY relname ASC; + SET client_min_messages TO WARNING; DROP SCHEMA alter_table_set_access_method CASCADE; SELECT 1 FROM master_remove_node('localhost', :master_port);