Fix range covered by osm chunk slices

The initial range for the OSM chunk will be from INT64_MAX - 1 to INT64_MAX.
This range was chosen to minimize interference with tuple routing and
occupy a range outside of potential values as there must be no overlap
between the hypercube occupied by the osm chunk and actual chunks.
Previously the range covered by the osm chunk would bucket the start
of the range leading to a dependency on chunk_time_interval and
limiting the range of usable values in the hypertable when an osm chunk
is present.
This commit is contained in:
Sven Klemm 2023-09-11 23:30:08 +02:00 committed by Sven Klemm
parent 93519d0af8
commit 90cedf3da5
4 changed files with 132 additions and 14 deletions

View File

@ -167,3 +167,10 @@ ALTER FUNCTION _timescaledb_internal.finalize_agg_ffunc(internal,text,name,name,
ALTER FUNCTION _timescaledb_internal.finalize_agg_sfunc(internal,text,name,name,name[],bytea,anyelement) SET SCHEMA _timescaledb_functions;
ALTER FUNCTION _timescaledb_internal.partialize_agg(anyelement) SET SCHEMA _timescaledb_functions;
-- Fix osm chunk ranges
UPDATE _timescaledb_catalog.dimension_slice ds
SET range_start = 9223372036854775806
FROM _timescaledb_catalog.chunk_constraint cc
INNER JOIN _timescaledb_catalog.chunk c ON c.id = cc.chunk_id AND c.osm_chunk
WHERE cc.dimension_slice_id = ds.id AND ds.range_start <> 9223372036854775806;

View File

@ -4517,20 +4517,23 @@ ts_chunk_scan_iterator_set_chunk_id(ScanIterator *it, int32 chunk_id)
}
#include "hypercube.h"
/*
* Create a hypercube for the OSM chunk
* The initial range for the OSM chunk will be from INT64_MAX - 1 to INT64_MAX.
* This range was chosen to minimize interference with tuple routing and
* occupy a range outside of potential values as there must be no overlap
* between the hypercube occupied by the osm chunk and actual chunks.
*/
static Hypercube *
fill_hypercube_for_foreign_table_chunk(Hyperspace *hs)
fill_hypercube_for_osm_chunk(Hyperspace *hs)
{
Hypercube *cube = ts_hypercube_alloc(hs->num_dimensions);
Point *p = ts_point_create(hs->num_dimensions);
Assert(hs->num_dimensions == 1); // does not work with partitioned range
for (int i = 0; i < hs->num_dimensions; i++)
{
const Dimension *dim = &hs->dimensions[i];
Assert(dim->type == DIMENSION_TYPE_OPEN);
Oid dimtype = ts_dimension_get_partition_type(dim);
Datum val = ts_time_datum_get_max(dimtype);
p->coordinates[p->num_coords++] = ts_time_value_to_internal(val, dimtype);
cube->slices[i] = ts_dimension_calculate_default_slice(dim, p->coordinates[i]);
cube->slices[i] = ts_dimension_slice_create(dim->fd.id, PG_INT64_MAX - 1, PG_INT64_MAX);
cube->num_slices++;
}
Assert(cube->num_slices == 1);
@ -4580,7 +4583,7 @@ add_foreign_table_as_chunk(Oid relid, Hypertable *parent_ht)
/* fill in the correct table_name for the chunk*/
chunk->fd.hypertable_id = hs->hypertable_id;
chunk->fd.osm_chunk = true; /* this is an OSM chunk */
chunk->cube = fill_hypercube_for_foreign_table_chunk(hs);
chunk->cube = fill_hypercube_for_osm_chunk(hs);
chunk->hypertable_relid = parent_ht->main_table_relid;
chunk->constraints = ts_chunk_constraints_alloc(1, CurrentMemoryContext);

View File

@ -533,10 +533,10 @@ SELECT chunk_name, range_start, range_end
FROM chunk_view
WHERE hypertable_name = 'ht_try'
ORDER BY chunk_name;
chunk_name | range_start | range_end
-------------------+--------------------------------+------------------------------
_hyper_5_10_chunk | Wed May 04 17:00:00 2022 PDT | Thu May 05 17:00:00 2022 PDT
child_fdw_table | Thu Dec 31 16:00:00 294246 PST | infinity
chunk_name | range_start | range_end
-------------------+---------------------------------------+------------------------------
_hyper_5_10_chunk | Wed May 04 17:00:00 2022 PDT | Thu May 05 17:00:00 2022 PDT
child_fdw_table | Sat Jan 09 20:00:54.775806 294247 PST | infinity
(2 rows)
SELECT * FROM ht_try ORDER BY 1;
@ -802,9 +802,9 @@ SELECT chunk_name, range_start, range_end
FROM chunk_view
WHERE hypertable_name = 'hyper_constr'
ORDER BY chunk_name;
chunk_name | range_start | range_end
--------------------+-------------------------------------+-----------
child_hyper_constr | Sat Jan 09 20:00:54.7758 294247 PST | infinity
chunk_name | range_start | range_end
--------------------+---------------------------------------+-----------
child_hyper_constr | Sat Jan 09 20:00:54.775806 294247 PST | infinity
(1 row)
----- TESTS for copy into frozen chunk ------------
@ -910,6 +910,83 @@ SELECT indexname, tablename FROM pg_indexes WHERE indexname = 'hyper_constr_mid_
(1 row)
DROP INDEX hyper_constr_mid_idx;
-- test range of dimension slice for osm chunk for different datatypes
CREATE TABLE osm_int2(time int2 NOT NULL);
CREATE TABLE osm_int4(time int4 NOT NULL);
CREATE TABLE osm_int8(time int8 NOT NULL);
CREATE TABLE osm_date(time date NOT NULL);
CREATE TABLE osm_ts(time timestamp NOT NULL);
CREATE TABLE osm_tstz(time timestamptz NOT NULL);
SELECT table_name FROM create_hypertable('osm_int2','time',chunk_time_interval:=1000);
table_name
------------
osm_int2
(1 row)
SELECT table_name FROM create_hypertable('osm_int4','time',chunk_time_interval:=1000);
table_name
------------
osm_int4
(1 row)
SELECT table_name FROM create_hypertable('osm_int8','time',chunk_time_interval:=1000);
table_name
------------
osm_int8
(1 row)
SELECT table_name FROM create_hypertable('osm_date','time');
table_name
------------
osm_date
(1 row)
SELECT table_name FROM create_hypertable('osm_ts','time');
WARNING: column type "timestamp without time zone" used for "time" does not follow best practices
table_name
------------
osm_ts
(1 row)
SELECT table_name FROM create_hypertable('osm_tstz','time');
table_name
------------
osm_tstz
(1 row)
CREATE FOREIGN TABLE osm_int2_fdw_child(time int2 NOT NULL) SERVER s3_server;
CREATE FOREIGN TABLE osm_int4_fdw_child(time int4 NOT NULL) SERVER s3_server;
CREATE FOREIGN TABLE osm_int8_fdw_child(time int8 NOT NULL) SERVER s3_server;
CREATE FOREIGN TABLE osm_date_fdw_child(time date NOT NULL) SERVER s3_server;
CREATE FOREIGN TABLE osm_ts_fdw_child(time timestamp NOT NULL) SERVER s3_server;
CREATE FOREIGN TABLE osm_tstz_fdw_child(time timestamptz NOT NULL) SERVER s3_server;
SELECT dt, _timescaledb_functions.attach_osm_table_chunk('osm_' || dt, 'osm_' || dt || '_fdw_child') FROM unnest('{int2,int4,int8,date,ts,tstz}'::text[]) u(dt);
dt | attach_osm_table_chunk
------+------------------------
int2 | t
int4 | t
int8 | t
date | t
ts | t
tstz | t
(6 rows)
SELECT ht.table_name, ds.*
FROM _timescaledb_catalog.dimension_slice ds
INNER JOIN _timescaledb_catalog.dimension d ON d.id=ds.dimension_id
INNER JOIN _timescaledb_catalog.hypertable ht on ht.id=d.hypertable_id
WHERE ht.table_name LIKE 'osm%'
ORDER BY 2,3;
table_name | id | dimension_id | range_start | range_end
------------+----+--------------+---------------------+---------------------
osm_int2 | 17 | 9 | 9223372036854775806 | 9223372036854775807
osm_int4 | 18 | 10 | 9223372036854775806 | 9223372036854775807
osm_int8 | 19 | 11 | 9223372036854775806 | 9223372036854775807
osm_date | 20 | 12 | 9223372036854775806 | 9223372036854775807
osm_ts | 21 | 13 | 9223372036854775806 | 9223372036854775807
osm_tstz | 22 | 14 | 9223372036854775806 | 9223372036854775807
(6 rows)
-- clean up databases created
\c :TEST_DBNAME :ROLE_SUPERUSER
DROP DATABASE postgres_fdw_db;

View File

@ -555,6 +555,37 @@ CREATE INDEX hyper_constr_mid_idx ON hyper_constr(mid, time) WITH (timescaledb.t
SELECT indexname, tablename FROM pg_indexes WHERE indexname = 'hyper_constr_mid_idx';
DROP INDEX hyper_constr_mid_idx;
-- test range of dimension slice for osm chunk for different datatypes
CREATE TABLE osm_int2(time int2 NOT NULL);
CREATE TABLE osm_int4(time int4 NOT NULL);
CREATE TABLE osm_int8(time int8 NOT NULL);
CREATE TABLE osm_date(time date NOT NULL);
CREATE TABLE osm_ts(time timestamp NOT NULL);
CREATE TABLE osm_tstz(time timestamptz NOT NULL);
SELECT table_name FROM create_hypertable('osm_int2','time',chunk_time_interval:=1000);
SELECT table_name FROM create_hypertable('osm_int4','time',chunk_time_interval:=1000);
SELECT table_name FROM create_hypertable('osm_int8','time',chunk_time_interval:=1000);
SELECT table_name FROM create_hypertable('osm_date','time');
SELECT table_name FROM create_hypertable('osm_ts','time');
SELECT table_name FROM create_hypertable('osm_tstz','time');
CREATE FOREIGN TABLE osm_int2_fdw_child(time int2 NOT NULL) SERVER s3_server;
CREATE FOREIGN TABLE osm_int4_fdw_child(time int4 NOT NULL) SERVER s3_server;
CREATE FOREIGN TABLE osm_int8_fdw_child(time int8 NOT NULL) SERVER s3_server;
CREATE FOREIGN TABLE osm_date_fdw_child(time date NOT NULL) SERVER s3_server;
CREATE FOREIGN TABLE osm_ts_fdw_child(time timestamp NOT NULL) SERVER s3_server;
CREATE FOREIGN TABLE osm_tstz_fdw_child(time timestamptz NOT NULL) SERVER s3_server;
SELECT dt, _timescaledb_functions.attach_osm_table_chunk('osm_' || dt, 'osm_' || dt || '_fdw_child') FROM unnest('{int2,int4,int8,date,ts,tstz}'::text[]) u(dt);
SELECT ht.table_name, ds.*
FROM _timescaledb_catalog.dimension_slice ds
INNER JOIN _timescaledb_catalog.dimension d ON d.id=ds.dimension_id
INNER JOIN _timescaledb_catalog.hypertable ht on ht.id=d.hypertable_id
WHERE ht.table_name LIKE 'osm%'
ORDER BY 2,3;
-- clean up databases created
\c :TEST_DBNAME :ROLE_SUPERUSER
DROP DATABASE postgres_fdw_db;