diff --git a/ansible/vars.yml b/ansible/vars.yml index 8dd127ae3..12123a7c6 100644 --- a/ansible/vars.yml +++ b/ansible/vars.yml @@ -10,9 +10,9 @@ postgres_major: # Full version strings for each major version postgres_release: - postgresorioledb-17: "17.5.1.051-orioledb" - postgres17: "17.6.1.030" - postgres15: "15.14.1.030" + postgresorioledb-17: "17.5.1.051-orioledb-test-partman" + postgres17: "17.6.1.030-test-partman" + postgres15: "15.14.1.030-test-partman" # Non Postgres Extensions pgbouncer_release: 1.19.0 diff --git a/migrations/schema.sql b/migrations/schema.sql index cb031f797..65e720224 100644 --- a/migrations/schema.sql +++ b/migrations/schema.sql @@ -78,6 +78,12 @@ CREATE EXTENSION IF NOT EXISTS pg_graphql WITH SCHEMA graphql; COMMENT ON EXTENSION pg_graphql IS 'pg_graphql: GraphQL support'; +-- +-- Name: pg_partman; Type: EXTENSION; Schema: -; Owner: - +-- + +CREATE SCHEMA partman; +CREATE EXTENSION pg_partman SCHEMA partman; -- -- Name: pg_stat_statements; Type: EXTENSION; Schema: -; Owner: - diff --git a/migrations/tests/extensions/30-pg_partman.sql b/migrations/tests/extensions/30-pg_partman.sql new file mode 100644 index 000000000..ad4ef6d72 --- /dev/null +++ b/migrations/tests/extensions/30-pg_partman.sql @@ -0,0 +1,4 @@ +BEGIN; +create schema if not exists "partman"; +create extension if not exists pg_partman with schema "partman"; +ROLLBACK; diff --git a/migrations/tests/extensions/test.sql b/migrations/tests/extensions/test.sql index 7e0d1f38d..1d7075c13 100644 --- a/migrations/tests/extensions/test.sql +++ b/migrations/tests/extensions/test.sql @@ -28,3 +28,4 @@ \ir 27-pg_repack.sql \ir 28-pgvector.sql \ir 29-pg_tle.sql +\ir 30-pg_partman.sql diff --git a/nix/ext/pg_partman.nix b/nix/ext/pg_partman.nix index 08fc74cee..437db5131 100644 --- a/nix/ext/pg_partman.nix +++ b/nix/ext/pg_partman.nix @@ -1,38 +1,107 @@ { + pkgs, lib, stdenv, fetchFromGitHub, postgresql, + makeWrapper, + switch-ext-version, }: -stdenv.mkDerivation rec { +let pname = "pg_partman"; - version = "5.1.0"; + build = + version: hash: + stdenv.mkDerivation rec { + inherit pname version; - buildInputs = [ postgresql ]; + buildInputs = [ postgresql ]; + + src = fetchFromGitHub { + owner = "pgpartman"; + repo = pname; + rev = "refs/tags/v${version}"; + inherit hash; + }; + + installPhase = '' + mkdir -p $out/{lib,share/postgresql/extension} + + # Install versioned library + install -Dm755 src/*${postgresql.dlSuffix} $out/lib/${pname}-${version}${postgresql.dlSuffix} + + # Only install SQL files for the latest version + if [[ "${version}" == "${latestVersion}" ]]; then + # Install all SQL files from sql/ directory + cp -r sql/* $out/share/postgresql/extension/ + + # Install upgrade scripts + cp updates/* $out/share/postgresql/extension/ + fi + + # Create versioned control file with modified module path + sed -e "/^default_version =/d" \ + -e "s|^module_pathname = .*|module_pathname = '\$libdir/${pname}'|" \ + ${pname}.control > $out/share/postgresql/extension/${pname}--${version}.control + ''; + + meta = with lib; { + description = "Partition management extension for PostgreSQL"; + homepage = "https://github.com/pgpartman/pg_partman"; + changelog = "https://github.com/pgpartman/pg_partman/blob/v${version}/CHANGELOG.md"; + platforms = postgresql.meta.platforms; + license = licenses.postgresql; + }; + }; + allVersions = (builtins.fromJSON (builtins.readFile ./versions.json)).pg_partman; + supportedVersions = lib.filterAttrs ( + _: value: builtins.elem (lib.versions.major postgresql.version) value.postgresql + ) allVersions; + versions = lib.naturalSort (lib.attrNames supportedVersions); + latestVersion = lib.last versions; + numberOfVersions = builtins.length versions; + packages = builtins.attrValues ( + lib.mapAttrs (name: value: build name value.hash) supportedVersions + ); +in +pkgs.buildEnv { + name = pname; + paths = packages; + nativeBuildInputs = [ makeWrapper ]; + + pathsToLink = [ + "/lib" + "/share/postgresql/extension" + ]; + + postBuild = '' + { + echo "default_version = '${latestVersion}'" + cat $out/share/postgresql/extension/${pname}--${latestVersion}.control + } > $out/share/postgresql/extension/${pname}.control + ln -sfn ${pname}-${latestVersion}${postgresql.dlSuffix} $out/lib/${pname}${postgresql.dlSuffix} - src = fetchFromGitHub { - owner = "pgpartman"; - repo = pname; - rev = "refs/tags/v${version}"; - sha256 = "sha256-GrVOJ5ywZMyqyDroYDLdKkXDdIJSDGhDfveO/ZvrmYs="; - }; - installPhase = '' - mkdir -p $out/{lib,share/postgresql/extension} + # checks + (set -x + test "$(ls -A $out/lib/${pname}*${postgresql.dlSuffix} | wc -l)" = "${ + toString (numberOfVersions + 1) + }" + ) - cp src/*${postgresql.dlSuffix} $out/lib - cp updates/* $out/share/postgresql/extension - cp -r sql/* $out/share/postgresql/extension - cp *.control $out/share/postgresql/extension + makeWrapper ${lib.getExe switch-ext-version} $out/bin/switch_pg_partman_version \ + --prefix EXT_WRAPPER : "$out" --prefix EXT_NAME : "${pname}" ''; - meta = with lib; { - description = "Partition management extension for PostgreSQL"; - homepage = "https://github.com/pgpartman/pg_partman"; - changelog = "https://github.com/pgpartman/pg_partman/blob/v${version}/CHANGELOG.md"; - platforms = postgresql.meta.platforms; - license = licenses.postgresql; - broken = versionOlder postgresql.version "14"; + passthru = { + inherit versions numberOfVersions switch-ext-version; + pname = "${pname}-all"; + hasBackgroundWorker = true; + defaultSchema = "partman"; + defaultSettings = { + shared_preload_libraries = [ "pg_partman" ]; + }; + version = + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); }; } diff --git a/nix/ext/tests/default.nix b/nix/ext/tests/default.nix index 51c22ff0e..0c03e8d77 100644 --- a/nix/ext/tests/default.nix +++ b/nix/ext/tests/default.nix @@ -138,6 +138,7 @@ let } sql_test_directory = Path("${../../tests}") pg_regress_test_name = "${(installedExtension "15").pgRegressTestName or pname}" + ext_schema = "${(installedExtension "15").defaultSchema or "public"}" ${builtins.readFile ./lib.py} @@ -146,7 +147,8 @@ let server.wait_for_unit("multi-user.target") server.wait_for_unit("postgresql.service") - test = PostgresExtensionTest(server, extension_name, versions, sql_test_directory, support_upgrade) + test = PostgresExtensionTest(server, extension_name, versions, sql_test_directory, support_upgrade, ext_schema) + test.create_schema() with subtest("Check upgrade path with postgresql 15"): test.check_upgrade_path("15") @@ -206,6 +208,7 @@ builtins.listToAttrs ( "pg_graphql" "pg_jsonschema" "pg_net" + "pg_partman" "vector" "wrappers" ] diff --git a/nix/ext/tests/lib.py b/nix/ext/tests/lib.py index 3383f2498..232919c4c 100644 --- a/nix/ext/tests/lib.py +++ b/nix/ext/tests/lib.py @@ -20,6 +20,7 @@ def __init__( versions: Versions, sql_test_dir: Path, support_upgrade: bool = True, + schema: str = "public", ): """Initialize the PostgreSQL extension test framework. @@ -35,6 +36,10 @@ def __init__( self.versions = versions self.support_upgrade = support_upgrade self.sql_test_dir = sql_test_dir + self.schema = schema + + def create_schema(self): + self.run_sql(f"CREATE SCHEMA IF NOT EXISTS {self.schema};") def run_sql(self, query: str) -> str: return self.vm.succeed( @@ -50,8 +55,12 @@ def drop_extension(self): self.run_sql(f"DROP EXTENSION IF EXISTS {self.extension_name};") def install_extension(self, version: str): + if self.schema != "public": + ext_schema = f"SCHEMA {self.schema} " + else: + ext_schema = "" self.run_sql( - f"""CREATE EXTENSION {self.extension_name} WITH VERSION '{version}' CASCADE;""" + f"""CREATE EXTENSION {self.extension_name} WITH {ext_schema}VERSION '{version}' CASCADE;""" ) # Verify version was installed correctly self.assert_version_matches(version) diff --git a/nix/ext/versions.json b/nix/ext/versions.json index 840944094..cb97cc743 100644 --- a/nix/ext/versions.json +++ b/nix/ext/versions.json @@ -320,6 +320,16 @@ ], "hash": "sha256-Cpi2iASi1QJoED0Qs1dANqg/BNZTsz5S+pw8iYyW03Y=" } + }, + "pg_partman": { + "5.2.4": { + "postgresql": [ + "15", + "17", + "orioledb-17" + ], + "hash": "sha256-i/o+JZEXnJRO17kfdTw87aca28+I8pvuFZsPMA/kf+w=" + } }, "pgmq": { "1.4.4": { diff --git a/nix/packages/postgres.nix b/nix/packages/postgres.nix index 170180188..6852db981 100644 --- a/nix/packages/postgres.nix +++ b/nix/packages/postgres.nix @@ -36,6 +36,7 @@ ../ext/pg_graphql ../ext/pg_stat_monitor.nix ../ext/pg_jsonschema + ../ext/pg_partman.nix ../ext/pgvector.nix ../ext/vault.nix ../ext/hypopg.nix diff --git a/nix/tests/expected/pg_partman.out b/nix/tests/expected/pg_partman.out new file mode 100644 index 000000000..16d0f43de --- /dev/null +++ b/nix/tests/expected/pg_partman.out @@ -0,0 +1,24 @@ +CREATE SCHEMA IF NOT EXISTS partman_test; +CREATE TABLE partman_test.time_taptest_table + (col1 int, + col2 text default 'stuff', + col3 timestamptz NOT NULL DEFAULT now()) +PARTITION BY RANGE (col3); +CREATE INDEX ON partman_test.time_taptest_table (col3); +CREATE TABLE partman_test.time_taptest_table_template (LIKE partman_test.time_taptest_table); +ALTER TABLE partman_test.time_taptest_table_template ADD PRIMARY KEY (col1); +SELECT partman.create_parent( + p_parent_table := 'partman_test.time_taptest_table' + , p_control := 'col3' + , p_interval := '1 day' + , p_template_table := 'partman_test.time_taptest_table_template' +); + create_parent +--------------- + t +(1 row) + +DROP SCHEMA partman_test CASCADE; +NOTICE: drop cascades to 2 other objects +DETAIL: drop cascades to table partman_test.time_taptest_table +drop cascades to table partman_test.time_taptest_table_template diff --git a/nix/tests/expected/z_15_ext_interface.out b/nix/tests/expected/z_15_ext_interface.out index a0db07837..aae3958b7 100644 --- a/nix/tests/expected/z_15_ext_interface.out +++ b/nix/tests/expected/z_15_ext_interface.out @@ -84,6 +84,7 @@ order by pg_hashids | t pg_jsonschema | f pg_net | f + pg_partman | f pg_prewarm | t pg_repack | f pg_stat_monitor | t @@ -128,7 +129,7 @@ order by vector | t wrappers | t xml2 | f -(79 rows) +(80 rows) /* @@ -168,8 +169,8 @@ order by n.nspname, p.proname, md5(pg_catalog.pg_get_function_identity_arguments(p.oid)); - extension_name | schema_name | function_name | argument_types | return_type -------------------------+--------------------------+--------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + extension_name | schema_name | function_name | argument_types | return_type +------------------------+--------------------------+--------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ address_standardizer | public | parse_address | text, OUT num text, OUT street text, OUT street2 text, OUT address1 text, OUT city text, OUT state text, OUT zip text, OUT zipplus text, OUT country text | record address_standardizer | public | standardize_address | lextab text, gaztab text, rultab text, address text | stdaddr address_standardizer | public | standardize_address | lextab text, gaztab text, rultab text, micro text, macro text | stdaddr @@ -1167,6 +1168,47 @@ order by pg_net | net | wait_until_running | | void pg_net | net | wake | | void pg_net | net | worker_restart | | boolean + pg_partman | partman | apply_cluster | p_parent_schema text, p_parent_tablename text, p_child_schema text, p_child_tablename text | void + pg_partman | partman | apply_constraints | p_parent_table text, p_child_table text, p_analyze boolean, p_job_id bigint | void + pg_partman | partman | apply_privileges | p_parent_schema text, p_parent_tablename text, p_child_schema text, p_child_tablename text, p_job_id bigint | void + pg_partman | partman | autovacuum_off | p_parent_schema text, p_parent_tablename text, p_source_schema text, p_source_tablename text | boolean + pg_partman | partman | autovacuum_reset | p_parent_schema text, p_parent_tablename text, p_source_schema text, p_source_tablename text | boolean + pg_partman | partman | calculate_time_partition_info | p_time_interval interval, p_start_time timestamp with time zone, p_date_trunc_interval text, OUT base_timestamp timestamp with time zone, OUT datetime_string text | record + pg_partman | partman | check_automatic_maintenance_value | p_automatic_maintenance text | boolean + pg_partman | partman | check_control_type | p_parent_schema text, p_parent_tablename text, p_control text | TABLE(general_type text, exact_type text) + pg_partman | partman | check_default | p_exact_count boolean | SETOF partman.check_default_table + pg_partman | partman | check_epoch_type | p_type text | boolean + pg_partman | partman | check_name_length | p_object_name text, p_suffix text, p_table_partition boolean | text + pg_partman | partman | check_partition_type | p_type text | boolean + pg_partman | partman | check_subpart_sameconfig | p_parent_table text | TABLE(sub_control text, sub_partition_interval text, sub_partition_type text, sub_premake integer, sub_automatic_maintenance text, sub_template_table text, sub_retention text, sub_retention_schema text, sub_retention_keep_index boolean, sub_retention_keep_table boolean, sub_epoch text, sub_constraint_cols text[], sub_optimize_constraint integer, sub_infinite_time_partitions boolean, sub_jobmon boolean, sub_inherit_privileges boolean, sub_constraint_valid boolean, sub_date_trunc_interval text, sub_ignore_default_data boolean, sub_default_table boolean, sub_maintenance_order integer, sub_retention_keep_publication boolean, sub_control_not_null boolean) + pg_partman | partman | check_subpartition_limits | p_parent_table text, p_type text, OUT sub_min text, OUT sub_max text | record + pg_partman | partman | create_parent | p_parent_table text, p_control text, p_interval text, p_type text, p_epoch text, p_premake integer, p_start_partition text, p_default_table boolean, p_automatic_maintenance text, p_constraint_cols text[], p_template_table text, p_jobmon boolean, p_date_trunc_interval text, p_control_not_null boolean, p_time_encoder text, p_time_decoder text | boolean + pg_partman | partman | create_partition_id | p_parent_table text, p_partition_ids bigint[], p_start_partition text | boolean + pg_partman | partman | create_partition_time | p_parent_table text, p_partition_times timestamp with time zone[], p_start_partition text | boolean + pg_partman | partman | create_sub_parent | p_top_parent text, p_control text, p_interval text, p_type text, p_default_table boolean, p_declarative_check text, p_constraint_cols text[], p_premake integer, p_start_partition text, p_epoch text, p_jobmon boolean, p_date_trunc_interval text, p_control_not_null boolean, p_time_encoder text, p_time_decoder text | boolean + pg_partman | partman | drop_constraints | p_parent_table text, p_child_table text, p_debug boolean | void + pg_partman | partman | drop_partition_id | p_parent_table text, p_retention bigint, p_keep_table boolean, p_keep_index boolean, p_retention_schema text | integer + pg_partman | partman | drop_partition_time | p_parent_table text, p_retention interval, p_keep_table boolean, p_keep_index boolean, p_retention_schema text, p_reference_timestamp timestamp with time zone | integer + pg_partman | partman | dump_partitioned_table_definition | p_parent_table text, p_ignore_template_table boolean | text + pg_partman | partman | inherit_replica_identity | p_parent_schemaname text, p_parent_tablename text, p_child_tablename text | void + pg_partman | partman | inherit_template_properties | p_parent_table text, p_child_schema text, p_child_tablename text | boolean + pg_partman | partman | partition_data_id | p_parent_table text, p_batch_count integer, p_batch_interval bigint, p_lock_wait numeric, p_order text, p_analyze boolean, p_source_table text, p_ignored_columns text[] | bigint + pg_partman | partman | partition_data_proc | IN p_parent_table text, IN p_loop_count integer, IN p_interval text, IN p_lock_wait integer, IN p_lock_wait_tries integer, IN p_wait integer, IN p_order text, IN p_source_table text, IN p_ignored_columns text[], IN p_quiet boolean | + pg_partman | partman | partition_data_time | p_parent_table text, p_batch_count integer, p_batch_interval interval, p_lock_wait numeric, p_order text, p_analyze boolean, p_source_table text, p_ignored_columns text[] | bigint + pg_partman | partman | partition_gap_fill | p_parent_table text | integer + pg_partman | partman | reapply_constraints_proc | IN p_parent_table text, IN p_drop_constraints boolean, IN p_apply_constraints boolean, IN p_wait integer, IN p_dryrun boolean | + pg_partman | partman | reapply_privileges | p_parent_table text | void + pg_partman | partman | run_analyze | IN p_skip_locked boolean, IN p_quiet boolean, IN p_parent_table text | + pg_partman | partman | run_maintenance | p_parent_table text, p_analyze boolean, p_jobmon boolean | void + pg_partman | partman | run_maintenance_proc | IN p_wait integer, IN p_analyze boolean, IN p_jobmon boolean | + pg_partman | partman | show_partition_info | p_child_table text, p_partition_interval text, p_parent_table text, OUT child_start_time timestamp with time zone, OUT child_end_time timestamp with time zone, OUT child_start_id bigint, OUT child_end_id bigint, OUT suffix text | record + pg_partman | partman | show_partition_name | p_parent_table text, p_value text, OUT partition_schema text, OUT partition_table text, OUT suffix_timestamp timestamp with time zone, OUT suffix_id bigint, OUT table_exists boolean | record + pg_partman | partman | show_partitions | p_parent_table text, p_order text, p_include_default boolean | TABLE(partition_schemaname text, partition_tablename text) + pg_partman | partman | stop_sub_partition | p_parent_table text, p_jobmon boolean | boolean + pg_partman | partman | undo_partition | p_parent_table text, p_target_table text, p_loop_count integer, p_batch_interval text, p_keep_table boolean, p_lock_wait numeric, p_ignored_columns text[], p_drop_cascade boolean, OUT partitions_undone integer, OUT rows_undone bigint | record + pg_partman | partman | undo_partition_proc | IN p_parent_table text, IN p_target_table text, IN p_loop_count integer, IN p_interval text, IN p_keep_table boolean, IN p_lock_wait integer, IN p_lock_wait_tries integer, IN p_wait integer, IN p_ignored_columns text[], IN p_drop_cascade boolean, IN p_quiet boolean | + pg_partman | partman | uuid7_time_decoder | uuidv7 text | timestamp with time zone + pg_partman | partman | uuid7_time_encoder | ts timestamp with time zone | uuid pg_prewarm | public | autoprewarm_dump_now | | bigint pg_prewarm | public | autoprewarm_start_worker | | void pg_prewarm | public | pg_prewarm | regclass, mode text, fork text, first_block bigint, last_block bigint | bigint @@ -5241,7 +5283,7 @@ order by xml2 | public | xpath_table | text, text, text, text, text | SETOF record xml2 | public | xslt_process | text, text | text xml2 | public | xslt_process | text, text, text | text -(5071 rows) +(5112 rows) /* @@ -5324,6 +5366,65 @@ order by pg_net | net | http_request_queue | method pg_net | net | http_request_queue | timeout_milliseconds pg_net | net | http_request_queue | url + pg_partman | partman | part_config | automatic_maintenance + pg_partman | partman | part_config | constraint_cols + pg_partman | partman | part_config | constraint_valid + pg_partman | partman | part_config | control + pg_partman | partman | part_config | date_trunc_interval + pg_partman | partman | part_config | datetime_string + pg_partman | partman | part_config | epoch + pg_partman | partman | part_config | ignore_default_data + pg_partman | partman | part_config | infinite_time_partitions + pg_partman | partman | part_config | inherit_privileges + pg_partman | partman | part_config | jobmon + pg_partman | partman | part_config | maintenance_last_run + pg_partman | partman | part_config | maintenance_order + pg_partman | partman | part_config | optimize_constraint + pg_partman | partman | part_config | parent_table + pg_partman | partman | part_config | partition_interval + pg_partman | partman | part_config | partition_type + pg_partman | partman | part_config | premake + pg_partman | partman | part_config | retention + pg_partman | partman | part_config | retention_keep_index + pg_partman | partman | part_config | retention_keep_publication + pg_partman | partman | part_config | retention_keep_table + pg_partman | partman | part_config | retention_schema + pg_partman | partman | part_config | sub_partition_set_full + pg_partman | partman | part_config | template_table + pg_partman | partman | part_config | time_decoder + pg_partman | partman | part_config | time_encoder + pg_partman | partman | part_config | undo_in_progress + pg_partman | partman | part_config_sub | sub_automatic_maintenance + pg_partman | partman | part_config_sub | sub_constraint_cols + pg_partman | partman | part_config_sub | sub_constraint_valid + pg_partman | partman | part_config_sub | sub_control + pg_partman | partman | part_config_sub | sub_control_not_null + pg_partman | partman | part_config_sub | sub_date_trunc_interval + pg_partman | partman | part_config_sub | sub_default_table + pg_partman | partman | part_config_sub | sub_epoch + pg_partman | partman | part_config_sub | sub_ignore_default_data + pg_partman | partman | part_config_sub | sub_infinite_time_partitions + pg_partman | partman | part_config_sub | sub_inherit_privileges + pg_partman | partman | part_config_sub | sub_jobmon + pg_partman | partman | part_config_sub | sub_maintenance_order + pg_partman | partman | part_config_sub | sub_optimize_constraint + pg_partman | partman | part_config_sub | sub_parent + pg_partman | partman | part_config_sub | sub_partition_interval + pg_partman | partman | part_config_sub | sub_partition_type + pg_partman | partman | part_config_sub | sub_premake + pg_partman | partman | part_config_sub | sub_retention + pg_partman | partman | part_config_sub | sub_retention_keep_index + pg_partman | partman | part_config_sub | sub_retention_keep_publication + pg_partman | partman | part_config_sub | sub_retention_keep_table + pg_partman | partman | part_config_sub | sub_retention_schema + pg_partman | partman | part_config_sub | sub_template_table + pg_partman | partman | part_config_sub | sub_time_decoder + pg_partman | partman | part_config_sub | sub_time_encoder + pg_partman | partman | table_privs | grantee + pg_partman | partman | table_privs | grantor + pg_partman | partman | table_privs | privilege_type + pg_partman | partman | table_privs | table_name + pg_partman | partman | table_privs | table_schema pg_repack | repack | primary_keys | indexrelid pg_repack | repack | primary_keys | indrelid pg_repack | repack | tables | alter_col_storage @@ -6383,5 +6484,5 @@ order by wrappers | public | wrappers_fdw_stats | rows_in wrappers | public | wrappers_fdw_stats | rows_out wrappers | public | wrappers_fdw_stats | updated_at -(1108 rows) +(1167 rows) diff --git a/nix/tests/expected/z_15_unhype_timescale_to_partman.out b/nix/tests/expected/z_15_unhype_timescale_to_partman.out new file mode 100644 index 000000000..fa4eb37dc --- /dev/null +++ b/nix/tests/expected/z_15_unhype_timescale_to_partman.out @@ -0,0 +1,77 @@ +/* + +The purpose of this test is to validate the method of moving from Timescale Hypertables to Postgres native partitioned tables +managed by pg_partman + +*/ +CREATE SCHEMA ts; +-- Create a table for time-series data +CREATE TABLE ts.readings ( + time TIMESTAMPTZ NOT NULL, + sensor_id INT NOT NULL, + value DOUBLE PRECISION NOT NULL +); +-- Convert the table into a hypertable +SELECT create_hypertable('ts.readings', by_range('time', INTERVAL '1 day')); + create_hypertable +------------------- + (2,t) +(1 row) + +-- Convert default 7 day chunk interval +SELECT set_chunk_time_interval('ts.readings', INTERVAL '24 hours'); + set_chunk_time_interval +------------------------- + +(1 row) + +-- Insert sample data +INSERT INTO ts.readings (time, sensor_id, value) +SELECT + time_series AS time, + FLOOR(RANDOM() * 10 + 1)::INT AS sensor_id, -- Random sensor_id between 1 and 10 + RANDOM() * 100 AS value -- Random value between 0 and 100 +FROM + generate_series( + '2023-01-19 00:00:00+00'::TIMESTAMPTZ, + '2025-03-26 03:00:00+00'::TIMESTAMPTZ, + INTERVAL '1 second' + ) AS time_series +LIMIT 600000; +-- List hypertables +SELECT * FROM timescaledb_information.hypertables; + hypertable_schema | hypertable_name | owner | num_dimensions | num_chunks | compression_enabled | tablespaces +-------------------+-----------------+----------------+----------------+------------+---------------------+------------- + ts | readings | supabase_admin | 1 | 7 | f | +(1 row) + +-- Rename hypertable +ALTER TABLE ts.readings RENAME TO ht_readings; +-- Create copy of hypertable with original name +CREATE TABLE ts.readings (LIKE ts.ht_readings) PARTITION BY RANGE(time); +-- Configure pg_partman for daily partitions on sensor_data +SELECT partman.create_parent( + p_parent_table := 'ts.readings', + p_control := 'time', + p_type := 'range', + p_interval := '1 day', + p_premake := 7, -- Create partitions for the next 7 days + p_start_partition := '2023-01-19 00:00:00+00' -- Start date for partitioning +); + create_parent +--------------- + t +(1 row) + +INSERT INTO ts.readings SELECT * FROM ts.ht_readings; +DROP SCHEMA ts CASCADE; +NOTICE: drop cascades to 9 other objects +DETAIL: drop cascades to table ts.ht_readings +drop cascades to table _timescaledb_internal._hyper_2_3_chunk +drop cascades to table _timescaledb_internal._hyper_2_4_chunk +drop cascades to table _timescaledb_internal._hyper_2_5_chunk +drop cascades to table _timescaledb_internal._hyper_2_6_chunk +drop cascades to table _timescaledb_internal._hyper_2_7_chunk +drop cascades to table _timescaledb_internal._hyper_2_8_chunk +drop cascades to table _timescaledb_internal._hyper_2_9_chunk +drop cascades to table ts.readings diff --git a/nix/tests/expected/z_17_ext_interface.out b/nix/tests/expected/z_17_ext_interface.out index 6a7b4a16c..89fc4c1bc 100644 --- a/nix/tests/expected/z_17_ext_interface.out +++ b/nix/tests/expected/z_17_ext_interface.out @@ -76,6 +76,7 @@ order by pg_hashids | t pg_jsonschema | f pg_net | f + pg_partman | f pg_prewarm | t pg_repack | f pg_stat_monitor | t @@ -115,7 +116,7 @@ order by vector | t wrappers | t xml2 | f -(72 rows) +(73 rows) /* @@ -155,8 +156,8 @@ order by n.nspname, p.proname, md5(pg_catalog.pg_get_function_identity_arguments(p.oid)); - extension_name | schema_name | function_name | argument_types | return_type -----------------------+----------------+--------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + extension_name | schema_name | function_name | argument_types | return_type +----------------------+----------------+--------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ address_standardizer | public | parse_address | text, OUT num text, OUT street text, OUT street2 text, OUT address1 text, OUT city text, OUT state text, OUT zip text, OUT zipplus text, OUT country text | record address_standardizer | public | standardize_address | lextab text, gaztab text, rultab text, address text | stdaddr address_standardizer | public | standardize_address | lextab text, gaztab text, rultab text, micro text, macro text | stdaddr @@ -1152,6 +1153,47 @@ order by pg_net | net | wait_until_running | | void pg_net | net | wake | | void pg_net | net | worker_restart | | boolean + pg_partman | partman | apply_cluster | p_parent_schema text, p_parent_tablename text, p_child_schema text, p_child_tablename text | void + pg_partman | partman | apply_constraints | p_parent_table text, p_child_table text, p_analyze boolean, p_job_id bigint | void + pg_partman | partman | apply_privileges | p_parent_schema text, p_parent_tablename text, p_child_schema text, p_child_tablename text, p_job_id bigint | void + pg_partman | partman | autovacuum_off | p_parent_schema text, p_parent_tablename text, p_source_schema text, p_source_tablename text | boolean + pg_partman | partman | autovacuum_reset | p_parent_schema text, p_parent_tablename text, p_source_schema text, p_source_tablename text | boolean + pg_partman | partman | calculate_time_partition_info | p_time_interval interval, p_start_time timestamp with time zone, p_date_trunc_interval text, OUT base_timestamp timestamp with time zone, OUT datetime_string text | record + pg_partman | partman | check_automatic_maintenance_value | p_automatic_maintenance text | boolean + pg_partman | partman | check_control_type | p_parent_schema text, p_parent_tablename text, p_control text | TABLE(general_type text, exact_type text) + pg_partman | partman | check_default | p_exact_count boolean | SETOF partman.check_default_table + pg_partman | partman | check_epoch_type | p_type text | boolean + pg_partman | partman | check_name_length | p_object_name text, p_suffix text, p_table_partition boolean | text + pg_partman | partman | check_partition_type | p_type text | boolean + pg_partman | partman | check_subpart_sameconfig | p_parent_table text | TABLE(sub_control text, sub_partition_interval text, sub_partition_type text, sub_premake integer, sub_automatic_maintenance text, sub_template_table text, sub_retention text, sub_retention_schema text, sub_retention_keep_index boolean, sub_retention_keep_table boolean, sub_epoch text, sub_constraint_cols text[], sub_optimize_constraint integer, sub_infinite_time_partitions boolean, sub_jobmon boolean, sub_inherit_privileges boolean, sub_constraint_valid boolean, sub_date_trunc_interval text, sub_ignore_default_data boolean, sub_default_table boolean, sub_maintenance_order integer, sub_retention_keep_publication boolean, sub_control_not_null boolean) + pg_partman | partman | check_subpartition_limits | p_parent_table text, p_type text, OUT sub_min text, OUT sub_max text | record + pg_partman | partman | create_parent | p_parent_table text, p_control text, p_interval text, p_type text, p_epoch text, p_premake integer, p_start_partition text, p_default_table boolean, p_automatic_maintenance text, p_constraint_cols text[], p_template_table text, p_jobmon boolean, p_date_trunc_interval text, p_control_not_null boolean, p_time_encoder text, p_time_decoder text | boolean + pg_partman | partman | create_partition_id | p_parent_table text, p_partition_ids bigint[], p_start_partition text | boolean + pg_partman | partman | create_partition_time | p_parent_table text, p_partition_times timestamp with time zone[], p_start_partition text | boolean + pg_partman | partman | create_sub_parent | p_top_parent text, p_control text, p_interval text, p_type text, p_default_table boolean, p_declarative_check text, p_constraint_cols text[], p_premake integer, p_start_partition text, p_epoch text, p_jobmon boolean, p_date_trunc_interval text, p_control_not_null boolean, p_time_encoder text, p_time_decoder text | boolean + pg_partman | partman | drop_constraints | p_parent_table text, p_child_table text, p_debug boolean | void + pg_partman | partman | drop_partition_id | p_parent_table text, p_retention bigint, p_keep_table boolean, p_keep_index boolean, p_retention_schema text | integer + pg_partman | partman | drop_partition_time | p_parent_table text, p_retention interval, p_keep_table boolean, p_keep_index boolean, p_retention_schema text, p_reference_timestamp timestamp with time zone | integer + pg_partman | partman | dump_partitioned_table_definition | p_parent_table text, p_ignore_template_table boolean | text + pg_partman | partman | inherit_replica_identity | p_parent_schemaname text, p_parent_tablename text, p_child_tablename text | void + pg_partman | partman | inherit_template_properties | p_parent_table text, p_child_schema text, p_child_tablename text | boolean + pg_partman | partman | partition_data_id | p_parent_table text, p_batch_count integer, p_batch_interval bigint, p_lock_wait numeric, p_order text, p_analyze boolean, p_source_table text, p_ignored_columns text[] | bigint + pg_partman | partman | partition_data_proc | IN p_parent_table text, IN p_loop_count integer, IN p_interval text, IN p_lock_wait integer, IN p_lock_wait_tries integer, IN p_wait integer, IN p_order text, IN p_source_table text, IN p_ignored_columns text[], IN p_quiet boolean | + pg_partman | partman | partition_data_time | p_parent_table text, p_batch_count integer, p_batch_interval interval, p_lock_wait numeric, p_order text, p_analyze boolean, p_source_table text, p_ignored_columns text[] | bigint + pg_partman | partman | partition_gap_fill | p_parent_table text | integer + pg_partman | partman | reapply_constraints_proc | IN p_parent_table text, IN p_drop_constraints boolean, IN p_apply_constraints boolean, IN p_wait integer, IN p_dryrun boolean | + pg_partman | partman | reapply_privileges | p_parent_table text | void + pg_partman | partman | run_analyze | IN p_skip_locked boolean, IN p_quiet boolean, IN p_parent_table text | + pg_partman | partman | run_maintenance | p_parent_table text, p_analyze boolean, p_jobmon boolean | void + pg_partman | partman | run_maintenance_proc | IN p_wait integer, IN p_analyze boolean, IN p_jobmon boolean | + pg_partman | partman | show_partition_info | p_child_table text, p_partition_interval text, p_parent_table text, OUT child_start_time timestamp with time zone, OUT child_end_time timestamp with time zone, OUT child_start_id bigint, OUT child_end_id bigint, OUT suffix text | record + pg_partman | partman | show_partition_name | p_parent_table text, p_value text, OUT partition_schema text, OUT partition_table text, OUT suffix_timestamp timestamp with time zone, OUT suffix_id bigint, OUT table_exists boolean | record + pg_partman | partman | show_partitions | p_parent_table text, p_order text, p_include_default boolean | TABLE(partition_schemaname text, partition_tablename text) + pg_partman | partman | stop_sub_partition | p_parent_table text, p_jobmon boolean | boolean + pg_partman | partman | undo_partition | p_parent_table text, p_target_table text, p_loop_count integer, p_batch_interval text, p_keep_table boolean, p_lock_wait numeric, p_ignored_columns text[], p_drop_cascade boolean, OUT partitions_undone integer, OUT rows_undone bigint | record + pg_partman | partman | undo_partition_proc | IN p_parent_table text, IN p_target_table text, IN p_loop_count integer, IN p_interval text, IN p_keep_table boolean, IN p_lock_wait integer, IN p_lock_wait_tries integer, IN p_wait integer, IN p_ignored_columns text[], IN p_drop_cascade boolean, IN p_quiet boolean | + pg_partman | partman | uuid7_time_decoder | uuidv7 text | timestamp with time zone + pg_partman | partman | uuid7_time_encoder | ts timestamp with time zone | uuid pg_prewarm | public | autoprewarm_dump_now | | bigint pg_prewarm | public | autoprewarm_start_worker | | void pg_prewarm | public | pg_prewarm | regclass, mode text, fork text, first_block bigint, last_block bigint | bigint @@ -4885,7 +4927,7 @@ order by xml2 | public | xpath_table | text, text, text, text, text | SETOF record xml2 | public | xslt_process | text, text | text xml2 | public | xslt_process | text, text, text | text -(4728 rows) +(4769 rows) /* @@ -4917,8 +4959,8 @@ order by n.nspname, pc.relname, pa.attname; - extension_name | schema_name | entity_name | attname -------------------------------+-------------+-------------------------+------------------------ + extension_name | schema_name | entity_name | attname +------------------------------+-------------+-------------------------+-------------------------------- address_standardizer_data_us | public | us_gaz | id address_standardizer_data_us | public | us_gaz | is_custom address_standardizer_data_us | public | us_gaz | seq @@ -4968,6 +5010,65 @@ order by pg_net | net | http_request_queue | method pg_net | net | http_request_queue | timeout_milliseconds pg_net | net | http_request_queue | url + pg_partman | partman | part_config | automatic_maintenance + pg_partman | partman | part_config | constraint_cols + pg_partman | partman | part_config | constraint_valid + pg_partman | partman | part_config | control + pg_partman | partman | part_config | date_trunc_interval + pg_partman | partman | part_config | datetime_string + pg_partman | partman | part_config | epoch + pg_partman | partman | part_config | ignore_default_data + pg_partman | partman | part_config | infinite_time_partitions + pg_partman | partman | part_config | inherit_privileges + pg_partman | partman | part_config | jobmon + pg_partman | partman | part_config | maintenance_last_run + pg_partman | partman | part_config | maintenance_order + pg_partman | partman | part_config | optimize_constraint + pg_partman | partman | part_config | parent_table + pg_partman | partman | part_config | partition_interval + pg_partman | partman | part_config | partition_type + pg_partman | partman | part_config | premake + pg_partman | partman | part_config | retention + pg_partman | partman | part_config | retention_keep_index + pg_partman | partman | part_config | retention_keep_publication + pg_partman | partman | part_config | retention_keep_table + pg_partman | partman | part_config | retention_schema + pg_partman | partman | part_config | sub_partition_set_full + pg_partman | partman | part_config | template_table + pg_partman | partman | part_config | time_decoder + pg_partman | partman | part_config | time_encoder + pg_partman | partman | part_config | undo_in_progress + pg_partman | partman | part_config_sub | sub_automatic_maintenance + pg_partman | partman | part_config_sub | sub_constraint_cols + pg_partman | partman | part_config_sub | sub_constraint_valid + pg_partman | partman | part_config_sub | sub_control + pg_partman | partman | part_config_sub | sub_control_not_null + pg_partman | partman | part_config_sub | sub_date_trunc_interval + pg_partman | partman | part_config_sub | sub_default_table + pg_partman | partman | part_config_sub | sub_epoch + pg_partman | partman | part_config_sub | sub_ignore_default_data + pg_partman | partman | part_config_sub | sub_infinite_time_partitions + pg_partman | partman | part_config_sub | sub_inherit_privileges + pg_partman | partman | part_config_sub | sub_jobmon + pg_partman | partman | part_config_sub | sub_maintenance_order + pg_partman | partman | part_config_sub | sub_optimize_constraint + pg_partman | partman | part_config_sub | sub_parent + pg_partman | partman | part_config_sub | sub_partition_interval + pg_partman | partman | part_config_sub | sub_partition_type + pg_partman | partman | part_config_sub | sub_premake + pg_partman | partman | part_config_sub | sub_retention + pg_partman | partman | part_config_sub | sub_retention_keep_index + pg_partman | partman | part_config_sub | sub_retention_keep_publication + pg_partman | partman | part_config_sub | sub_retention_keep_table + pg_partman | partman | part_config_sub | sub_retention_schema + pg_partman | partman | part_config_sub | sub_template_table + pg_partman | partman | part_config_sub | sub_time_decoder + pg_partman | partman | part_config_sub | sub_time_encoder + pg_partman | partman | table_privs | grantee + pg_partman | partman | table_privs | grantor + pg_partman | partman | table_privs | privilege_type + pg_partman | partman | table_privs | table_name + pg_partman | partman | table_privs | table_schema pg_repack | repack | primary_keys | indexrelid pg_repack | repack | primary_keys | indrelid pg_repack | repack | tables | alter_col_storage @@ -5308,5 +5409,5 @@ order by wrappers | public | wrappers_fdw_stats | rows_in wrappers | public | wrappers_fdw_stats | rows_out wrappers | public | wrappers_fdw_stats | updated_at -(389 rows) +(448 rows) diff --git a/nix/tests/expected/z_orioledb-17_ext_interface.out b/nix/tests/expected/z_orioledb-17_ext_interface.out index 6a7b4a16c..89fc4c1bc 100644 --- a/nix/tests/expected/z_orioledb-17_ext_interface.out +++ b/nix/tests/expected/z_orioledb-17_ext_interface.out @@ -76,6 +76,7 @@ order by pg_hashids | t pg_jsonschema | f pg_net | f + pg_partman | f pg_prewarm | t pg_repack | f pg_stat_monitor | t @@ -115,7 +116,7 @@ order by vector | t wrappers | t xml2 | f -(72 rows) +(73 rows) /* @@ -155,8 +156,8 @@ order by n.nspname, p.proname, md5(pg_catalog.pg_get_function_identity_arguments(p.oid)); - extension_name | schema_name | function_name | argument_types | return_type -----------------------+----------------+--------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + extension_name | schema_name | function_name | argument_types | return_type +----------------------+----------------+--------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ address_standardizer | public | parse_address | text, OUT num text, OUT street text, OUT street2 text, OUT address1 text, OUT city text, OUT state text, OUT zip text, OUT zipplus text, OUT country text | record address_standardizer | public | standardize_address | lextab text, gaztab text, rultab text, address text | stdaddr address_standardizer | public | standardize_address | lextab text, gaztab text, rultab text, micro text, macro text | stdaddr @@ -1152,6 +1153,47 @@ order by pg_net | net | wait_until_running | | void pg_net | net | wake | | void pg_net | net | worker_restart | | boolean + pg_partman | partman | apply_cluster | p_parent_schema text, p_parent_tablename text, p_child_schema text, p_child_tablename text | void + pg_partman | partman | apply_constraints | p_parent_table text, p_child_table text, p_analyze boolean, p_job_id bigint | void + pg_partman | partman | apply_privileges | p_parent_schema text, p_parent_tablename text, p_child_schema text, p_child_tablename text, p_job_id bigint | void + pg_partman | partman | autovacuum_off | p_parent_schema text, p_parent_tablename text, p_source_schema text, p_source_tablename text | boolean + pg_partman | partman | autovacuum_reset | p_parent_schema text, p_parent_tablename text, p_source_schema text, p_source_tablename text | boolean + pg_partman | partman | calculate_time_partition_info | p_time_interval interval, p_start_time timestamp with time zone, p_date_trunc_interval text, OUT base_timestamp timestamp with time zone, OUT datetime_string text | record + pg_partman | partman | check_automatic_maintenance_value | p_automatic_maintenance text | boolean + pg_partman | partman | check_control_type | p_parent_schema text, p_parent_tablename text, p_control text | TABLE(general_type text, exact_type text) + pg_partman | partman | check_default | p_exact_count boolean | SETOF partman.check_default_table + pg_partman | partman | check_epoch_type | p_type text | boolean + pg_partman | partman | check_name_length | p_object_name text, p_suffix text, p_table_partition boolean | text + pg_partman | partman | check_partition_type | p_type text | boolean + pg_partman | partman | check_subpart_sameconfig | p_parent_table text | TABLE(sub_control text, sub_partition_interval text, sub_partition_type text, sub_premake integer, sub_automatic_maintenance text, sub_template_table text, sub_retention text, sub_retention_schema text, sub_retention_keep_index boolean, sub_retention_keep_table boolean, sub_epoch text, sub_constraint_cols text[], sub_optimize_constraint integer, sub_infinite_time_partitions boolean, sub_jobmon boolean, sub_inherit_privileges boolean, sub_constraint_valid boolean, sub_date_trunc_interval text, sub_ignore_default_data boolean, sub_default_table boolean, sub_maintenance_order integer, sub_retention_keep_publication boolean, sub_control_not_null boolean) + pg_partman | partman | check_subpartition_limits | p_parent_table text, p_type text, OUT sub_min text, OUT sub_max text | record + pg_partman | partman | create_parent | p_parent_table text, p_control text, p_interval text, p_type text, p_epoch text, p_premake integer, p_start_partition text, p_default_table boolean, p_automatic_maintenance text, p_constraint_cols text[], p_template_table text, p_jobmon boolean, p_date_trunc_interval text, p_control_not_null boolean, p_time_encoder text, p_time_decoder text | boolean + pg_partman | partman | create_partition_id | p_parent_table text, p_partition_ids bigint[], p_start_partition text | boolean + pg_partman | partman | create_partition_time | p_parent_table text, p_partition_times timestamp with time zone[], p_start_partition text | boolean + pg_partman | partman | create_sub_parent | p_top_parent text, p_control text, p_interval text, p_type text, p_default_table boolean, p_declarative_check text, p_constraint_cols text[], p_premake integer, p_start_partition text, p_epoch text, p_jobmon boolean, p_date_trunc_interval text, p_control_not_null boolean, p_time_encoder text, p_time_decoder text | boolean + pg_partman | partman | drop_constraints | p_parent_table text, p_child_table text, p_debug boolean | void + pg_partman | partman | drop_partition_id | p_parent_table text, p_retention bigint, p_keep_table boolean, p_keep_index boolean, p_retention_schema text | integer + pg_partman | partman | drop_partition_time | p_parent_table text, p_retention interval, p_keep_table boolean, p_keep_index boolean, p_retention_schema text, p_reference_timestamp timestamp with time zone | integer + pg_partman | partman | dump_partitioned_table_definition | p_parent_table text, p_ignore_template_table boolean | text + pg_partman | partman | inherit_replica_identity | p_parent_schemaname text, p_parent_tablename text, p_child_tablename text | void + pg_partman | partman | inherit_template_properties | p_parent_table text, p_child_schema text, p_child_tablename text | boolean + pg_partman | partman | partition_data_id | p_parent_table text, p_batch_count integer, p_batch_interval bigint, p_lock_wait numeric, p_order text, p_analyze boolean, p_source_table text, p_ignored_columns text[] | bigint + pg_partman | partman | partition_data_proc | IN p_parent_table text, IN p_loop_count integer, IN p_interval text, IN p_lock_wait integer, IN p_lock_wait_tries integer, IN p_wait integer, IN p_order text, IN p_source_table text, IN p_ignored_columns text[], IN p_quiet boolean | + pg_partman | partman | partition_data_time | p_parent_table text, p_batch_count integer, p_batch_interval interval, p_lock_wait numeric, p_order text, p_analyze boolean, p_source_table text, p_ignored_columns text[] | bigint + pg_partman | partman | partition_gap_fill | p_parent_table text | integer + pg_partman | partman | reapply_constraints_proc | IN p_parent_table text, IN p_drop_constraints boolean, IN p_apply_constraints boolean, IN p_wait integer, IN p_dryrun boolean | + pg_partman | partman | reapply_privileges | p_parent_table text | void + pg_partman | partman | run_analyze | IN p_skip_locked boolean, IN p_quiet boolean, IN p_parent_table text | + pg_partman | partman | run_maintenance | p_parent_table text, p_analyze boolean, p_jobmon boolean | void + pg_partman | partman | run_maintenance_proc | IN p_wait integer, IN p_analyze boolean, IN p_jobmon boolean | + pg_partman | partman | show_partition_info | p_child_table text, p_partition_interval text, p_parent_table text, OUT child_start_time timestamp with time zone, OUT child_end_time timestamp with time zone, OUT child_start_id bigint, OUT child_end_id bigint, OUT suffix text | record + pg_partman | partman | show_partition_name | p_parent_table text, p_value text, OUT partition_schema text, OUT partition_table text, OUT suffix_timestamp timestamp with time zone, OUT suffix_id bigint, OUT table_exists boolean | record + pg_partman | partman | show_partitions | p_parent_table text, p_order text, p_include_default boolean | TABLE(partition_schemaname text, partition_tablename text) + pg_partman | partman | stop_sub_partition | p_parent_table text, p_jobmon boolean | boolean + pg_partman | partman | undo_partition | p_parent_table text, p_target_table text, p_loop_count integer, p_batch_interval text, p_keep_table boolean, p_lock_wait numeric, p_ignored_columns text[], p_drop_cascade boolean, OUT partitions_undone integer, OUT rows_undone bigint | record + pg_partman | partman | undo_partition_proc | IN p_parent_table text, IN p_target_table text, IN p_loop_count integer, IN p_interval text, IN p_keep_table boolean, IN p_lock_wait integer, IN p_lock_wait_tries integer, IN p_wait integer, IN p_ignored_columns text[], IN p_drop_cascade boolean, IN p_quiet boolean | + pg_partman | partman | uuid7_time_decoder | uuidv7 text | timestamp with time zone + pg_partman | partman | uuid7_time_encoder | ts timestamp with time zone | uuid pg_prewarm | public | autoprewarm_dump_now | | bigint pg_prewarm | public | autoprewarm_start_worker | | void pg_prewarm | public | pg_prewarm | regclass, mode text, fork text, first_block bigint, last_block bigint | bigint @@ -4885,7 +4927,7 @@ order by xml2 | public | xpath_table | text, text, text, text, text | SETOF record xml2 | public | xslt_process | text, text | text xml2 | public | xslt_process | text, text, text | text -(4728 rows) +(4769 rows) /* @@ -4917,8 +4959,8 @@ order by n.nspname, pc.relname, pa.attname; - extension_name | schema_name | entity_name | attname -------------------------------+-------------+-------------------------+------------------------ + extension_name | schema_name | entity_name | attname +------------------------------+-------------+-------------------------+-------------------------------- address_standardizer_data_us | public | us_gaz | id address_standardizer_data_us | public | us_gaz | is_custom address_standardizer_data_us | public | us_gaz | seq @@ -4968,6 +5010,65 @@ order by pg_net | net | http_request_queue | method pg_net | net | http_request_queue | timeout_milliseconds pg_net | net | http_request_queue | url + pg_partman | partman | part_config | automatic_maintenance + pg_partman | partman | part_config | constraint_cols + pg_partman | partman | part_config | constraint_valid + pg_partman | partman | part_config | control + pg_partman | partman | part_config | date_trunc_interval + pg_partman | partman | part_config | datetime_string + pg_partman | partman | part_config | epoch + pg_partman | partman | part_config | ignore_default_data + pg_partman | partman | part_config | infinite_time_partitions + pg_partman | partman | part_config | inherit_privileges + pg_partman | partman | part_config | jobmon + pg_partman | partman | part_config | maintenance_last_run + pg_partman | partman | part_config | maintenance_order + pg_partman | partman | part_config | optimize_constraint + pg_partman | partman | part_config | parent_table + pg_partman | partman | part_config | partition_interval + pg_partman | partman | part_config | partition_type + pg_partman | partman | part_config | premake + pg_partman | partman | part_config | retention + pg_partman | partman | part_config | retention_keep_index + pg_partman | partman | part_config | retention_keep_publication + pg_partman | partman | part_config | retention_keep_table + pg_partman | partman | part_config | retention_schema + pg_partman | partman | part_config | sub_partition_set_full + pg_partman | partman | part_config | template_table + pg_partman | partman | part_config | time_decoder + pg_partman | partman | part_config | time_encoder + pg_partman | partman | part_config | undo_in_progress + pg_partman | partman | part_config_sub | sub_automatic_maintenance + pg_partman | partman | part_config_sub | sub_constraint_cols + pg_partman | partman | part_config_sub | sub_constraint_valid + pg_partman | partman | part_config_sub | sub_control + pg_partman | partman | part_config_sub | sub_control_not_null + pg_partman | partman | part_config_sub | sub_date_trunc_interval + pg_partman | partman | part_config_sub | sub_default_table + pg_partman | partman | part_config_sub | sub_epoch + pg_partman | partman | part_config_sub | sub_ignore_default_data + pg_partman | partman | part_config_sub | sub_infinite_time_partitions + pg_partman | partman | part_config_sub | sub_inherit_privileges + pg_partman | partman | part_config_sub | sub_jobmon + pg_partman | partman | part_config_sub | sub_maintenance_order + pg_partman | partman | part_config_sub | sub_optimize_constraint + pg_partman | partman | part_config_sub | sub_parent + pg_partman | partman | part_config_sub | sub_partition_interval + pg_partman | partman | part_config_sub | sub_partition_type + pg_partman | partman | part_config_sub | sub_premake + pg_partman | partman | part_config_sub | sub_retention + pg_partman | partman | part_config_sub | sub_retention_keep_index + pg_partman | partman | part_config_sub | sub_retention_keep_publication + pg_partman | partman | part_config_sub | sub_retention_keep_table + pg_partman | partman | part_config_sub | sub_retention_schema + pg_partman | partman | part_config_sub | sub_template_table + pg_partman | partman | part_config_sub | sub_time_decoder + pg_partman | partman | part_config_sub | sub_time_encoder + pg_partman | partman | table_privs | grantee + pg_partman | partman | table_privs | grantor + pg_partman | partman | table_privs | privilege_type + pg_partman | partman | table_privs | table_name + pg_partman | partman | table_privs | table_schema pg_repack | repack | primary_keys | indexrelid pg_repack | repack | primary_keys | indrelid pg_repack | repack | tables | alter_col_storage @@ -5308,5 +5409,5 @@ order by wrappers | public | wrappers_fdw_stats | rows_in wrappers | public | wrappers_fdw_stats | rows_out wrappers | public | wrappers_fdw_stats | updated_at -(389 rows) +(448 rows) diff --git a/nix/tests/prime.sql b/nix/tests/prime.sql index fb724847f..5ae47444e 100644 --- a/nix/tests/prime.sql +++ b/nix/tests/prime.sql @@ -46,6 +46,8 @@ create extension if not exists pg_hashids; create extension if not exists pg_prewarm; create extension if not exists pgmq; create extension if not exists pg_jsonschema; +create schema if not exists partman; +create extension if not exists pg_partman with schema partman; create extension if not exists pg_repack; create extension if not exists pg_stat_monitor; create extension if not exists pg_stat_statements; diff --git a/nix/tests/sql/pg_partman.sql b/nix/tests/sql/pg_partman.sql new file mode 100644 index 000000000..db686b78c --- /dev/null +++ b/nix/tests/sql/pg_partman.sql @@ -0,0 +1,22 @@ +CREATE SCHEMA IF NOT EXISTS partman_test; + +CREATE TABLE partman_test.time_taptest_table + (col1 int, + col2 text default 'stuff', + col3 timestamptz NOT NULL DEFAULT now()) +PARTITION BY RANGE (col3); + +CREATE INDEX ON partman_test.time_taptest_table (col3); + +CREATE TABLE partman_test.time_taptest_table_template (LIKE partman_test.time_taptest_table); + +ALTER TABLE partman_test.time_taptest_table_template ADD PRIMARY KEY (col1); + +SELECT partman.create_parent( + p_parent_table := 'partman_test.time_taptest_table' + , p_control := 'col3' + , p_interval := '1 day' + , p_template_table := 'partman_test.time_taptest_table_template' +); + +DROP SCHEMA partman_test CASCADE; diff --git a/nix/tests/sql/z_15_unhype_timescale_to_partman.sql b/nix/tests/sql/z_15_unhype_timescale_to_partman.sql new file mode 100644 index 000000000..795e3ae54 --- /dev/null +++ b/nix/tests/sql/z_15_unhype_timescale_to_partman.sql @@ -0,0 +1,58 @@ +/* + +The purpose of this test is to validate the method of moving from Timescale Hypertables to Postgres native partitioned tables +managed by pg_partman + +*/ + +CREATE SCHEMA ts; + +-- Create a table for time-series data +CREATE TABLE ts.readings ( + time TIMESTAMPTZ NOT NULL, + sensor_id INT NOT NULL, + value DOUBLE PRECISION NOT NULL +); + +-- Convert the table into a hypertable +SELECT create_hypertable('ts.readings', by_range('time', INTERVAL '1 day')); + +-- Convert default 7 day chunk interval +SELECT set_chunk_time_interval('ts.readings', INTERVAL '24 hours'); + +-- Insert sample data +INSERT INTO ts.readings (time, sensor_id, value) +SELECT + time_series AS time, + FLOOR(RANDOM() * 10 + 1)::INT AS sensor_id, -- Random sensor_id between 1 and 10 + RANDOM() * 100 AS value -- Random value between 0 and 100 +FROM + generate_series( + '2023-01-19 00:00:00+00'::TIMESTAMPTZ, + '2025-03-26 03:00:00+00'::TIMESTAMPTZ, + INTERVAL '1 second' + ) AS time_series +LIMIT 600000; + +-- List hypertables +SELECT * FROM timescaledb_information.hypertables; + +-- Rename hypertable +ALTER TABLE ts.readings RENAME TO ht_readings; + +-- Create copy of hypertable with original name +CREATE TABLE ts.readings (LIKE ts.ht_readings) PARTITION BY RANGE(time); + +-- Configure pg_partman for daily partitions on sensor_data +SELECT partman.create_parent( + p_parent_table := 'ts.readings', + p_control := 'time', + p_type := 'range', + p_interval := '1 day', + p_premake := 7, -- Create partitions for the next 7 days + p_start_partition := '2023-01-19 00:00:00+00' -- Start date for partitioning +); + +INSERT INTO ts.readings SELECT * FROM ts.ht_readings; + +DROP SCHEMA ts CASCADE; \ No newline at end of file