mirror of https://github.com/citusdata/citus.git
Add truncating according to interval and minor fixes
parent
ef724edf31
commit
e9bb732b22
|
@ -13,19 +13,14 @@ DECLARE
|
||||||
current_partition_count int;
|
current_partition_count int;
|
||||||
BEGIN
|
BEGIN
|
||||||
/*
|
/*
|
||||||
* TODO: Check whether the table is timeseries table with INTERVAL partition range
|
* First check whether such timeseries table exists. If not, error out.
|
||||||
* and timestamptz partition column
|
*
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Then check if start_from is given. If it is, create the partition for that time
|
* Then check if start_from is given. If it is, create the partition for that time
|
||||||
* and let remaining of the function fill the gap from start_from to to_date.
|
* and let remaining of the function fill the gap from start_from to to_date.
|
||||||
*
|
*
|
||||||
* TODO: That part is implemented by assuming that there is no partition exist for
|
* TODO: That part is implemented by assuming that there is no partition exist for
|
||||||
* the given table, in other words that function will be called via create_timeseries_table
|
* the given table, in other words that function will be called via create_timeseries_table
|
||||||
* only.
|
* only. That will be handled while adding starting time for old data ingestion (Task 1.3)
|
||||||
*
|
|
||||||
* TODO: Handle date trunc according to given interval of the timeseries table
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SELECT partitioninterval
|
SELECT partitioninterval
|
||||||
|
@ -33,11 +28,32 @@ BEGIN
|
||||||
FROM citus_timeseries.citus_timeseries_tables
|
FROM citus_timeseries.citus_timeseries_tables
|
||||||
WHERE logicalrelid = table_name;
|
WHERE logicalrelid = table_name;
|
||||||
|
|
||||||
|
IF NOT found THEN
|
||||||
|
RAISE '% must be timeseries table', table_name;
|
||||||
|
END IF;
|
||||||
|
|
||||||
IF start_from IS NOT NULL THEN
|
IF start_from IS NOT NULL THEN
|
||||||
RAISE NOTICE 'IN START FROM';
|
/*
|
||||||
|
* Decide on the current_range_from_value of the initial partition according to interval of the timeseries table.
|
||||||
|
* Since we will create all other partitions by adding intervals, truncating given start time will provide
|
||||||
|
* more intuitive interval ranges.
|
||||||
|
*/
|
||||||
|
IF table_partition_interval < INTERVAL '1 hour' THEN
|
||||||
|
current_range_from_value = date_trunc('minute', start_from);
|
||||||
|
ELSIF table_partition_interval < INTERVAL '1 day' THEN
|
||||||
|
current_range_from_value = date_trunc('hour', start_from);
|
||||||
|
ELSIF table_partition_interval < INTERVAL '1 week' THEN
|
||||||
|
current_range_from_value = date_trunc('day', start_from);
|
||||||
|
ELSIF table_partition_interval < INTERVAL '1 month' THEN
|
||||||
|
current_range_from_value = date_trunc('week', start_from);
|
||||||
|
ELSIF table_partition_interval < INTERVAL '1 year' THEN
|
||||||
|
current_range_from_value = date_trunc('month', start_from);
|
||||||
|
ELSE
|
||||||
|
current_range_from_value = date_trunc('year', start_from);
|
||||||
|
END IF;
|
||||||
|
|
||||||
current_partition_count := 0;
|
current_partition_count := 0;
|
||||||
current_range_from_value := start_from;
|
current_range_to_value := current_range_from_value + table_partition_interval;
|
||||||
current_range_to_value := start_from + table_partition_interval;
|
|
||||||
current_partition_name := table_name::text || '_' || current_partition_count::text;
|
current_partition_name := table_name::text || '_' || current_partition_count::text;
|
||||||
|
|
||||||
EXECUTE format('CREATE TABLE %I PARTITION OF %I FOR VALUES FROM (''%I'') TO (''%I'')', current_partition_name, table_name::text, current_range_from_value::text, current_range_to_value::text);
|
EXECUTE format('CREATE TABLE %I PARTITION OF %I FOR VALUES FROM (''%I'') TO (''%I'')', current_partition_name, table_name::text, current_range_from_value::text, current_range_to_value::text);
|
||||||
|
@ -59,9 +75,7 @@ BEGIN
|
||||||
FROM pg_catalog.time_partitions
|
FROM pg_catalog.time_partitions
|
||||||
WHERE parent_table = table_name;
|
WHERE parent_table = table_name;
|
||||||
|
|
||||||
RAISE NOTICE 'current_range_from_value %', current_range_from_value;
|
WHILE current_range_to_value < to_date LOOP
|
||||||
|
|
||||||
WHILE current_range_from_value < to_date LOOP
|
|
||||||
current_range_from_value := current_range_to_value;
|
current_range_from_value := current_range_to_value;
|
||||||
current_range_to_value := current_range_to_value + table_partition_interval;
|
current_range_to_value := current_range_to_value + table_partition_interval;
|
||||||
current_partition_name := table_name::text || '_' || current_partition_count::text;
|
current_partition_name := table_name::text || '_' || current_partition_count::text;
|
||||||
|
@ -69,14 +83,13 @@ BEGIN
|
||||||
-- TODO: Create that using attach partition, which can be implemented with another UDF to make sure that it gets light locks.
|
-- TODO: Create that using attach partition, which can be implemented with another UDF to make sure that it gets light locks.
|
||||||
BEGIN
|
BEGIN
|
||||||
EXECUTE format('CREATE TABLE %I PARTITION OF %I FOR VALUES FROM (''%I'') TO (''%I'')', current_partition_name, table_name::text, current_range_from_value::text, current_range_to_value::text);
|
EXECUTE format('CREATE TABLE %I PARTITION OF %I FOR VALUES FROM (''%I'') TO (''%I'')', current_partition_name, table_name::text, current_range_from_value::text, current_range_to_value::text);
|
||||||
EXCEPTION WHEN OTHERS THEN
|
|
||||||
raise notice 'Partition has already been created for the range from % to %', current_range_from_value::text, current_range_to_value::text;
|
|
||||||
END;
|
|
||||||
|
|
||||||
current_partition_count := current_partition_count + 1;
|
current_partition_count := current_partition_count + 1;
|
||||||
|
EXCEPTION WHEN OTHERS THEN
|
||||||
|
raise DEBUG3 'Partition has already been created for the range from % to %', current_range_from_value::text, current_range_to_value::text;
|
||||||
|
END;
|
||||||
END LOOP;
|
END LOOP;
|
||||||
|
|
||||||
return true;
|
RETURN true;
|
||||||
END;
|
END;
|
||||||
$$;
|
$$;
|
||||||
COMMENT ON FUNCTION pg_catalog.create_missing_partitions(
|
COMMENT ON FUNCTION pg_catalog.create_missing_partitions(
|
||||||
|
|
|
@ -13,19 +13,14 @@ DECLARE
|
||||||
current_partition_count int;
|
current_partition_count int;
|
||||||
BEGIN
|
BEGIN
|
||||||
/*
|
/*
|
||||||
* TODO: Check whether the table is timeseries table with INTERVAL partition range
|
* First check whether such timeseries table exists. If not, error out.
|
||||||
* and timestamptz partition column
|
*
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Then check if start_from is given. If it is, create the partition for that time
|
* Then check if start_from is given. If it is, create the partition for that time
|
||||||
* and let remaining of the function fill the gap from start_from to to_date.
|
* and let remaining of the function fill the gap from start_from to to_date.
|
||||||
*
|
*
|
||||||
* TODO: That part is implemented by assuming that there is no partition exist for
|
* TODO: That part is implemented by assuming that there is no partition exist for
|
||||||
* the given table, in other words that function will be called via create_timeseries_table
|
* the given table, in other words that function will be called via create_timeseries_table
|
||||||
* only.
|
* only. That will be handled while adding starting time for old data ingestion (Task 1.3)
|
||||||
*
|
|
||||||
* TODO: Handle date trunc according to given interval of the timeseries table
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SELECT partitioninterval
|
SELECT partitioninterval
|
||||||
|
@ -33,11 +28,32 @@ BEGIN
|
||||||
FROM citus_timeseries.citus_timeseries_tables
|
FROM citus_timeseries.citus_timeseries_tables
|
||||||
WHERE logicalrelid = table_name;
|
WHERE logicalrelid = table_name;
|
||||||
|
|
||||||
|
IF NOT found THEN
|
||||||
|
RAISE '% must be timeseries table', table_name;
|
||||||
|
END IF;
|
||||||
|
|
||||||
IF start_from IS NOT NULL THEN
|
IF start_from IS NOT NULL THEN
|
||||||
RAISE NOTICE 'IN START FROM';
|
/*
|
||||||
|
* Decide on the current_range_from_value of the initial partition according to interval of the timeseries table.
|
||||||
|
* Since we will create all other partitions by adding intervals, truncating given start time will provide
|
||||||
|
* more intuitive interval ranges.
|
||||||
|
*/
|
||||||
|
IF table_partition_interval < INTERVAL '1 hour' THEN
|
||||||
|
current_range_from_value = date_trunc('minute', start_from);
|
||||||
|
ELSIF table_partition_interval < INTERVAL '1 day' THEN
|
||||||
|
current_range_from_value = date_trunc('hour', start_from);
|
||||||
|
ELSIF table_partition_interval < INTERVAL '1 week' THEN
|
||||||
|
current_range_from_value = date_trunc('day', start_from);
|
||||||
|
ELSIF table_partition_interval < INTERVAL '1 month' THEN
|
||||||
|
current_range_from_value = date_trunc('week', start_from);
|
||||||
|
ELSIF table_partition_interval < INTERVAL '1 year' THEN
|
||||||
|
current_range_from_value = date_trunc('month', start_from);
|
||||||
|
ELSE
|
||||||
|
current_range_from_value = date_trunc('year', start_from);
|
||||||
|
END IF;
|
||||||
|
|
||||||
current_partition_count := 0;
|
current_partition_count := 0;
|
||||||
current_range_from_value := start_from;
|
current_range_to_value := current_range_from_value + table_partition_interval;
|
||||||
current_range_to_value := start_from + table_partition_interval;
|
|
||||||
current_partition_name := table_name::text || '_' || current_partition_count::text;
|
current_partition_name := table_name::text || '_' || current_partition_count::text;
|
||||||
|
|
||||||
EXECUTE format('CREATE TABLE %I PARTITION OF %I FOR VALUES FROM (''%I'') TO (''%I'')', current_partition_name, table_name::text, current_range_from_value::text, current_range_to_value::text);
|
EXECUTE format('CREATE TABLE %I PARTITION OF %I FOR VALUES FROM (''%I'') TO (''%I'')', current_partition_name, table_name::text, current_range_from_value::text, current_range_to_value::text);
|
||||||
|
@ -52,7 +68,6 @@ BEGIN
|
||||||
INTO current_range_from_value, current_range_to_value
|
INTO current_range_from_value, current_range_to_value
|
||||||
FROM pg_catalog.time_partitions
|
FROM pg_catalog.time_partitions
|
||||||
WHERE parent_table = table_name
|
WHERE parent_table = table_name
|
||||||
|
|
||||||
ORDER BY from_value::timestamptz;
|
ORDER BY from_value::timestamptz;
|
||||||
|
|
||||||
SELECT count(*)
|
SELECT count(*)
|
||||||
|
@ -60,25 +75,22 @@ BEGIN
|
||||||
FROM pg_catalog.time_partitions
|
FROM pg_catalog.time_partitions
|
||||||
WHERE parent_table = table_name;
|
WHERE parent_table = table_name;
|
||||||
|
|
||||||
RAISE NOTICE 'current_range_from_value %', current_range_from_value;
|
WHILE current_range_to_value < to_date LOOP
|
||||||
|
|
||||||
WHILE current_range_from_value < to_date LOOP
|
|
||||||
current_range_from_value := current_range_to_value;
|
current_range_from_value := current_range_to_value;
|
||||||
current_range_to_value := current_range_to_value + table_partition_interval;
|
current_range_to_value := current_range_to_value + table_partition_interval;
|
||||||
current_partition_name := table_name::text || '_' || current_partition_count::text;
|
current_partition_name := table_name::text || '_' || current_partition_count::text;
|
||||||
|
|
||||||
-- TODO: Create that using attach partition, which can be implemented with another UDF to make sure that it gets light locks.
|
-- TODO: Create that using attach partition, which can be implemented with another UDF to make sure that it gets light locks.
|
||||||
-- TODO: Add exception handling or partition check
|
|
||||||
BEGIN
|
BEGIN
|
||||||
EXECUTE format('CREATE TABLE %I PARTITION OF %I FOR VALUES FROM (''%I'') TO (''%I'')', current_partition_name, table_name::text, current_range_from_value::text, current_range_to_value::text);
|
EXECUTE format('CREATE TABLE %I PARTITION OF %I FOR VALUES FROM (''%I'') TO (''%I'')', current_partition_name, table_name::text, current_range_from_value::text, current_range_to_value::text);
|
||||||
EXCEPTION WHEN OTHERS THEN
|
EXCEPTION WHEN OTHERS THEN
|
||||||
raise notice 'oops %', sqlstate;
|
raise DEBUG3 'Partition has already been created for the range from % to %', current_range_from_value::text, current_range_to_value::text;
|
||||||
END;
|
END;
|
||||||
|
|
||||||
current_partition_count := current_partition_count + 1;
|
current_partition_count := current_partition_count + 1;
|
||||||
END LOOP;
|
END LOOP;
|
||||||
|
|
||||||
return true;
|
RETURN true;
|
||||||
END;
|
END;
|
||||||
$$;
|
$$;
|
||||||
COMMENT ON FUNCTION pg_catalog.create_missing_partitions(
|
COMMENT ON FUNCTION pg_catalog.create_missing_partitions(
|
||||||
|
|
Loading…
Reference in New Issue