From de82d0ff79d9f3af94692fc7f21a1d55a0acff69 Mon Sep 17 00:00:00 2001 From: Sait Talha Nisanci Date: Sat, 6 Jun 2020 12:55:21 +0300 Subject: [PATCH] add output for pg13 for propagate extension commands CREATE EXTENSION FROM is not supported anymore with postgres 13. An alternative output is added for pg13 where we basically error for that statement. --- .../expected/propagate_extension_commands.out | 13 +- .../propagate_extension_commands_1.out | 444 ++++++++++++++++++ 2 files changed, 451 insertions(+), 6 deletions(-) create mode 100644 src/test/regress/expected/propagate_extension_commands_1.out diff --git a/src/test/regress/expected/propagate_extension_commands.out b/src/test/regress/expected/propagate_extension_commands.out index 36f7254c9..969a52b97 100644 --- a/src/test/regress/expected/propagate_extension_commands.out +++ b/src/test/regress/expected/propagate_extension_commands.out @@ -226,16 +226,17 @@ $$); (1 row) CREATE EXTENSION dict_int FROM unpackaged; +ERROR: CREATE EXTENSION ... FROM is no longer supported SELECT run_command_on_workers($$SELECT count(extnamespace) FROM pg_extension WHERE extname = 'dict_int'$$); run_command_on_workers --------------------------------------------------------------------- - (localhost,57637,t,1) + (localhost,57637,t,0) (1 row) SELECT run_command_on_workers($$SELECT extversion FROM pg_extension WHERE extname = 'dict_int'$$); run_command_on_workers --------------------------------------------------------------------- - (localhost,57637,t,1.0) + (localhost,57637,t,"") (1 row) -- and add the other node @@ -264,15 +265,15 @@ SELECT run_command_on_workers($$SELECT extversion FROM pg_extension WHERE extnam SELECT run_command_on_workers($$SELECT count(extnamespace) FROM pg_extension WHERE extname = 'dict_int'$$); run_command_on_workers --------------------------------------------------------------------- - (localhost,57637,t,1) - (localhost,57638,t,1) + (localhost,57637,t,0) + (localhost,57638,t,0) (2 rows) SELECT run_command_on_workers($$SELECT extversion FROM pg_extension WHERE extname = 'dict_int'$$); run_command_on_workers --------------------------------------------------------------------- - (localhost,57637,t,1.0) - (localhost,57638,t,1.0) + (localhost,57637,t,"") + (localhost,57638,t,"") (2 rows) -- and similarly check for the reference table diff --git a/src/test/regress/expected/propagate_extension_commands_1.out b/src/test/regress/expected/propagate_extension_commands_1.out new file mode 100644 index 000000000..36f7254c9 --- /dev/null +++ b/src/test/regress/expected/propagate_extension_commands_1.out @@ -0,0 +1,444 @@ +CREATE SCHEMA "extension'test"; +-- use a schema name with escape character +SET search_path TO "extension'test"; +SET client_min_messages TO WARNING; +-- create an extension on the given search_path +-- the extension is on contrib, so should be avaliable for the regression tests +CREATE EXTENSION seg; +-- make sure that both the schema and the extension is distributed +SELECT count(*) FROM citus.pg_dist_object WHERE objid = (SELECT oid FROM pg_extension WHERE extname = 'seg'); + count +--------------------------------------------------------------------- + 1 +(1 row) + +SELECT count(*) FROM citus.pg_dist_object WHERE objid = (SELECT oid FROM pg_namespace WHERE nspname = 'extension''test'); + count +--------------------------------------------------------------------- + 1 +(1 row) + +CREATE TABLE test_table (key int, value seg); +SELECT create_distributed_table('test_table', 'key'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +-- make sure that the table is also distributed now +SELECT count(*) from pg_dist_partition where logicalrelid='extension''test.test_table'::regclass; + count +--------------------------------------------------------------------- + 1 +(1 row) + +CREATE TYPE two_segs AS (seg_1 seg, seg_2 seg); +-- verify that the type that depends on the extension is also marked as distributed +SELECT count(*) FROM citus.pg_dist_object WHERE objid = (SELECT oid FROM pg_type WHERE typname = 'two_segs' AND typnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'extension''test')); + count +--------------------------------------------------------------------- + 1 +(1 row) + +-- now try to run CREATE EXTENSION within a transction block, all should work fine +BEGIN; + CREATE EXTENSION isn WITH SCHEMA public; + -- now, try create a reference table relying on the data types + -- this should not succeed as we do not distribute extension commands within transaction blocks + CREATE TABLE dist_table (key int, value public.issn); + SELECT create_distributed_table('dist_table', 'key'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + + -- we can even run queries (sequentially) over the distributed table + SELECT * FROM dist_table; + key | value +--------------------------------------------------------------------- +(0 rows) + + INSERT INTO dist_table VALUES (1, public.issn('1436-4522')); + INSERT INTO dist_table SELECT * FROM dist_table RETURNING *; + key | value +--------------------------------------------------------------------- + 1 | 1436-4522 +(1 row) + +COMMIT; +-- make sure that the extension is distributed even if we run create extension in a transaction block +SELECT count(*) FROM citus.pg_dist_object WHERE objid = (SELECT oid FROM pg_extension WHERE extname = 'isn'); + count +--------------------------------------------------------------------- + 1 +(1 row) + +SELECT run_command_on_workers($$SELECT count(*) FROM pg_extension WHERE extname = 'isn'$$); + run_command_on_workers +--------------------------------------------------------------------- + (localhost,57637,t,1) + (localhost,57638,t,1) +(2 rows) + +CREATE TABLE ref_table (a public.issn); +-- now, create a reference table relying on the data types +SELECT create_reference_table('ref_table'); + create_reference_table +--------------------------------------------------------------------- + +(1 row) + +-- now, drop the extension, recreate it with an older version and update it to latest version +DROP EXTENSION isn CASCADE; +CREATE EXTENSION isn WITH VERSION "1.1"; +-- before updating the version, ensure the current version +SELECT run_command_on_workers($$SELECT extversion FROM pg_extension WHERE extname = 'isn'$$); + run_command_on_workers +--------------------------------------------------------------------- + (localhost,57637,t,1.1) + (localhost,57638,t,1.1) +(2 rows) + +-- now, update to a newer version +ALTER EXTENSION isn UPDATE TO '1.2'; +-- show that ALTER EXTENSION is propagated +SELECT run_command_on_workers($$SELECT extversion FROM pg_extension WHERE extname = 'isn'$$); + run_command_on_workers +--------------------------------------------------------------------- + (localhost,57637,t,1.2) + (localhost,57638,t,1.2) +(2 rows) + +-- before changing the schema, ensure the current schmea +SELECT run_command_on_workers($$SELECT nspname from pg_namespace where oid=(SELECT extnamespace FROM pg_extension WHERE extname = 'isn')$$); + run_command_on_workers +--------------------------------------------------------------------- + (localhost,57637,t,extension'test) + (localhost,57638,t,extension'test) +(2 rows) + +-- now change the schema +ALTER EXTENSION isn SET SCHEMA public; +-- switch back to public schema as we set extension's schema to public +SET search_path TO public; +-- make sure that the extension is distributed +SELECT count(*) FROM citus.pg_dist_object WHERE objid = (SELECT oid FROM pg_extension WHERE extname = 'isn'); + count +--------------------------------------------------------------------- + 1 +(1 row) + +-- show that the ALTER EXTENSION command is propagated +SELECT run_command_on_workers($$SELECT nspname from pg_namespace where oid=(SELECT extnamespace FROM pg_extension WHERE extname = 'isn')$$); + run_command_on_workers +--------------------------------------------------------------------- + (localhost,57637,t,public) + (localhost,57638,t,public) +(2 rows) + +-- drop the extension finally +DROP EXTENSION isn CASCADE; +-- now make sure that the reference tables depending on an extension can be succesfully created. +-- we should also ensure that we replicate this reference table (and hence the extension) +-- to new nodes after calling master_activate_node. +-- now, first drop seg and existing objects before next test +DROP EXTENSION seg CASCADE; +-- but as we have only 2 ports in postgresql tests, let's remove one of the nodes first +-- before remove, first remove the existing relations (due to the other tests) +DROP SCHEMA "extension'test" CASCADE; +SELECT 1 from master_remove_node('localhost', :worker_2_port); + ?column? +--------------------------------------------------------------------- + 1 +(1 row) + +-- then create the extension +CREATE EXTENSION seg; +-- show that the extension is created on existing worker +SELECT run_command_on_workers($$SELECT count(extnamespace) FROM pg_extension WHERE extname = 'seg'$$); + run_command_on_workers +--------------------------------------------------------------------- + (localhost,57637,t,1) +(1 row) + +SELECT run_command_on_workers($$SELECT extversion FROM pg_extension WHERE extname = 'seg'$$); + run_command_on_workers +--------------------------------------------------------------------- + (localhost,57637,t,1.3) +(1 row) + +-- now create the reference table +CREATE TABLE ref_table_2 (x seg); +SELECT create_reference_table('ref_table_2'); + create_reference_table +--------------------------------------------------------------------- + +(1 row) + +-- we also add an old style extension from before extensions which we upgrade to an extension +-- by exercising it before the add node we verify it will create the extension (without upgrading) +-- it on the new worker as well. For this we use the dict_int extension which is in contrib, +-- supports FROM unpackaged, and is relatively small +-- create objects for dict_int manually so we can upgrade from unpacked +CREATE FUNCTION dintdict_init(internal) RETURNS internal AS 'dict_int.so' LANGUAGE C STRICT; +CREATE FUNCTION dintdict_lexize(internal, internal, internal, internal) RETURNS internal AS 'dict_int.so' LANGUAGE C STRICT; +CREATE TEXT SEARCH TEMPLATE intdict_template (LEXIZE = dintdict_lexize, INIT = dintdict_init ); +CREATE TEXT SEARCH DICTIONARY intdict (TEMPLATE = intdict_template); +COMMENT ON TEXT SEARCH DICTIONARY intdict IS 'dictionary for integers'; +SELECT run_command_on_workers($$ +CREATE FUNCTION dintdict_init(internal) RETURNS internal AS 'dict_int.so' LANGUAGE C STRICT; +$$); + run_command_on_workers +--------------------------------------------------------------------- + (localhost,57637,t,"CREATE FUNCTION") +(1 row) + +SELECT run_command_on_workers($$ +CREATE FUNCTION dintdict_lexize(internal, internal, internal, internal) RETURNS internal AS 'dict_int.so' LANGUAGE C STRICT; +$$); + run_command_on_workers +--------------------------------------------------------------------- + (localhost,57637,t,"CREATE FUNCTION") +(1 row) + +SELECT run_command_on_workers($$ +CREATE TEXT SEARCH TEMPLATE intdict_template (LEXIZE = dintdict_lexize, INIT = dintdict_init ); +$$); + run_command_on_workers +--------------------------------------------------------------------- + (localhost,57637,t,"CREATE TEXT SEARCH TEMPLATE") +(1 row) + +SELECT run_command_on_workers($$ +CREATE TEXT SEARCH DICTIONARY intdict (TEMPLATE = intdict_template); +$$); + run_command_on_workers +--------------------------------------------------------------------- + (localhost,57637,t,"CREATE TEXT SEARCH DICTIONARY") +(1 row) + +SELECT run_command_on_workers($$ +COMMENT ON TEXT SEARCH DICTIONARY intdict IS 'dictionary for integers'; +$$); + run_command_on_workers +--------------------------------------------------------------------- + (localhost,57637,t,COMMENT) +(1 row) + +CREATE EXTENSION dict_int FROM unpackaged; +SELECT run_command_on_workers($$SELECT count(extnamespace) FROM pg_extension WHERE extname = 'dict_int'$$); + run_command_on_workers +--------------------------------------------------------------------- + (localhost,57637,t,1) +(1 row) + +SELECT run_command_on_workers($$SELECT extversion FROM pg_extension WHERE extname = 'dict_int'$$); + run_command_on_workers +--------------------------------------------------------------------- + (localhost,57637,t,1.0) +(1 row) + +-- and add the other node +SELECT 1 from master_add_node('localhost', :worker_2_port); + ?column? +--------------------------------------------------------------------- + 1 +(1 row) + +-- show that the extension is created on both existing and new node +SELECT run_command_on_workers($$SELECT count(extnamespace) FROM pg_extension WHERE extname = 'seg'$$); + run_command_on_workers +--------------------------------------------------------------------- + (localhost,57637,t,1) + (localhost,57638,t,1) +(2 rows) + +SELECT run_command_on_workers($$SELECT extversion FROM pg_extension WHERE extname = 'seg'$$); + run_command_on_workers +--------------------------------------------------------------------- + (localhost,57637,t,1.3) + (localhost,57638,t,1.3) +(2 rows) + +-- check for the unpackaged extension to be created correctly +SELECT run_command_on_workers($$SELECT count(extnamespace) FROM pg_extension WHERE extname = 'dict_int'$$); + run_command_on_workers +--------------------------------------------------------------------- + (localhost,57637,t,1) + (localhost,57638,t,1) +(2 rows) + +SELECT run_command_on_workers($$SELECT extversion FROM pg_extension WHERE extname = 'dict_int'$$); + run_command_on_workers +--------------------------------------------------------------------- + (localhost,57637,t,1.0) + (localhost,57638,t,1.0) +(2 rows) + +-- and similarly check for the reference table +select count(*) from pg_dist_partition where partmethod='n' and logicalrelid='ref_table_2'::regclass; + count +--------------------------------------------------------------------- + 1 +(1 row) + +SELECT count(*) FROM pg_dist_shard WHERE logicalrelid='ref_table_2'::regclass; + count +--------------------------------------------------------------------- + 1 +(1 row) + +DROP TABLE ref_table_2; +-- now test create extension in another transaction block but rollback this time +BEGIN; + CREATE EXTENSION isn WITH VERSION '1.1' SCHEMA public; +ROLLBACK; +-- at the end of the transaction block, we did not create isn extension in coordinator or worker nodes as we rollback'ed +-- make sure that the extension is not distributed +SELECT count(*) FROM citus.pg_dist_object WHERE objid = (SELECT oid FROM pg_extension WHERE extname = 'isn'); + count +--------------------------------------------------------------------- + 0 +(1 row) + +-- and the extension does not exist on workers +SELECT run_command_on_workers($$SELECT count(*) FROM pg_extension WHERE extname = 'isn'$$); + run_command_on_workers +--------------------------------------------------------------------- + (localhost,57637,t,0) + (localhost,57638,t,0) +(2 rows) + +-- give a notice for the following commands saying that it is not +-- propagated to the workers. the user should run it manually on the workers +CREATE TABLE t1 (A int); +CREATE VIEW v1 AS select * from t1; +ALTER EXTENSION seg ADD VIEW v1; +ALTER EXTENSION seg DROP VIEW v1; +DROP VIEW v1; +DROP TABLE t1; +-- drop multiple extensions at the same time +CREATE EXTENSION isn WITH VERSION '1.1' SCHEMA public; +-- let's create another extension locally +set citus.enable_ddl_propagation to 'off'; +CREATE EXTENSION pg_buffercache; +set citus.enable_ddl_propagation to 'on'; +DROP EXTENSION pg_buffercache, isn CASCADE; +SELECT count(*) FROM pg_extension WHERE extname IN ('pg_buffercache', 'isn'); + count +--------------------------------------------------------------------- + 0 +(1 row) + +-- drop extension should just work +DROP EXTENSION seg CASCADE; +SELECT count(*) FROM citus.pg_dist_object WHERE objid = (SELECT oid FROM pg_extension WHERE extname = 'seg'); + count +--------------------------------------------------------------------- + 0 +(1 row) + +SELECT run_command_on_workers($$SELECT count(*) FROM pg_extension WHERE extname = 'seg'$$); + run_command_on_workers +--------------------------------------------------------------------- + (localhost,57637,t,0) + (localhost,57638,t,0) +(2 rows) + +-- make sure that the extension is not avaliable anymore as a distributed object +SELECT count(*) FROM citus.pg_dist_object WHERE objid = (SELECT oid FROM pg_extension WHERE extname IN ('seg', 'isn')); + count +--------------------------------------------------------------------- + 0 +(1 row) + +CREATE SCHEMA "extension'test"; +SET search_path TO "extension'test"; +-- check restriction for sequential execution +-- enable it and see that create command errors but continues its execution by changing citus.multi_shard_modify_mode TO 'off +BEGIN; + CREATE TABLE some_random_table (a int); + SELECT create_distributed_table('some_random_table', 'a'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + + CREATE EXTENSION seg; + CREATE TABLE some_random_table_2 (a int, b seg); + SELECT create_distributed_table('some_random_table_2', 'a'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +ROLLBACK; +-- show that the CREATE EXTENSION command propagated even if the transaction +-- block is rollbacked, that's a shortcoming of dependency creation logic +SELECT run_command_on_workers($$SELECT extversion FROM pg_extension WHERE extname = 'seg'$$); + run_command_on_workers +--------------------------------------------------------------------- + (localhost,57637,t,1.3) + (localhost,57638,t,1.3) +(2 rows) + +-- drop the schema and all the objects +DROP SCHEMA "extension'test" CASCADE; +-- recreate for the next tests +CREATE SCHEMA "extension'test"; +-- use a schema name with escape character +SET search_path TO "extension'test"; +-- remove the node, we'll add back again +SELECT 1 from master_remove_node('localhost', :worker_2_port); + ?column? +--------------------------------------------------------------------- + 1 +(1 row) + +-- now, create a type that depends on another type, which +-- finally depends on an extension +BEGIN; + SET citus.shard_replication_factor TO 1; + CREATE EXTENSION seg; + CREATE EXTENSION isn; + CREATE TYPE test_type AS (a int, b seg); + CREATE TYPE test_type_2 AS (a int, b test_type); + CREATE TABLE t2 (a int, b test_type_2, c issn); + SELECT create_distributed_table('t2', 'a'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + + CREATE TYPE test_type_3 AS (a int, b test_type, c issn); + CREATE TABLE t3 (a int, b test_type_3); + SELECT create_reference_table('t3'); + create_reference_table +--------------------------------------------------------------------- + +(1 row) + +COMMIT; +-- add the node back +SELECT 1 from master_add_node('localhost', :worker_2_port); + ?column? +--------------------------------------------------------------------- + 1 +(1 row) + +-- make sure that both extensions are created on both nodes +SELECT count(*) FROM citus.pg_dist_object WHERE objid IN (SELECT oid FROM pg_extension WHERE extname IN ('seg', 'isn')); + count +--------------------------------------------------------------------- + 2 +(1 row) + +SELECT run_command_on_workers($$SELECT count(*) FROM pg_extension WHERE extname IN ('seg', 'isn')$$); + run_command_on_workers +--------------------------------------------------------------------- + (localhost,57637,t,2) + (localhost,57638,t,2) +(2 rows) + +-- drop the schema and all the objects +DROP SCHEMA "extension'test" CASCADE;