\set ON_ERROR_ROLLBACK 1 \set ON_ERROR_STOP true BEGIN; SELECT set_config('search_path','partman, public',false); SELECT plan(7); -- Sanity check that new features get adding to definition dumping. SELECT bag_eq( E'SELECT attname FROM pg_catalog.pg_attribute a JOIN pg_catalog.pg_class c ON a.attrelid = c.oid WHERE c.relname = ''part_config'' AND NOT attisdropped AND attnum > 0', ARRAY[ 'parent_table', 'control', 'partition_type', 'partition_interval', 'constraint_cols', 'premake', 'optimize_trigger', 'optimize_constraint', 'epoch', 'inherit_fk', 'retention', 'retention_schema', 'retention_keep_table', 'retention_keep_index', 'infinite_time_partitions', 'datetime_string', 'automatic_maintenance', 'jobmon', 'sub_partition_set_full', 'undo_in_progress', 'trigger_exception_handling', 'upsert', 'trigger_return_null', 'template_table', 'publications', 'inherit_privileges', 'constraint_valid', 'subscription_refresh', 'drop_cascade_fk', 'ignore_default_data' ]::TEXT[], 'When adding a new column to part_config please ensure it is also added to the dump_partitioned_table_definition function' ); -- Create a partman non-declarative partitioned table. CREATE TABLE public.objects(id SERIAL PRIMARY KEY, t TEXT, created_at TIMESTAMP NOT NULL); SELECT partman.create_parent('public.objects', 'created_at', 'partman', 'weekly', p_premake := 2); -- Update config options you can't set at initial creation. UPDATE partman.part_config SET retention='5 weeks', retention_keep_table = 'f', infinite_time_partitions = 't' WHERE parent_table = 'public.objects'; -- Test output "visually". -- Note that spaces before each line are literal tabs (\t), not spaces SELECT is( (SELECT partman.dump_partitioned_table_definition('public.objects')), E'SELECT partman.create_parent( p_parent_table := ''public.objects'', p_control := ''created_at'', p_type := ''partman'', p_interval := ''weekly'', p_constraint_cols := NULL, p_premake := 2, p_automatic_maintenance := ''on'', p_inherit_fk := ''t'', p_epoch := ''none'', p_upsert := '''', p_publications := NULL, p_trigger_return_null := ''t'', p_template_table := NULL, p_jobmon := ''t'' -- v_start_partition is intentionally ignored as there -- isn''t any obviously correct definition. ); UPDATE partman.part_config SET optimize_trigger = 4, optimize_constraint = 30, retention = ''5 weeks'', retention_schema = NULL, retention_keep_table = ''f'', retention_keep_index = ''t'', infinite_time_partitions = ''t'', datetime_string = ''IYYY"w"IW'', sub_partition_set_full = ''f'', trigger_exception_handling = ''f'', inherit_privileges = ''t'', constraint_valid = ''t'', subscription_refresh = NULL, ignore_default_data = ''f'' WHERE parent_table = ''public.objects'';' ); -- Test end to end: -- 1. Capture the current config. SELECT part_config AS objects_part_config FROM partman.part_config WHERE parent_table = 'public.objects' \gset SELECT partman.dump_partitioned_table_definition('public.objects') AS var_sql \gset -- 2. Remove partitioning and recreate table. SELECT partman.undo_partition('public.objects', p_keep_table := false); DROP TABLE public.objects; CREATE TABLE public.objects(id SERIAL PRIMARY KEY, t TEXT, created_at TIMESTAMP NOT NULL); SELECT is((SELECT 1 FROM partman.part_config WHERE parent_table = 'public.objects'), NULL); -- 3. Run dumped config. SELECT :'var_sql' \gexec -- 4. Check the current config (it should match step 1). SELECT row_eq( 'SELECT * FROM partman.part_config WHERE parent_table = ''public.objects''', (:'objects_part_config')::partman.part_config ); -- Create a partman declarative partitioned table. CREATE TABLE public.declarative_objects( id SERIAL, t TEXT, created_at TIMESTAMP NOT NULL ) PARTITION BY RANGE (created_at); SELECT partman.create_parent('public.declarative_objects', 'created_at', 'native', 'weekly', p_premake := 2, p_start_partition := (NOW() - '4 weeks'::INTERVAL)::TEXT); -- Update config options you can't set at initial creation. UPDATE partman.part_config SET retention='5 weeks', retention_keep_table = 'f', infinite_time_partitions = 't', constraint_valid = 'f', inherit_privileges = 't' WHERE parent_table = 'public.declarative_objects'; -- Test output "visually" (with p_ignore_template_table = true). SELECT partman.dump_partitioned_table_definition('public.declarative_objects', p_ignore_template_table := true); -- -- -- Test output "visually" (with default p_ignore_template_table = false). -- -- Note that spaces before each line are literal tabs (\t), not spaces SELECT is( (SELECT partman.dump_partitioned_table_definition('public.declarative_objects')), E'SELECT partman.create_parent( p_parent_table := ''public.declarative_objects'', p_control := ''created_at'', p_type := ''native'', p_interval := ''7 days'', p_constraint_cols := NULL, p_premake := 2, p_automatic_maintenance := ''on'', p_inherit_fk := ''t'', p_epoch := ''none'', p_upsert := '''', p_publications := NULL, p_trigger_return_null := ''t'', p_template_table := ''partman.template_public_declarative_objects'', p_jobmon := ''t'' -- v_start_partition is intentionally ignored as there -- isn''t any obviously correct definition. ); UPDATE partman.part_config SET optimize_trigger = 4, optimize_constraint = 30, retention = ''5 weeks'', retention_schema = NULL, retention_keep_table = ''f'', retention_keep_index = ''t'', infinite_time_partitions = ''t'', datetime_string = ''IYYY"w"IW'', sub_partition_set_full = ''f'', trigger_exception_handling = ''f'', inherit_privileges = ''t'', constraint_valid = ''f'', subscription_refresh = NULL, ignore_default_data = ''f'' WHERE parent_table = ''public.declarative_objects'';' ); -- Test end to end (with p_ignore_template_table = true): -- 1. Capture the current config. SELECT part_config AS declarative_objects_part_config FROM partman.part_config WHERE parent_table = 'public.declarative_objects' \gset SELECT partman.dump_partitioned_table_definition('public.declarative_objects', p_ignore_template_table := true) AS var_sql \gset -- 2. Remove partitioning and recreate table. CREATE TABLE public.old_declarative_objects(id SERIAL, t TEXT, created_at TIMESTAMP NOT NULL); SELECT partman.undo_partition('public.declarative_objects', p_keep_table := false, p_target_table := 'public.old_declarative_objects'); DROP TABLE public.declarative_objects; CREATE TABLE public.declarative_objects( id SERIAL, t TEXT, created_at TIMESTAMP NOT NULL ) PARTITION BY RANGE (created_at); -- 3. Run dumped config. SELECT :'var_sql' \gexec -- 4. Check the current config (it should match step 1). SELECT row_eq( 'SELECT * FROM partman.part_config WHERE parent_table = ''public.declarative_objects''', (:'declarative_objects_part_config')::partman.part_config ); -- Test end to end (with default p_ignore_template_table = false): -- 1. Capture the current config. SELECT part_config AS declarative_objects_part_config FROM partman.part_config WHERE parent_table = 'public.declarative_objects' \gset SELECT partman.dump_partitioned_table_definition('public.declarative_objects') AS var_sql \gset -- 2. Remove partitioning and recreate table. SELECT partman.undo_partition('public.declarative_objects', p_keep_table := false, p_target_table := 'public.old_declarative_objects'); DROP TABLE public.declarative_objects; CREATE TABLE public.declarative_objects( id SERIAL, t TEXT, created_at TIMESTAMP NOT NULL ) PARTITION BY RANGE (created_at); -- 3. Run dumped config (after creating template table). CREATE TABLE partman.template_public_declarative_objects( id SERIAL, t TEXT, created_at TIMESTAMP NOT NULL ); SELECT :'var_sql' \gexec -- 4. Check the current config (it should match step 1). SELECT row_eq( 'SELECT * FROM partman.part_config WHERE parent_table = ''public.declarative_objects''', (:'declarative_objects_part_config')::partman.part_config ); SELECT * FROM finish(); ROLLBACK;