diff --git a/ansible/vars.yml b/ansible/vars.yml index 7c98a794f..543283f72 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.6.0.017-orioledb" - postgres17: "17.6.1.060" - postgres15: "15.14.1.060" + postgresorioledb-17: "17.6.0.018-orioledb" + postgres17: "17.6.1.061" + postgres15: "15.14.1.061" # Non Postgres Extensions pgbouncer_release: 1.19.0 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..809861d52 100644 --- a/nix/ext/pg_partman.nix +++ b/nix/ext/pg_partman.nix @@ -1,38 +1,113 @@ { + pkgs, lib, stdenv, fetchFromGitHub, postgresql, + makeWrapper, + switch-ext-version, }: -stdenv.mkDerivation rec { +let pname = "pg_partman"; - version = "5.1.0"; + libName = "pg_partman_bgw"; + 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/${libName}${postgresql.dlSuffix} $out/lib/${libName}-${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 ${libName}-${latestVersion}${postgresql.dlSuffix} $out/lib/${libName}${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}" --prefix LIB_NAME : "${libName}" ''; - 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 + libName + ; + pname = "${pname}-all"; + hasBackgroundWorker = true; + defaultSchema = "partman"; + defaultSettings = { + shared_preload_libraries = [ libName ]; + }; + 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 facd250f6..a3e67d6da 100644 --- a/nix/ext/tests/default.nix +++ b/nix/ext/tests/default.nix @@ -146,12 +146,16 @@ let "17": [${lib.concatStringsSep ", " (map (s: ''"${s}"'') (versions "17"))}], } extension_name = "${pname}" + support_upgrade = True pg17_configuration = "${pg17-configuration}" ext_has_background_worker = ${ if (installedExtension "15") ? hasBackgroundWorker then "True" else "False" } sql_test_directory = Path("${../../tests}") pg_regress_test_name = "${(installedExtension "15").pgRegressTestName or pname}" + ext_schema = "${(installedExtension "15").defaultSchema or "public"}" + lib_name = "${(installedExtension "15").libName or pname}" + print(f"Running tests for extension: {lib_name}") ${builtins.readFile ./lib.py} @@ -160,7 +164,8 @@ let server.wait_for_unit("multi-user.target") server.wait_for_unit("postgresql.service") - test = PostgresExtensionTest(server, extension_name, versions, sql_test_directory) + 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") @@ -174,7 +179,7 @@ let if ext_has_background_worker: with subtest("Test switch_${pname}_version"): - test.check_switch_extension_with_background_worker(Path("${psql_15}/lib/${pname}.so"), "15") + test.check_switch_extension_with_background_worker(Path(f"${psql_15}/lib/{lib_name}.so"), "15") with subtest("Check pg_regress with postgresql 15 after installing the last version"): test.check_pg_regress(Path("${psql_15}/lib/pgxs/src/test/regress/pg_regress"), "15", pg_regress_test_name) @@ -224,6 +229,7 @@ builtins.listToAttrs ( "pg_stat_monitor" "pg_tle" "pgaudit" + "pg_partman" "vector" "wal2json" "wrappers" diff --git a/nix/ext/tests/lib.py b/nix/ext/tests/lib.py index 42b5eb361..d04f830fd 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 5bfc1f303..b35c6c40b 100644 --- a/nix/ext/versions.json +++ b/nix/ext/versions.json @@ -353,21 +353,31 @@ "hash": "sha256-9St/ESPiFq2NiPKqbwHLwkIyATKUkOGxFcUrWgT+Iqo=" } }, - "pgmq": { - "1.4.4": { - "postgresql": [ - "15" - ], - "hash": "sha256-z+8/BqIlHwlMnuIzMz6eylmYbSmhtsNt7TJf/CxbdVw=" - }, - "1.5.1": { + "pg_partman": { + "5.3.1": { "postgresql": [ "15", - "17" + "17", + "orioledb-17" ], - "hash": "sha256-IU+i6ONPwtgsFKdzya6E+222ualR66gkbb0lDr+7Rb8=" + "hash": "sha256-LK+z/0puUuNLz2ah/SDaxxyLS/On/cmCBhKNwTLa7Pk=" } }, + "pgmq": { + "1.4.4": { + "postgresql": [ + "15" + ], + "hash": "sha256-z+8/BqIlHwlMnuIzMz6eylmYbSmhtsNt7TJf/CxbdVw=" + }, + "1.5.1": { + "postgresql": [ + "15", + "17" + ], + "hash": "sha256-IU+i6ONPwtgsFKdzya6E+222ualR66gkbb0lDr+7Rb8=" + } + }, "pgroonga": { "3.0.7": { "postgresql": [ diff --git a/nix/packages/postgres.nix b/nix/packages/postgres.nix index 2ce9410f6..8472e05fc 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/packages/switch-ext-version.nix b/nix/packages/switch-ext-version.nix index e3d211bbb..3164e9e13 100644 --- a/nix/packages/switch-ext-version.nix +++ b/nix/packages/switch-ext-version.nix @@ -31,28 +31,32 @@ writeShellApplication { echo " NIX_PROFILE - Path to nix profile (default: /var/lib/postgresql/.nix-profile)" echo " LIB_DIR - Override library directory" echo " EXTENSION_DIR - Override extension directory" + echo " LIB_NAME - Override library name" exit 1 fi VERSION="$1" - echo "$VERSION" + + if [ -z "''${LIB_NAME:-}" ]; then + LIB_NAME="$EXT_NAME" + fi # Enable overlay on the wrapper package to be able to switch version ${lib.getExe overlayfs-on-package} "$EXT_WRAPPER" # Check if version exists EXT_WRAPPER_LIB="$EXT_WRAPPER/lib" - EXT_LIB_TO_USE="$EXT_WRAPPER_LIB/$EXT_NAME-$VERSION${postgresql.dlSuffix}" + EXT_LIB_TO_USE="$EXT_WRAPPER_LIB/$LIB_NAME-$VERSION${postgresql.dlSuffix}" if [ ! -f "$EXT_LIB_TO_USE" ]; then echo "Error: Version $VERSION not found in $EXT_WRAPPER_LIB" echo "Available versions:" #shellcheck disable=SC2012 - ls "$EXT_WRAPPER_LIB/$EXT_NAME"-*${postgresql.dlSuffix} 2>/dev/null | sed "s/.*$EXT_NAME-/ /" | sed 's/${postgresql.dlSuffix}$//' || echo " No versions found" + ls "$EXT_WRAPPER_LIB/$LIB_NAME"-*${postgresql.dlSuffix} 2>/dev/null | sed "s/.*$LIB_NAME-/ /" | sed 's/${postgresql.dlSuffix}$//' || echo " No versions found" exit 1 fi # Update library symlink - ln -sfnv "$EXT_LIB_TO_USE" "$EXT_WRAPPER_LIB/$EXT_NAME${postgresql.dlSuffix}" + ln -sfnv "$EXT_LIB_TO_USE" "$EXT_WRAPPER_LIB/$LIB_NAME${postgresql.dlSuffix}" # Handle extension specific steps if [ -x "''${EXTRA_STEPS:-}" ]; then 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 e07b6e60e..c68d84210 100644 --- a/nix/tests/expected/z_15_ext_interface.out +++ b/nix/tests/expected/z_15_ext_interface.out @@ -85,6 +85,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 @@ -129,7 +130,7 @@ order by vector | t wrappers | t xml2 | f -(79 rows) +(80 rows) /* @@ -169,8 +170,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 @@ -1168,6 +1169,48 @@ 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, p_offset_id bigint | 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_async | 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_ignored_columns text[], IN p_quiet 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[], p_override_system_value boolean | 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[], p_override_system_value boolean | 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, p_table_exists boolean, 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 @@ -5250,7 +5293,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 -(5079 rows) +(5121 rows) /* @@ -5333,6 +5376,66 @@ 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 | async_partitioning_in_progress + 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 @@ -6392,5 +6495,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) +(1168 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 0d932ec2c..1b09ed17e 100644 --- a/nix/tests/expected/z_17_ext_interface.out +++ b/nix/tests/expected/z_17_ext_interface.out @@ -77,6 +77,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 @@ -116,7 +117,7 @@ order by vector | t wrappers | t xml2 | f -(72 rows) +(73 rows) /* @@ -156,8 +157,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 @@ -1153,6 +1154,48 @@ 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, p_offset_id bigint | 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_async | 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_ignored_columns text[], IN p_quiet 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[], p_override_system_value boolean | 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[], p_override_system_value boolean | 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, p_table_exists boolean, 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 @@ -4894,7 +4937,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 -(4736 rows) +(4778 rows) /* @@ -4926,8 +4969,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 @@ -4977,6 +5020,66 @@ 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 | async_partitioning_in_progress + 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 @@ -5317,5 +5420,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) +(449 rows) diff --git a/nix/tests/expected/z_orioledb-17_ext_interface.out b/nix/tests/expected/z_orioledb-17_ext_interface.out index 0d932ec2c..1b09ed17e 100644 --- a/nix/tests/expected/z_orioledb-17_ext_interface.out +++ b/nix/tests/expected/z_orioledb-17_ext_interface.out @@ -77,6 +77,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 @@ -116,7 +117,7 @@ order by vector | t wrappers | t xml2 | f -(72 rows) +(73 rows) /* @@ -156,8 +157,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 @@ -1153,6 +1154,48 @@ 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, p_offset_id bigint | 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_async | 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_ignored_columns text[], IN p_quiet 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[], p_override_system_value boolean | 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[], p_override_system_value boolean | 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, p_table_exists boolean, 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 @@ -4894,7 +4937,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 -(4736 rows) +(4778 rows) /* @@ -4926,8 +4969,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 @@ -4977,6 +5020,66 @@ 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 | async_partitioning_in_progress + 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 @@ -5317,5 +5420,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) +(449 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