Disallow infinite values for partition interval in create_time_partitions udf (#7822)

PG17 added +/- infinity values for the interval data type
Relevant PG commit:
https://github.com/postgres/postgres/commit/519fc1bd9
pull/7820/head
Naisila Puka 2024-12-30 20:27:28 +03:00 committed by GitHub
parent 9e3c3297fc
commit 7dc97d3dc9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 95 additions and 0 deletions

View File

@ -2,3 +2,4 @@
-- bump version to 13.0-1
#include "udfs/citus_prepare_pg_upgrade/13.0-1.sql"
#include "udfs/create_time_partitions/13.0-1.sql"

View File

@ -1,2 +1,4 @@
-- citus--13.0-1--12.1-1
-- this is an empty downgrade path since citus--12.1-1--13.0-1.sql is empty
#include "../udfs/create_time_partitions/10.2-1.sql"

View File

@ -0,0 +1,58 @@
CREATE OR REPLACE FUNCTION pg_catalog.create_time_partitions(
table_name regclass,
partition_interval INTERVAL,
end_at timestamptz,
start_from timestamptz DEFAULT now())
returns boolean
LANGUAGE plpgsql
AS $$
DECLARE
-- partitioned table name
schema_name_text name;
table_name_text name;
-- record for to-be-created partition
missing_partition_record record;
-- result indiciates whether any partitions were created
partition_created bool := false;
BEGIN
IF start_from >= end_at THEN
RAISE 'start_from (%) must be older than end_at (%)', start_from, end_at;
END IF;
IF NOT isfinite(partition_interval) THEN
RAISE 'Partition interval must be a finite value';
END IF;
SELECT nspname, relname
INTO schema_name_text, table_name_text
FROM pg_class JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid
WHERE pg_class.oid = table_name::oid;
-- Get missing partition range info using the get_missing_partition_ranges
-- and create partitions using that info.
FOR missing_partition_record IN
SELECT *
FROM get_missing_time_partition_ranges(table_name, partition_interval, end_at, start_from)
LOOP
EXECUTE format('CREATE TABLE %I.%I PARTITION OF %I.%I FOR VALUES FROM (%L) TO (%L)',
schema_name_text,
missing_partition_record.partition_name,
schema_name_text,
table_name_text,
missing_partition_record.range_from_value,
missing_partition_record.range_to_value);
partition_created := true;
END LOOP;
RETURN partition_created;
END;
$$;
COMMENT ON FUNCTION pg_catalog.create_time_partitions(
table_name regclass,
partition_interval INTERVAL,
end_at timestamptz,
start_from timestamptz)
IS 'create time partitions for the given range';

View File

@ -21,6 +21,10 @@ BEGIN
RAISE 'start_from (%) must be older than end_at (%)', start_from, end_at;
END IF;
IF NOT isfinite(partition_interval) THEN
RAISE 'Partition interval must be a finite value';
END IF;
SELECT nspname, relname
INTO schema_name_text, table_name_text
FROM pg_class JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid

View File

@ -1453,6 +1453,21 @@ ROLLBACK;
NOTICE: issuing ROLLBACK
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
-- End of Testing AT LOCAL option
-- interval can have infinite values
-- Relevant PG17 commit: https://github.com/postgres/postgres/commit/519fc1bd9
-- disallow those in create_time_partitions
-- test create_time_partitions with infinity values
CREATE TABLE date_partitioned_table(
measureid integer,
eventdate date,
measure_data jsonb) PARTITION BY RANGE(eventdate);
SELECT create_time_partitions('date_partitioned_table', INTERVAL 'infinity', '2022-01-01', '2021-01-01');
ERROR: Partition interval must be a finite value
CONTEXT: PL/pgSQL function create_time_partitions(regclass,interval,timestamp with time zone,timestamp with time zone) line XX at RAISE
SELECT create_time_partitions('date_partitioned_table', INTERVAL '-infinity', '2022-01-01', '2021-01-01');
ERROR: Partition interval must be a finite value
CONTEXT: PL/pgSQL function create_time_partitions(regclass,interval,timestamp with time zone,timestamp with time zone) line XX at RAISE
-- end of testing interval with infinite values
\set VERBOSITY terse
SET client_min_messages TO WARNING;
DROP SCHEMA pg17 CASCADE;

View File

@ -797,6 +797,21 @@ ROLLBACK;
-- End of Testing AT LOCAL option
-- interval can have infinite values
-- Relevant PG17 commit: https://github.com/postgres/postgres/commit/519fc1bd9
-- disallow those in create_time_partitions
-- test create_time_partitions with infinity values
CREATE TABLE date_partitioned_table(
measureid integer,
eventdate date,
measure_data jsonb) PARTITION BY RANGE(eventdate);
SELECT create_time_partitions('date_partitioned_table', INTERVAL 'infinity', '2022-01-01', '2021-01-01');
SELECT create_time_partitions('date_partitioned_table', INTERVAL '-infinity', '2022-01-01', '2021-01-01');
-- end of testing interval with infinite values
\set VERBOSITY terse
SET client_min_messages TO WARNING;
DROP SCHEMA pg17 CASCADE;