From 5cee104d57a753f5ccea2b93cb81e4de3921a90a Mon Sep 17 00:00:00 2001 From: Matvey Arye Date: Thu, 24 Aug 2017 14:55:44 -0400 Subject: [PATCH] Allow chunk_time_interval to be specified as an INTERVAL type --- sql/ddl_api.sql | 30 ++--------- sql/ddl_internal.sql | 62 +++++++++++++++-------- sql/updates/pre-0.4.2--0.5.0-dev.sql | 4 ++ sql/util_time.sql | 49 ++++++++++++++++++ test/expected/ddl_errors.out | 2 +- test/expected/insert.out | 2 +- test/expected/insert_single.out | 75 +++++++++++++++++++--------- test/expected/pg_dump.out | 4 +- test/expected/timestamp.out | 49 ++++++++++++++++++ test/sql/ddl_errors.sql | 2 +- test/sql/insert.sql | 2 +- test/sql/insert_single.sql | 15 +++++- test/sql/timestamp.sql | 20 ++++++++ 13 files changed, 238 insertions(+), 78 deletions(-) diff --git a/sql/ddl_api.sql b/sql/ddl_api.sql index 98806d978..256b1d316 100644 --- a/sql/ddl_api.sql +++ b/sql/ddl_api.sql @@ -17,7 +17,7 @@ CREATE OR REPLACE FUNCTION create_hypertable( number_partitions INTEGER = NULL, associated_schema_name NAME = NULL, associated_table_prefix NAME = NULL, - chunk_time_interval BIGINT = NULL, + chunk_time_interval anyelement = NULL::bigint, create_default_indexes BOOLEAN = TRUE, if_not_exists BOOLEAN = FALSE ) @@ -71,7 +71,7 @@ BEGIN IF if_not_exists THEN RAISE NOTICE 'hypertable % already exists, skipping', main_table; RETURN; - ELSE + ELSE RAISE EXCEPTION 'hypertable % already exists', main_table USING ERRCODE = 'IO110'; END IF; @@ -84,30 +84,10 @@ BEGIN USING ERRCODE = 'IO102'; END IF; - -- We don't use INTO STRICT here because that error (no column) is surfaced later. - SELECT atttypid - INTO time_type - FROM pg_attribute - WHERE attrelid = main_table AND attname = time_column_name; + time_type := _timescaledb_internal.dimension_type(main_table, time_column_name, true); - -- Timestamp types can use default value, integral should be an error if NULL - IF time_type IN ('TIMESTAMP', 'TIMESTAMPTZ', 'DATE') AND chunk_time_interval IS NULL THEN - chunk_time_interval_actual := _timescaledb_internal.interval_to_usec('1 month'); - ELSIF time_type IN ('SMALLINT', 'INTEGER', 'BIGINT') AND chunk_time_interval IS NULL THEN - RAISE EXCEPTION 'chunk_time_interval needs to be explicitly set for types SMALLINT, INTEGER, and BIGINT' - USING ERRCODE = 'IO102'; - ELSE - chunk_time_interval_actual := chunk_time_interval; - END IF; - - -- Bounds check for integral timestamp types - IF time_type = 'INTEGER'::REGTYPE AND chunk_time_interval_actual > 2147483647 THEN - RAISE EXCEPTION 'chunk_time_interval is too large for type INTEGER (max: 2147483647)' - USING ERRCODE = 'IO102'; - ELSIF time_type = 'SMALLINT'::REGTYPE AND chunk_time_interval_actual > 65535 THEN - RAISE EXCEPTION 'chunk_time_interval is too large for type SMALLINT (max: 65535)' - USING ERRCODE = 'IO102'; - END IF; + chunk_time_interval_actual := _timescaledb_internal.time_interval_specification_to_internal( + time_type, chunk_time_interval, INTERVAL '1 month', 'chunk_time_interval'); BEGIN SELECT * diff --git a/sql/ddl_internal.sql b/sql/ddl_internal.sql index e26732b28..f2864d653 100644 --- a/sql/ddl_internal.sql +++ b/sql/ddl_internal.sql @@ -74,6 +74,39 @@ BEGIN END $BODY$; +CREATE OR REPLACE FUNCTION _timescaledb_internal.dimension_type( + main_table REGCLASS, + column_name NAME, + is_open BOOLEAN +) + RETURNS REGTYPE LANGUAGE PLPGSQL STABLE AS +$BODY$ +DECLARE + column_type REGTYPE; +BEGIN + BEGIN + SELECT atttypid + INTO STRICT column_type + FROM pg_attribute + WHERE attrelid = main_table AND attname = column_name; + EXCEPTION + WHEN NO_DATA_FOUND THEN + RAISE EXCEPTION 'column "%" does not exist', column_name + USING ERRCODE = 'IO102'; + END; + + IF is_open THEN + -- Open dimension + IF column_type NOT IN ('BIGINT', 'INTEGER', 'SMALLINT', 'DATE', 'TIMESTAMP', 'TIMESTAMPTZ') THEN + RAISE EXCEPTION 'illegal type for column "%": %', column_name, column_type + USING ERRCODE = 'IO102'; + END IF; + END IF; + RETURN column_type; +END +$BODY$; + + CREATE OR REPLACE FUNCTION _timescaledb_internal.add_dimension( main_table REGCLASS, hypertable_row _timescaledb_catalog.hypertable, -- should be locked FOR UPDATE @@ -106,29 +139,16 @@ BEGIN USING ERRCODE = 'IO102'; END IF; - BEGIN - SELECT atttypid - INTO STRICT column_type - FROM pg_attribute - WHERE attrelid = main_table AND attname = column_name; - EXCEPTION - WHEN NO_DATA_FOUND THEN - RAISE EXCEPTION 'column "%" does not exist', column_name - USING ERRCODE = 'IO102'; - END; + column_type = _timescaledb_internal.dimension_type(main_table, column_name, num_slices IS NULL); + + IF column_type = 'DATE'::regtype AND interval_length IS NOT NULL AND + (interval_length <= 0 OR interval_length % _timescaledb_internal.interval_to_usec('1 day') != 0) + THEN + RAISE EXCEPTION 'The interval for a hypertable with a DATE time column must be at least one day and given in multiples of days' + USING ERRCODE = 'IO102'; + END IF; IF num_slices IS NULL THEN - -- Open dimension - IF column_type NOT IN ('BIGINT', 'INTEGER', 'SMALLINT', 'DATE', 'TIMESTAMP', 'TIMESTAMPTZ') THEN - RAISE EXCEPTION 'illegal type for column "%": %', column_name, column_type - USING ERRCODE = 'IO102'; - END IF; - IF column_type = 'DATE'::regtype AND - (interval_length <= 0 OR interval_length % _timescaledb_internal.interval_to_usec('1 day') != 0) - THEN - RAISE EXCEPTION 'The interval for a hypertable with a DATE time column must be at least one day and given in multiples of days' - USING ERRCODE = 'IO102'; - END IF; partitioning_func := NULL; partitioning_func_schema := NULL; aligned = TRUE; diff --git a/sql/updates/pre-0.4.2--0.5.0-dev.sql b/sql/updates/pre-0.4.2--0.5.0-dev.sql index fafc399f5..074105702 100644 --- a/sql/updates/pre-0.4.2--0.5.0-dev.sql +++ b/sql/updates/pre-0.4.2--0.5.0-dev.sql @@ -35,3 +35,7 @@ CREATE SEQUENCE _timescaledb_catalog.chunk_constraint_name; SELECT pg_catalog.pg_extension_config_dump('_timescaledb_catalog.chunk_constraint_name', ''); DROP FUNCTION _timescaledb_internal.rename_hypertable(name, name, text, text); + +ALTER EXTENSION timescaledb +DROP FUNCTION create_hypertable(REGCLASS, NAME, NAME,INTEGER,NAME,NAME,BIGINT,BOOLEAN, BOOLEAN); +DROP FUNCTION create_hypertable(REGCLASS, NAME, NAME,INTEGER,NAME,NAME,BIGINT,BOOLEAN, BOOLEAN); diff --git a/sql/util_time.sql b/sql/util_time.sql index ebf18cb7b..e8bd59ce7 100644 --- a/sql/util_time.sql +++ b/sql/util_time.sql @@ -49,3 +49,52 @@ RETURNS BIGINT LANGUAGE SQL IMMUTABLE AS $BODY$ SELECT (int_sec * 1000000)::bigint from extract(epoch from chunk_interval) as int_sec; $BODY$; + +CREATE OR REPLACE FUNCTION _timescaledb_internal.time_interval_specification_to_internal( + time_type REGTYPE, + specification anyelement, + default_value INTERVAL, + field_name TEXT +) +RETURNS BIGINT LANGUAGE PLPGSQL IMMUTABLE AS +$BODY$ +BEGIN + IF time_type IN ('TIMESTAMP', 'TIMESTAMPTZ', 'DATE') THEN + IF specification IS NULL THEN + RETURN _timescaledb_internal.interval_to_usec(default_value); + ELSIF pg_typeof(specification) IN ('INT'::regtype, 'SMALLINT'::regtype, 'BIGINT'::regtype) THEN + IF specification::BIGINT < _timescaledb_internal.interval_to_usec('1 second') THEN + RAISE WARNING 'You specified a % of less than a second, make sure that this is what you intended', field_name + USING HINT = 'specification is specified in microseconds'; + END IF; + RETURN specification::BIGINT; + ELSIF pg_typeof(specification) = 'INTERVAL'::regtype THEN + RETURN _timescaledb_internal.interval_to_usec(specification); + ELSE + RAISE EXCEPTION '% needs to be an INTERVAL or integer type for TIMESTAMP, TIMESTAMPTZ, or DATE time columns', field_name + USING ERRCODE = 'IO102'; + END IF; + ELSIF time_type IN ('SMALLINT', 'INTEGER', 'BIGINT') THEN + IF specification IS NULL THEN + RAISE EXCEPTION '% needs to be explicitly set for time columns of type SMALLINT, INTEGER, and BIGINT', field_name + USING ERRCODE = 'IO102'; + ELSIF pg_typeof(specification) IN ('INT'::regtype, 'SMALLINT'::regtype, 'BIGINT'::regtype) THEN + --bounds check + IF time_type = 'INTEGER'::REGTYPE AND specification > 2147483647 THEN + RAISE EXCEPTION '% is too large for type INTEGER (max: 2147483647)', field_name + USING ERRCODE = 'IO102'; + ELSIF time_type = 'SMALLINT'::REGTYPE AND specification > 65535 THEN + RAISE EXCEPTION '% is too large for type SMALLINT (max: 65535)', field_name + USING ERRCODE = 'IO102'; + END IF; + RETURN specification::BIGINT; + ELSE + RAISE EXCEPTION '% needs to be an integer type for SMALLINT, INTEGER, and BIGINT time columns', field_name + USING ERRCODE = 'IO102'; + END IF; + ELSE + RAISE EXCEPTION 'unknown time column type: %', time_type + USING ERRCODE = 'IO102'; + END IF; +END +$BODY$; diff --git a/test/expected/ddl_errors.out b/test/expected/ddl_errors.out index f46dd704e..757de1c19 100644 --- a/test/expected/ddl_errors.out +++ b/test/expected/ddl_errors.out @@ -41,6 +41,6 @@ ERROR: hypertable public."Hypertable_1" already exists \set ON_ERROR_STOP 1 INSERT INTO "Hypertable_1" VALUES (0, 1, 0); \set ON_ERROR_STOP 0 -ALTER TABLE _timescaledb_internal._hyper_4_1_chunk ALTER COLUMN temp_c DROP NOT NULL; +ALTER TABLE _timescaledb_internal._hyper_2_1_chunk ALTER COLUMN temp_c DROP NOT NULL; ERROR: Operation not supported on chunk tables. \set ON_ERROR_STOP 1 diff --git a/test/expected/insert.out b/test/expected/insert.out index 68f7d793f..c2e81359a 100644 --- a/test/expected/insert.out +++ b/test/expected/insert.out @@ -435,7 +435,7 @@ SELECT count(*) FROM many_partitions_test; (1 row) CREATE TABLE date_col_test(time date, temp float8, device text NOT NULL); -SELECT create_hypertable('date_col_test', 'time', 'device', 1000); +SELECT create_hypertable('date_col_test', 'time', 'device', 1000, chunk_time_interval => INTERVAL '1 Day'); create_hypertable ------------------- diff --git a/test/expected/insert_single.out b/test/expected/insert_single.out index 9b4be7ca0..996e46e1b 100644 --- a/test/expected/insert_single.out +++ b/test/expected/insert_single.out @@ -303,7 +303,7 @@ SELECT "1dim" FROM "1dim"; --test that we can insert pre-1970 dates CREATE TABLE "1dim_pre1970"(time timestamp PRIMARY KEY, temp float); -SELECT create_hypertable('"1dim_pre1970"', 'time'); +SELECT create_hypertable('"1dim_pre1970"', 'time', chunk_time_interval=> INTERVAL '1 Month'); create_hypertable ------------------- @@ -313,6 +313,26 @@ INSERT INTO "1dim_pre1970" VALUES('1969-12-01T19:00:00', 21.2); INSERT INTO "1dim_pre1970" VALUES('1969-12-20T09:00:00', 25.1); INSERT INTO "1dim_pre1970" VALUES('1970-01-20T09:00:00', 26.6); INSERT INTO "1dim_pre1970" VALUES('1969-02-20T09:00:00', 29.9); +--should show warning +BEGIN; +CREATE TABLE "1dim_usec_interval"(time timestamp PRIMARY KEY, temp float); +SELECT create_hypertable('"1dim_usec_interval"', 'time', chunk_time_interval=> 10); +WARNING: You specified a chunk_time_interval of less than a second, make sure that this is what you intended + create_hypertable +------------------- + +(1 row) + +INSERT INTO "1dim_usec_interval" VALUES('1969-12-01T19:00:00', 21.2); +ROLLBACK; +CREATE TABLE "1dim_usec_interval"(time timestamp PRIMARY KEY, temp float); +SELECT create_hypertable('"1dim_usec_interval"', 'time', chunk_time_interval=> 1000000); + create_hypertable +------------------- + +(1 row) + +INSERT INTO "1dim_usec_interval" VALUES('1969-12-01T19:00:00', 21.2); CREATE TABLE "1dim_neg"(time INTEGER, temp float); SELECT create_hypertable('"1dim_neg"', 'time', chunk_time_interval=>10); create_hypertable @@ -358,12 +378,13 @@ SELECT * FROM _timescaledb_catalog.chunk; 5 | 3 | _timescaledb_internal | _hyper_3_5_chunk 6 | 3 | _timescaledb_internal | _hyper_3_6_chunk 7 | 3 | _timescaledb_internal | _hyper_3_7_chunk - 8 | 4 | _timescaledb_internal | _hyper_4_8_chunk - 9 | 4 | _timescaledb_internal | _hyper_4_9_chunk - 10 | 4 | _timescaledb_internal | _hyper_4_10_chunk - 11 | 4 | _timescaledb_internal | _hyper_4_11_chunk - 12 | 4 | _timescaledb_internal | _hyper_4_12_chunk -(12 rows) + 9 | 5 | _timescaledb_internal | _hyper_5_9_chunk + 10 | 6 | _timescaledb_internal | _hyper_6_10_chunk + 11 | 6 | _timescaledb_internal | _hyper_6_11_chunk + 12 | 6 | _timescaledb_internal | _hyper_6_12_chunk + 13 | 6 | _timescaledb_internal | _hyper_6_13_chunk + 14 | 6 | _timescaledb_internal | _hyper_6_14_chunk +(13 rows) SELECT * FROM _timescaledb_catalog.dimension_slice; id | dimension_id | range_start | range_end @@ -375,12 +396,13 @@ SELECT * FROM _timescaledb_catalog.dimension_slice; 5 | 3 | -2592000000000 | 0 6 | 3 | 0 | 2592000000000 7 | 3 | -28512000000000 | -25920000000000 - 8 | 4 | -20 | -10 - 9 | 4 | -10 | 0 - 10 | 4 | 0 | 10 - 11 | 4 | 10 | 20 - 12 | 4 | 20 | 30 -(12 rows) + 9 | 5 | -2581200000000 | -2581199000000 + 10 | 6 | -20 | -10 + 11 | 6 | -10 | 0 + 12 | 6 | 0 | 10 + 13 | 6 | 10 | 20 + 14 | 6 | 20 | 30 +(13 rows) -- Create a three-dimensional table CREATE TABLE "3dim" (time timestamp, temp float, device text, location text); @@ -400,17 +422,22 @@ INSERT INTO "3dim" VALUES('2017-01-20T09:00:01', 22.5, 'blue', 'nyc'); INSERT INTO "3dim" VALUES('2017-01-20T09:00:21', 21.2, 'brown', 'sthlm'); INSERT INTO "3dim" VALUES('2017-01-20T09:00:47', 25.1, 'yellow', 'la'); --show the constraints on the three-dimensional chunk -\d+ _timescaledb_internal._hyper_4_10_chunk - Table "_timescaledb_internal._hyper_4_10_chunk" - Column | Type | Modifiers | Storage | Stats target | Description ---------+------------------+-----------+---------+--------------+------------- - time | integer | | plain | | - temp | double precision | | plain | | +\d+ _timescaledb_internal._hyper_7_15_chunk + Table "_timescaledb_internal._hyper_7_15_chunk" + Column | Type | Modifiers | Storage | Stats target | Description +----------+-----------------------------+-----------+----------+--------------+------------- + time | timestamp without time zone | | plain | | + temp | double precision | | plain | | + device | text | | extended | | + location | text | | extended | | Indexes: - "21-1dim_neg_time_idx" btree ("time" DESC) + "24-3dim_time_idx" btree ("time" DESC) + "25-3dim_device_time_idx" btree (device, "time" DESC) Check constraints: - "constraint_10" CHECK ("time" >= 0 AND "time" < 10) -Inherits: "1dim_neg" + "constraint_15" CHECK ("time" >= 'Sat Dec 24 16:00:00 2016'::timestamp without time zone AND "time" < 'Mon Jan 23 16:00:00 2017'::timestamp without time zone) + "constraint_16" CHECK (_timescaledb_internal.get_partition_for_key(device) >= 0 AND _timescaledb_internal.get_partition_for_key(device) < 1073741823) + "constraint_17" CHECK (_timescaledb_internal.get_partition_for_key(location) >= 1073741823 AND _timescaledb_internal.get_partition_for_key(location) < 2147483647) +Inherits: "3dim" --queries should work in three dimensions SELECT * FROM "3dim"; @@ -494,7 +521,7 @@ CREATE TABLE "inttime_err"(time INTEGER PRIMARY KEY, temp float); SELECT create_hypertable('"inttime_err"', 'time', chunk_time_interval=>2147483648); ERROR: chunk_time_interval is too large for type INTEGER (max: 2147483647) SELECT create_hypertable('"inttime_err"', 'time'); -ERROR: chunk_time_interval needs to be explicitly set for types SMALLINT, INTEGER, and BIGINT +ERROR: chunk_time_interval needs to be explicitly set for time columns of type SMALLINT, INTEGER, and BIGINT \set ON_ERROR_STOP 1 SELECT create_hypertable('"inttime_err"', 'time', chunk_time_interval=>2147483647); create_hypertable @@ -508,7 +535,7 @@ CREATE TABLE "smallinttime_err"(time SMALLINT PRIMARY KEY, temp float); SELECT create_hypertable('"smallinttime_err"', 'time', chunk_time_interval=>65536); ERROR: chunk_time_interval is too large for type SMALLINT (max: 65535) SELECT create_hypertable('"smallinttime_err"', 'time'); -ERROR: chunk_time_interval needs to be explicitly set for types SMALLINT, INTEGER, and BIGINT +ERROR: chunk_time_interval needs to be explicitly set for time columns of type SMALLINT, INTEGER, and BIGINT \set ON_ERROR_STOP 1 SELECT create_hypertable('"smallinttime_err"', 'time', chunk_time_interval=>65535); create_hypertable diff --git a/test/expected/pg_dump.out b/test/expected/pg_dump.out index eca7cacdb..658c2a3e1 100644 --- a/test/expected/pg_dump.out +++ b/test/expected/pg_dump.out @@ -43,7 +43,7 @@ SELECT count(*) AND refobjid = (SELECT oid FROM pg_extension WHERE extname = 'timescaledb'); count ------- - 125 + 127 (1 row) \c postgres @@ -67,7 +67,7 @@ SELECT count(*) AND refobjid = (SELECT oid FROM pg_extension WHERE extname = 'timescaledb'); count ------- - 125 + 127 (1 row) \c single diff --git a/test/expected/timestamp.out b/test/expected/timestamp.out index 39c6ace2b..b6970647e 100644 --- a/test/expected/timestamp.out +++ b/test/expected/timestamp.out @@ -609,3 +609,52 @@ FROM unnest(ARRAY[ 11-09-2017 | 11-09-2017 (4 rows) +------------------------------------ +-- Test time input functions -- +------------------------------------ +SELECT _timescaledb_internal.time_interval_specification_to_internal('TIMESTAMP', INTERVAL '1 day', INTERVAL '1 month', 'test_name'); + time_interval_specification_to_internal +----------------------------------------- + 86400000000 +(1 row) + +SELECT _timescaledb_internal.time_interval_specification_to_internal('TIMESTAMP', 86400000000, INTERVAL '1 month', 'test_name'); + time_interval_specification_to_internal +----------------------------------------- + 86400000000 +(1 row) + +--should give warning +SELECT _timescaledb_internal.time_interval_specification_to_internal('TIMESTAMP', 86400, INTERVAL '1 month', 'test_name'); +WARNING: You specified a test_name of less than a second, make sure that this is what you intended +HINT: specification is specified in microseconds + time_interval_specification_to_internal +----------------------------------------- + 86400 +(1 row) + +SELECT _timescaledb_internal.time_interval_specification_to_internal('TIMESTAMP', NULL::bigint, INTERVAL '1 month', 'test_name'); + time_interval_specification_to_internal +----------------------------------------- + 2592000000000 +(1 row) + +SELECT _timescaledb_internal.time_interval_specification_to_internal('BIGINT', 2147483649::bigint, INTERVAL '1 month', 'test_name'); + time_interval_specification_to_internal +----------------------------------------- + 2147483649 +(1 row) + +\set VERBOSITY terse +\set ON_ERROR_STOP 0 +SELECT _timescaledb_internal.time_interval_specification_to_internal('INT', NULL::bigint, INTERVAL '1 month', 'test_name'); +ERROR: test_name needs to be explicitly set for time columns of type SMALLINT, INTEGER, and BIGINT +SELECT _timescaledb_internal.time_interval_specification_to_internal('INT', 2147483649::bigint, INTERVAL '1 month', 'test_name'); +ERROR: test_name is too large for type INTEGER (max: 2147483647) +SELECT _timescaledb_internal.time_interval_specification_to_internal('SMALLINT', 65536::bigint, INTERVAL '1 month', 'test_name'); +ERROR: test_name is too large for type SMALLINT (max: 65535) +SELECT _timescaledb_internal.time_interval_specification_to_internal('TEXT', 65536::bigint, INTERVAL '1 month', 'test_name'); +ERROR: unknown time column type: text +SELECT _timescaledb_internal.time_interval_specification_to_internal('INT', INTERVAL '1 day', INTERVAL '1 month', 'test_name'); +ERROR: test_name needs to be an integer type for SMALLINT, INTEGER, and BIGINT time columns +\set ON_ERROR_STOP 1 diff --git a/test/sql/ddl_errors.sql b/test/sql/ddl_errors.sql index 6d29464ef..a3b9e0661 100644 --- a/test/sql/ddl_errors.sql +++ b/test/sql/ddl_errors.sql @@ -33,5 +33,5 @@ SELECT * FROM create_hypertable('"public"."Hypertable_1"', 'time', 'Device_id', INSERT INTO "Hypertable_1" VALUES (0, 1, 0); \set ON_ERROR_STOP 0 -ALTER TABLE _timescaledb_internal._hyper_4_1_chunk ALTER COLUMN temp_c DROP NOT NULL; +ALTER TABLE _timescaledb_internal._hyper_2_1_chunk ALTER COLUMN temp_c DROP NOT NULL; \set ON_ERROR_STOP 1 diff --git a/test/sql/insert.sql b/test/sql/insert.sql index 235ce2977..53ff434df 100644 --- a/test/sql/insert.sql +++ b/test/sql/insert.sql @@ -46,7 +46,7 @@ SELECT * FROM many_partitions_test ORDER BY time DESC LIMIT 2; SELECT count(*) FROM many_partitions_test; CREATE TABLE date_col_test(time date, temp float8, device text NOT NULL); -SELECT create_hypertable('date_col_test', 'time', 'device', 1000); +SELECT create_hypertable('date_col_test', 'time', 'device', 1000, chunk_time_interval => INTERVAL '1 Day'); INSERT INTO date_col_test VALUES ('2001-02-01', 98, 'dev1'), ('2001-03-02', 98, 'dev1'); diff --git a/test/sql/insert_single.sql b/test/sql/insert_single.sql index d318d1700..074ed23c0 100644 --- a/test/sql/insert_single.sql +++ b/test/sql/insert_single.sql @@ -23,12 +23,23 @@ SELECT "1dim" FROM "1dim"; --test that we can insert pre-1970 dates CREATE TABLE "1dim_pre1970"(time timestamp PRIMARY KEY, temp float); -SELECT create_hypertable('"1dim_pre1970"', 'time'); +SELECT create_hypertable('"1dim_pre1970"', 'time', chunk_time_interval=> INTERVAL '1 Month'); INSERT INTO "1dim_pre1970" VALUES('1969-12-01T19:00:00', 21.2); INSERT INTO "1dim_pre1970" VALUES('1969-12-20T09:00:00', 25.1); INSERT INTO "1dim_pre1970" VALUES('1970-01-20T09:00:00', 26.6); INSERT INTO "1dim_pre1970" VALUES('1969-02-20T09:00:00', 29.9); +--should show warning +BEGIN; +CREATE TABLE "1dim_usec_interval"(time timestamp PRIMARY KEY, temp float); +SELECT create_hypertable('"1dim_usec_interval"', 'time', chunk_time_interval=> 10); +INSERT INTO "1dim_usec_interval" VALUES('1969-12-01T19:00:00', 21.2); +ROLLBACK; + +CREATE TABLE "1dim_usec_interval"(time timestamp PRIMARY KEY, temp float); +SELECT create_hypertable('"1dim_usec_interval"', 'time', chunk_time_interval=> 1000000); +INSERT INTO "1dim_usec_interval" VALUES('1969-12-01T19:00:00', 21.2); + CREATE TABLE "1dim_neg"(time INTEGER, temp float); SELECT create_hypertable('"1dim_neg"', 'time', chunk_time_interval=>10); INSERT INTO "1dim_neg" VALUES (-20, 21.2); @@ -53,7 +64,7 @@ INSERT INTO "3dim" VALUES('2017-01-20T09:00:21', 21.2, 'brown', 'sthlm'); INSERT INTO "3dim" VALUES('2017-01-20T09:00:47', 25.1, 'yellow', 'la'); --show the constraints on the three-dimensional chunk -\d+ _timescaledb_internal._hyper_4_10_chunk +\d+ _timescaledb_internal._hyper_7_15_chunk --queries should work in three dimensions SELECT * FROM "3dim"; diff --git a/test/sql/timestamp.sql b/test/sql/timestamp.sql index 8da01dc59..9bb974bd8 100644 --- a/test/sql/timestamp.sql +++ b/test/sql/timestamp.sql @@ -356,3 +356,23 @@ FROM unnest(ARRAY[ date '2017-11-08', date '2017-11-09' ]) AS time; + +------------------------------------ +-- Test time input functions -- +------------------------------------ +SELECT _timescaledb_internal.time_interval_specification_to_internal('TIMESTAMP', INTERVAL '1 day', INTERVAL '1 month', 'test_name'); +SELECT _timescaledb_internal.time_interval_specification_to_internal('TIMESTAMP', 86400000000, INTERVAL '1 month', 'test_name'); +--should give warning +SELECT _timescaledb_internal.time_interval_specification_to_internal('TIMESTAMP', 86400, INTERVAL '1 month', 'test_name'); + +SELECT _timescaledb_internal.time_interval_specification_to_internal('TIMESTAMP', NULL::bigint, INTERVAL '1 month', 'test_name'); +SELECT _timescaledb_internal.time_interval_specification_to_internal('BIGINT', 2147483649::bigint, INTERVAL '1 month', 'test_name'); + +\set VERBOSITY terse +\set ON_ERROR_STOP 0 +SELECT _timescaledb_internal.time_interval_specification_to_internal('INT', NULL::bigint, INTERVAL '1 month', 'test_name'); +SELECT _timescaledb_internal.time_interval_specification_to_internal('INT', 2147483649::bigint, INTERVAL '1 month', 'test_name'); +SELECT _timescaledb_internal.time_interval_specification_to_internal('SMALLINT', 65536::bigint, INTERVAL '1 month', 'test_name'); +SELECT _timescaledb_internal.time_interval_specification_to_internal('TEXT', 65536::bigint, INTERVAL '1 month', 'test_name'); +SELECT _timescaledb_internal.time_interval_specification_to_internal('INT', INTERVAL '1 day', INTERVAL '1 month', 'test_name'); +\set ON_ERROR_STOP 1