diff --git a/sql/chunk.sql b/sql/chunk.sql index 93707bf9b..915a3f254 100644 --- a/sql/chunk.sql +++ b/sql/chunk.sql @@ -69,4 +69,4 @@ CREATE OR REPLACE FUNCTION _timescaledb_internal.create_chunk_table( slices JSONB, schema_name NAME, table_name NAME) -RETURNS BOOL AS '@MODULE_PATHNAME@', 'ts_chunk_create_empty_table' LANGUAGE C VOLATILE STRICT; +RETURNS BOOL AS '@MODULE_PATHNAME@', 'ts_chunk_create_empty_table' LANGUAGE C VOLATILE; diff --git a/src/error_utils.h b/src/error_utils.h new file mode 100644 index 000000000..d9087f980 --- /dev/null +++ b/src/error_utils.h @@ -0,0 +1,27 @@ +/* + * This file and its contents are licensed under the Apache License 2.0. + * Please see the included NOTICE for copyright information and + * LICENSE-APACHE for a copy of the license. + */ +#ifndef TIMESCALEDB_ERROR_UTILS_H +#define TIMESCALEDB_ERROR_UTILS_H + +#define GETARG_NOTNULL_OID(var, arg, name) \ + { \ + var = PG_ARGISNULL(arg) ? InvalidOid : PG_GETARG_OID(arg); \ + if (!OidIsValid(var)) \ + ereport(ERROR, \ + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), \ + errmsg("%s cannot be NULL", name))); \ + } + +#define GETARG_NOTNULL_NULLABLE(var, arg, name, type) \ + { \ + if (PG_ARGISNULL(arg)) \ + ereport(ERROR, \ + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), \ + errmsg("%s cannot be NULL", name))); \ + var = PG_GETARG_##type(arg); \ + } + +#endif /* TIMESCALEDB_ERROR_UTILS_H */ diff --git a/tsl/src/chunk_api.c b/tsl/src/chunk_api.c index b432eb1bf..725893681 100644 --- a/tsl/src/chunk_api.c +++ b/tsl/src/chunk_api.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -1623,20 +1624,22 @@ chunk_api_get_chunk_relstats(PG_FUNCTION_ARGS) Datum chunk_create_empty_table(PG_FUNCTION_ARGS) { - const Oid hypertable_relid = PG_GETARG_OID(0); - Jsonb *const slices = PG_GETARG_JSONB_P(1); - const char *const schema_name = PG_GETARG_CSTRING(2); - const char *const table_name = PG_GETARG_CSTRING(3); + Oid hypertable_relid; + Jsonb *slices; + const char *schema_name; + const char *table_name; Cache *const hcache = ts_hypertable_cache_pin(); - Hypertable *const ht = ts_hypertable_cache_get_entry(hcache, hypertable_relid, CACHE_FLAG_NONE); + Hypertable *ht; Hypercube *hc; const char *parse_err; AclResult acl_result; - Assert(!PG_ARGISNULL(0)); - Assert(!PG_ARGISNULL(1)); - Assert(!PG_ARGISNULL(2)); - Assert(!PG_ARGISNULL(3)); + GETARG_NOTNULL_OID(hypertable_relid, 0, "hypertable"); + GETARG_NOTNULL_NULLABLE(slices, 1, "slices", JSONB_P); + GETARG_NOTNULL_NULLABLE(schema_name, 2, "chunk schema name", CSTRING); + GETARG_NOTNULL_NULLABLE(table_name, 3, "chunk table name", CSTRING); + + ht = ts_hypertable_cache_get_entry(hcache, hypertable_relid, CACHE_FLAG_NONE); Assert(ht != NULL); acl_result = pg_class_aclcheck(hypertable_relid, GetUserId(), ACL_INSERT); diff --git a/tsl/test/expected/chunk_api.out b/tsl/test/expected/chunk_api.out index c4add79da..1f21c2598 100644 --- a/tsl/test/expected/chunk_api.out +++ b/tsl/test/expected/chunk_api.out @@ -86,15 +86,17 @@ ERROR: permission denied for table "chunkapi" DETAIL: Insert privileges required on "chunkapi" to create chunks. \set ON_ERROR_STOP 1 SET ROLE :ROLE_DEFAULT_PERM_USER; --- Test create_chunk_table is STRICT -SELECT * FROM _timescaledb_internal.create_chunk_table('chunkapi', NULL, '_timescaledb_internal','_hyper_1_1_chunk'); - create_chunk_table --------------------- - -(1 row) - -- Test create_chunk_table for errors \set ON_ERROR_STOP 0 +-- Test create_chunk_table for NULL input +SELECT * FROM _timescaledb_internal.create_chunk_table(NULL,' {"time": [1515024000000000, 1519024000000000], "device": [-9223372036854775808, 1073741823]}', '_timescaledb_internal','_hyper_1_1_chunk'); +ERROR: hypertable cannot be NULL +SELECT * FROM _timescaledb_internal.create_chunk_table('chunkapi', NULL, '_timescaledb_internal','_hyper_1_1_chunk'); +ERROR: slices cannot be NULL +SELECT * FROM _timescaledb_internal.create_chunk_table('chunkapi',' {"time": [1515024000000000, 1519024000000000], "device": [-9223372036854775808, 1073741823]}', NULL,'_hyper_1_1_chunk'); +ERROR: chunk schema name cannot be NULL +SELECT * FROM _timescaledb_internal.create_chunk_table('chunkapi',' {"time": [1515024000000000, 1519024000000000], "device": [-9223372036854775808, 1073741823]}', '_timescaledb_internal',NULL); +ERROR: chunk table name cannot be NULL -- Modified time constraint should fail with collision SELECT * FROM _timescaledb_internal.create_chunk_table('chunkapi',' {"time": [1514419600000000, 1515024000000000], "device": [-9223372036854775808, 1073741823]}', '_timescaledb_internal','_hyper_1_1_chunk'); ERROR: chunk table creation failed due to dimension slice collision diff --git a/tsl/test/sql/chunk_api.sql b/tsl/test/sql/chunk_api.sql index 664e8b98f..5ecd691a3 100644 --- a/tsl/test/sql/chunk_api.sql +++ b/tsl/test/sql/chunk_api.sql @@ -49,10 +49,13 @@ SELECT * FROM _timescaledb_internal.create_chunk('chunkapi',' {"time": [15150240 \set ON_ERROR_STOP 1 SET ROLE :ROLE_DEFAULT_PERM_USER; --- Test create_chunk_table is STRICT -SELECT * FROM _timescaledb_internal.create_chunk_table('chunkapi', NULL, '_timescaledb_internal','_hyper_1_1_chunk'); -- Test create_chunk_table for errors \set ON_ERROR_STOP 0 +-- Test create_chunk_table for NULL input +SELECT * FROM _timescaledb_internal.create_chunk_table(NULL,' {"time": [1515024000000000, 1519024000000000], "device": [-9223372036854775808, 1073741823]}', '_timescaledb_internal','_hyper_1_1_chunk'); +SELECT * FROM _timescaledb_internal.create_chunk_table('chunkapi', NULL, '_timescaledb_internal','_hyper_1_1_chunk'); +SELECT * FROM _timescaledb_internal.create_chunk_table('chunkapi',' {"time": [1515024000000000, 1519024000000000], "device": [-9223372036854775808, 1073741823]}', NULL,'_hyper_1_1_chunk'); +SELECT * FROM _timescaledb_internal.create_chunk_table('chunkapi',' {"time": [1515024000000000, 1519024000000000], "device": [-9223372036854775808, 1073741823]}', '_timescaledb_internal',NULL); -- Modified time constraint should fail with collision SELECT * FROM _timescaledb_internal.create_chunk_table('chunkapi',' {"time": [1514419600000000, 1515024000000000], "device": [-9223372036854775808, 1073741823]}', '_timescaledb_internal','_hyper_1_1_chunk'); -- Missing dimension