diff --git a/src/backend/distributed/sql/citus--9.2-4--9.2-2.sql b/src/backend/distributed/sql/citus--9.2-4--9.2-2.sql new file mode 100644 index 000000000..fa71f4a6c --- /dev/null +++ b/src/backend/distributed/sql/citus--9.2-4--9.2-2.sql @@ -0,0 +1,2 @@ +-- citus--9.2-4--9.2-2 +-- this is an empty downgrade path since citus--9.2-2--9.2-4.sql is empty diff --git a/src/backend/distributed/sql/citus--9.3-2--9.2-4.sql b/src/backend/distributed/sql/citus--9.3-2--9.2-4.sql new file mode 100644 index 000000000..b5af80f38 --- /dev/null +++ b/src/backend/distributed/sql/citus--9.3-2--9.2-4.sql @@ -0,0 +1,30 @@ +-- citus--9.3-2--9.2-4 +-- this is a downgrade path that will revert the changes made in citus--9.2-4--9.3-2.sql +-- +-- 9.3-2 added citus extension owner as a distributed object, if not already in there. +-- However we can not really know if it was a distributed owner prior to 9.3-2. +-- That's why we leave the record in place. + +-- Revert the return type to void +DROP FUNCTION pg_catalog.citus_extradata_container(INTERNAL); +CREATE FUNCTION pg_catalog.citus_extradata_container(INTERNAL) + RETURNS void + LANGUAGE C + AS 'MODULE_PATHNAME', $$citus_extradata_container$$; +COMMENT ON FUNCTION pg_catalog.citus_extradata_container(INTERNAL) + IS 'placeholder function to store additional data in postgres node trees'; + +-- Remove newly introduced functions that are absent in earlier versions +DROP FUNCTION pg_catalog.update_distributed_table_colocation(regclass, text); +DROP FUNCTION pg_catalog.replicate_reference_tables(); +DROP FUNCTION pg_catalog.citus_remote_connection_stats( + OUT hostname text, + OUT port int, + OUT database_name text, + OUT connection_count_to_node int); +DROP FUNCTION pg_catalog.worker_create_or_alter_role( + role_name text, + create_role_utility_query text, + alter_role_utility_query text); +DROP FUNCTION pg_catalog.truncate_local_data_after_distributing_table( + function_name regclass); diff --git a/src/backend/distributed/sql/citus--9.4-1--9.3-2.sql b/src/backend/distributed/sql/citus--9.4-1--9.3-2.sql new file mode 100644 index 000000000..b7f8c2bbc --- /dev/null +++ b/src/backend/distributed/sql/citus--9.4-1--9.3-2.sql @@ -0,0 +1,6 @@ +-- citus--9.4-1--9.3-2 +-- this is a downgrade path that will revert the changes made in citus--9.3-2--9.4-1.sql + +DROP FUNCTION pg_catalog.worker_last_saved_explain_analyze(); +DROP FUNCTION pg_catalog.worker_save_query_explain_analyze(query text, + options jsonb); diff --git a/src/test/regress/expected/multi_extension.out b/src/test/regress/expected/multi_extension.out index 2b728f10d..441d9e31f 100644 --- a/src/test/regress/expected/multi_extension.out +++ b/src/test/regress/expected/multi_extension.out @@ -32,6 +32,35 @@ END; $$; $definition$ create_function_test_maintenance_worker \gset +CREATE TABLE prev_objects(description text); +CREATE TABLE extension_diff(previous_object text COLLATE "C", + current_object text COLLATE "C"); +CREATE FUNCTION print_extension_changes() +RETURNS TABLE(previous_object text, current_object text) +AS $func$ +BEGIN + TRUNCATE TABLE extension_diff; + + CREATE TABLE current_objects AS + SELECT pg_catalog.pg_describe_object(classid, objid, 0) AS description + FROM pg_catalog.pg_depend, pg_catalog.pg_extension e + WHERE refclassid = 'pg_catalog.pg_extension'::pg_catalog.regclass + AND refobjid = e.oid + AND deptype = 'e' + AND e.extname='citus'; + + INSERT INTO extension_diff + SELECT p.description previous_object, c.description current_object + FROM current_objects c FULL JOIN prev_objects p + ON p.description = c.description + WHERE p.description is null OR c.description is null; + + DROP TABLE prev_objects; + ALTER TABLE current_objects RENAME TO prev_objects; + + RETURN QUERY SELECT * FROM extension_diff ORDER BY 1, 2; +END +$func$ LANGUAGE plpgsql; CREATE SCHEMA test; :create_function_test_maintenance_worker -- check maintenance daemon is started @@ -120,17 +149,264 @@ ALTER EXTENSION citus UPDATE TO '9.0-2'; ALTER EXTENSION citus UPDATE TO '9.1-1'; ALTER EXTENSION citus UPDATE TO '9.2-1'; ALTER EXTENSION citus UPDATE TO '9.2-2'; +-- Snapshot of state at 9.2-2 +SELECT * FROM print_extension_changes(); + previous_object | current_object +--------------------------------------------------------------------- + | event trigger citus_cascade_to_partition + | function alter_role_if_exists(text,text) + | function any_value(anyelement) + | function any_value_agg(anyelement,anyelement) + | function array_cat_agg(anyarray) + | function assign_distributed_transaction_id(integer,bigint,timestamp with time zone) + | function authinfo_valid(text) + | function broadcast_intermediate_result(text,text) + | function check_distributed_deadlocks() + | function citus_add_rebalance_strategy(name,regproc,regproc,regproc,real,real) + | function citus_blocking_pids(integer) + | function citus_create_restore_point(text) + | function citus_dist_stat_activity() + | function citus_drop_trigger() + | function citus_executor_name(integer) + | function citus_extradata_container(internal) + | function citus_finish_pg_upgrade() + | function citus_internal.find_groupid_for_node(text,integer) + | function citus_internal.pg_dist_node_trigger_func() + | function citus_internal.pg_dist_rebalance_strategy_enterprise_check() + | function citus_internal.pg_dist_rebalance_strategy_trigger_func() + | function citus_internal.pg_dist_shard_placement_trigger_func() + | function citus_internal.refresh_isolation_tester_prepared_statement() + | function citus_internal.replace_isolation_tester_func() + | function citus_internal.restore_isolation_tester_func() + | function citus_isolation_test_session_is_blocked(integer,integer[]) + | function citus_json_concatenate(json,json) + | function citus_json_concatenate_final(json) + | function citus_jsonb_concatenate(jsonb,jsonb) + | function citus_jsonb_concatenate_final(jsonb) + | function citus_node_capacity_1(integer) + | function citus_prepare_pg_upgrade() + | function citus_query_stats() + | function citus_relation_size(regclass) + | function citus_server_id() + | function citus_set_default_rebalance_strategy(text) + | function citus_shard_allowed_on_node_true(bigint,integer) + | function citus_shard_cost_1(bigint) + | function citus_shard_cost_by_disk_size(bigint) + | function citus_stat_statements() + | function citus_stat_statements_reset() + | function citus_table_is_visible(oid) + | function citus_table_size(regclass) + | function citus_text_send_as_jsonb(text) + | function citus_total_relation_size(regclass) + | function citus_truncate_trigger() + | function citus_validate_rebalance_strategy_functions(regproc,regproc,regproc) + | function citus_version() + | function citus_worker_stat_activity() + | function column_name_to_column(regclass,text) + | function column_to_column_name(regclass,text) + | function coord_combine_agg(oid,cstring,anyelement) + | function coord_combine_agg_ffunc(internal,oid,cstring,anyelement) + | function coord_combine_agg_sfunc(internal,oid,cstring,anyelement) + | function create_distributed_function(regprocedure,text,text) + | function create_distributed_table(regclass,text,citus.distribution_type,text) + | function create_intermediate_result(text,text) + | function create_reference_table(regclass) + | function distributed_tables_colocated(regclass,regclass) + | function dump_global_wait_edges() + | function dump_local_wait_edges() + | function fetch_intermediate_results(text[],text,integer) + | function get_all_active_transactions() + | function get_colocated_shard_array(bigint) + | function get_colocated_table_array(regclass) + | function get_current_transaction_id() + | function get_global_active_transactions() + | function get_rebalance_progress() + | function get_rebalance_table_shards_plan(regclass,real,integer,bigint[],boolean,name) + | function get_shard_id_for_distribution_column(regclass,"any") + | function isolate_tenant_to_new_shard(regclass,"any",text) + | function json_cat_agg(json) + | function jsonb_cat_agg(jsonb) + | function lock_relation_if_exists(text,text) + | function lock_shard_metadata(integer,bigint[]) + | function lock_shard_resources(integer,bigint[]) + | function mark_tables_colocated(regclass,regclass[]) + | function master_activate_node(text,integer) + | function master_add_inactive_node(text,integer,integer,noderole,name) + | function master_add_node(text,integer,integer,noderole,name) + | function master_add_secondary_node(text,integer,text,integer,name) + | function master_append_table_to_shard(bigint,text,text,integer) + | function master_apply_delete_command(text) + | function master_conninfo_cache_invalidate() + | function master_copy_shard_placement(bigint,text,integer,text,integer,boolean,citus.shard_transfer_mode) + | function master_create_distributed_table(regclass,text,citus.distribution_type) + | function master_create_empty_shard(text) + | function master_create_worker_shards(text,integer,integer) + | function master_disable_node(text,integer) + | function master_dist_local_group_cache_invalidate() + | function master_dist_node_cache_invalidate() + | function master_dist_object_cache_invalidate() + | function master_dist_partition_cache_invalidate() + | function master_dist_placement_cache_invalidate() + | function master_dist_shard_cache_invalidate() + | function master_drain_node(text,integer,citus.shard_transfer_mode,name) + | function master_drop_all_shards(regclass,text,text) + | function master_drop_sequences(text[]) + | function master_get_active_worker_nodes() + | function master_get_new_placementid() + | function master_get_new_shardid() + | function master_get_table_ddl_events(text) + | function master_get_table_metadata(text) + | function master_modify_multiple_shards(text) + | function master_move_shard_placement(bigint,text,integer,text,integer,citus.shard_transfer_mode) + | function master_remove_distributed_table_metadata_from_workers(regclass,text,text) + | function master_remove_node(text,integer) + | function master_remove_partition_metadata(regclass,text,text) + | function master_run_on_worker(text[],integer[],text[],boolean) + | function master_set_node_property(text,integer,text,boolean) + | function master_unmark_object_distributed(oid,oid,integer) + | function master_update_node(integer,text,integer,boolean,integer) + | function master_update_shard_statistics(bigint) + | function master_update_table_statistics(regclass) + | function poolinfo_valid(text) + | function read_intermediate_result(text,citus_copy_format) + | function read_intermediate_results(text[],citus_copy_format) + | function rebalance_table_shards(regclass,real,integer,bigint[],citus.shard_transfer_mode,boolean,name) + | function recover_prepared_transactions() + | function relation_is_a_known_shard(regclass) + | function replicate_table_shards(regclass,integer,integer,bigint[],citus.shard_transfer_mode) + | function role_exists(name) + | function run_command_on_colocated_placements(regclass,regclass,text,boolean) + | function run_command_on_placements(regclass,text,boolean) + | function run_command_on_shards(regclass,text,boolean) + | function run_command_on_workers(text,boolean) + | function shard_name(regclass,bigint) + | function start_metadata_sync_to_node(text,integer) + | function stop_metadata_sync_to_node(text,integer) + | function task_tracker_assign_task(bigint,integer,text) + | function task_tracker_cleanup_job(bigint) + | function task_tracker_conninfo_cache_invalidate() + | function task_tracker_task_status(bigint,integer) + | function upgrade_to_reference_table(regclass) + | function worker_append_table_to_shard(text,text,text,integer) + | function worker_apply_inter_shard_ddl_command(bigint,text,bigint,text,text) + | function worker_apply_sequence_command(text) + | function worker_apply_sequence_command(text,regtype) + | function worker_apply_shard_ddl_command(bigint,text) + | function worker_apply_shard_ddl_command(bigint,text,text) + | function worker_cleanup_job_schema_cache() + | function worker_create_or_replace_object(text) + | function worker_create_schema(bigint,text) + | function worker_create_truncate_trigger(regclass) + | function worker_drop_distributed_table(text) + | function worker_execute_sql_task(bigint,integer,text,boolean) + | function worker_fetch_foreign_file(text,text,bigint,text[],integer[]) + | function worker_fetch_partition_file(bigint,integer,integer,integer,text,integer) + | function worker_hash("any") + | function worker_hash_partition_table(bigint,integer,text,text,oid,anyarray) + | function worker_merge_files_and_run_query(bigint,integer,text,text) + | function worker_merge_files_into_table(bigint,integer,text[],text[]) + | function worker_partial_agg(oid,anyelement) + | function worker_partial_agg_ffunc(internal) + | function worker_partial_agg_sfunc(internal,oid,anyelement) + | function worker_partition_query_result(text,text,integer,citus.distribution_type,text[],text[],boolean) + | function worker_range_partition_table(bigint,integer,text,text,oid,anyarray) + | function worker_repartition_cleanup(bigint) + | schema citus + | schema citus_internal + | sequence pg_dist_colocationid_seq + | sequence pg_dist_groupid_seq + | sequence pg_dist_node_nodeid_seq + | sequence pg_dist_placement_placementid_seq + | sequence pg_dist_shardid_seq + | table citus.pg_dist_object + | table pg_dist_authinfo + | table pg_dist_colocation + | table pg_dist_local_group + | table pg_dist_node + | table pg_dist_node_metadata + | table pg_dist_partition + | table pg_dist_placement + | table pg_dist_poolinfo + | table pg_dist_rebalance_strategy + | table pg_dist_shard + | table pg_dist_transaction + | type citus.distribution_type + | type citus.shard_transfer_mode + | type citus_copy_format + | type noderole + | view citus_dist_stat_activity + | view citus_lock_waits + | view citus_shard_indexes_on_worker + | view citus_shards_on_worker + | view citus_stat_statements + | view citus_worker_stat_activity + | view pg_dist_shard_placement +(188 rows) + +-- Test downgrade to 9.2-2 from 9.2-4 ALTER EXTENSION citus UPDATE TO '9.2-4'; +ALTER EXTENSION citus UPDATE TO '9.2-2'; +-- Should be empty result since upgrade+downgrade should be a no-op +SELECT * FROM print_extension_changes(); + previous_object | current_object +--------------------------------------------------------------------- +(0 rows) + /* - * As we mistakenly bumped schema version to 9.3-1 (in previous - * release), we support updating citus schema from 9.3-1 to 9.2-4, - * but we do not support explicitly updating it to to 9.3-1. - * Hence below update (to 9.3-1) command should fail. + * As we mistakenly bumped schema version to 9.3-1 in a bad release, we support + * updating citus schema from 9.3-1 to 9.2-4, but we do not support updates to 9.3-1. + * + * Hence the query below should fail. */ ALTER EXTENSION citus UPDATE TO '9.3-1'; -ERROR: extension "citus" has no update path from version "9.2-4" to version "9.3-1" +ERROR: extension "citus" has no update path from version "9.2-2" to version "9.3-1" +ALTER EXTENSION citus UPDATE TO '9.2-4'; +-- Snapshot of state at 9.2-4 +SELECT * FROM print_extension_changes(); + previous_object | current_object +--------------------------------------------------------------------- +(0 rows) + +-- Test downgrade to 9.2-4 from 9.3-2 ALTER EXTENSION citus UPDATE TO '9.3-2'; +ALTER EXTENSION citus UPDATE TO '9.2-4'; +-- Should be empty result since upgrade+downgrade should be a no-op +SELECT * FROM print_extension_changes(); + previous_object | current_object +--------------------------------------------------------------------- +(0 rows) + +-- Snapshot of state at 9.3-2 +ALTER EXTENSION citus UPDATE TO '9.3-2'; +SELECT * FROM print_extension_changes(); + previous_object | current_object +--------------------------------------------------------------------- + | function citus_remote_connection_stats() + | function replicate_reference_tables() + | function truncate_local_data_after_distributing_table(regclass) + | function update_distributed_table_colocation(regclass,text) + | function worker_create_or_alter_role(text,text,text) +(5 rows) + +-- Test downgrade to 9.3-2 from 9.4-1 ALTER EXTENSION citus UPDATE TO '9.4-1'; +ALTER EXTENSION citus UPDATE TO '9.3-2'; +-- Should be empty result since upgrade+downgrade should be a no-op +SELECT * FROM print_extension_changes(); + previous_object | current_object +--------------------------------------------------------------------- +(0 rows) + +-- Snapshot of state at 9.4-1 +ALTER EXTENSION citus UPDATE TO '9.4-1'; +SELECT * FROM print_extension_changes(); + previous_object | current_object +--------------------------------------------------------------------- + | function worker_last_saved_explain_analyze() + | function worker_save_query_explain_analyze(text,jsonb) +(2 rows) + +DROP TABLE prev_objects, extension_diff; -- show running version SHOW citus.version; citus.version diff --git a/src/test/regress/sql/multi_extension.sql b/src/test/regress/sql/multi_extension.sql index 97ff982c4..a757bab31 100644 --- a/src/test/regress/sql/multi_extension.sql +++ b/src/test/regress/sql/multi_extension.sql @@ -36,6 +36,37 @@ $$; $definition$ create_function_test_maintenance_worker \gset +CREATE TABLE prev_objects(description text); +CREATE TABLE extension_diff(previous_object text COLLATE "C", + current_object text COLLATE "C"); + +CREATE FUNCTION print_extension_changes() +RETURNS TABLE(previous_object text, current_object text) +AS $func$ +BEGIN + TRUNCATE TABLE extension_diff; + + CREATE TABLE current_objects AS + SELECT pg_catalog.pg_describe_object(classid, objid, 0) AS description + FROM pg_catalog.pg_depend, pg_catalog.pg_extension e + WHERE refclassid = 'pg_catalog.pg_extension'::pg_catalog.regclass + AND refobjid = e.oid + AND deptype = 'e' + AND e.extname='citus'; + + INSERT INTO extension_diff + SELECT p.description previous_object, c.description current_object + FROM current_objects c FULL JOIN prev_objects p + ON p.description = c.description + WHERE p.description is null OR c.description is null; + + DROP TABLE prev_objects; + ALTER TABLE current_objects RENAME TO prev_objects; + + RETURN QUERY SELECT * FROM extension_diff ORDER BY 1, 2; +END +$func$ LANGUAGE plpgsql; + CREATE SCHEMA test; :create_function_test_maintenance_worker @@ -121,16 +152,48 @@ ALTER EXTENSION citus UPDATE TO '9.0-2'; ALTER EXTENSION citus UPDATE TO '9.1-1'; ALTER EXTENSION citus UPDATE TO '9.2-1'; ALTER EXTENSION citus UPDATE TO '9.2-2'; +-- Snapshot of state at 9.2-2 +SELECT * FROM print_extension_changes(); + +-- Test downgrade to 9.2-2 from 9.2-4 ALTER EXTENSION citus UPDATE TO '9.2-4'; +ALTER EXTENSION citus UPDATE TO '9.2-2'; +-- Should be empty result since upgrade+downgrade should be a no-op +SELECT * FROM print_extension_changes(); + /* - * As we mistakenly bumped schema version to 9.3-1 (in previous - * release), we support updating citus schema from 9.3-1 to 9.2-4, - * but we do not support explicitly updating it to to 9.3-1. - * Hence below update (to 9.3-1) command should fail. + * As we mistakenly bumped schema version to 9.3-1 in a bad release, we support + * updating citus schema from 9.3-1 to 9.2-4, but we do not support updates to 9.3-1. + * + * Hence the query below should fail. */ ALTER EXTENSION citus UPDATE TO '9.3-1'; + +ALTER EXTENSION citus UPDATE TO '9.2-4'; +-- Snapshot of state at 9.2-4 +SELECT * FROM print_extension_changes(); + +-- Test downgrade to 9.2-4 from 9.3-2 ALTER EXTENSION citus UPDATE TO '9.3-2'; +ALTER EXTENSION citus UPDATE TO '9.2-4'; +-- Should be empty result since upgrade+downgrade should be a no-op +SELECT * FROM print_extension_changes(); + +-- Snapshot of state at 9.3-2 +ALTER EXTENSION citus UPDATE TO '9.3-2'; +SELECT * FROM print_extension_changes(); + +-- Test downgrade to 9.3-2 from 9.4-1 ALTER EXTENSION citus UPDATE TO '9.4-1'; +ALTER EXTENSION citus UPDATE TO '9.3-2'; +-- Should be empty result since upgrade+downgrade should be a no-op +SELECT * FROM print_extension_changes(); + +-- Snapshot of state at 9.4-1 +ALTER EXTENSION citus UPDATE TO '9.4-1'; +SELECT * FROM print_extension_changes(); + +DROP TABLE prev_objects, extension_diff; -- show running version SHOW citus.version;