Return error for NULL input to create_chunk_table

Gives errors if any argument of create_chunk_table is NULL instead of
being STRICT. Utilizes newly added macros for this.
This commit is contained in:
Ruslan Fomkin 2021-04-22 10:11:14 +02:00 committed by Dmitry Simonenko
parent 28ccecbe7c
commit 34e99a1c23
5 changed files with 54 additions and 19 deletions

View File

@ -69,4 +69,4 @@ CREATE OR REPLACE FUNCTION _timescaledb_internal.create_chunk_table(
slices JSONB, slices JSONB,
schema_name NAME, schema_name NAME,
table_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;

27
src/error_utils.h Normal file
View File

@ -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 */

View File

@ -30,6 +30,7 @@
#include <chunk.h> #include <chunk.h>
#include <chunk_data_node.h> #include <chunk_data_node.h>
#include <errors.h> #include <errors.h>
#include <error_utils.h>
#include <hypercube.h> #include <hypercube.h>
#include <hypertable.h> #include <hypertable.h>
#include <hypertable_cache.h> #include <hypertable_cache.h>
@ -1623,20 +1624,22 @@ chunk_api_get_chunk_relstats(PG_FUNCTION_ARGS)
Datum Datum
chunk_create_empty_table(PG_FUNCTION_ARGS) chunk_create_empty_table(PG_FUNCTION_ARGS)
{ {
const Oid hypertable_relid = PG_GETARG_OID(0); Oid hypertable_relid;
Jsonb *const slices = PG_GETARG_JSONB_P(1); Jsonb *slices;
const char *const schema_name = PG_GETARG_CSTRING(2); const char *schema_name;
const char *const table_name = PG_GETARG_CSTRING(3); const char *table_name;
Cache *const hcache = ts_hypertable_cache_pin(); 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; Hypercube *hc;
const char *parse_err; const char *parse_err;
AclResult acl_result; AclResult acl_result;
Assert(!PG_ARGISNULL(0)); GETARG_NOTNULL_OID(hypertable_relid, 0, "hypertable");
Assert(!PG_ARGISNULL(1)); GETARG_NOTNULL_NULLABLE(slices, 1, "slices", JSONB_P);
Assert(!PG_ARGISNULL(2)); GETARG_NOTNULL_NULLABLE(schema_name, 2, "chunk schema name", CSTRING);
Assert(!PG_ARGISNULL(3)); 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); Assert(ht != NULL);
acl_result = pg_class_aclcheck(hypertable_relid, GetUserId(), ACL_INSERT); acl_result = pg_class_aclcheck(hypertable_relid, GetUserId(), ACL_INSERT);

View File

@ -86,15 +86,17 @@ ERROR: permission denied for table "chunkapi"
DETAIL: Insert privileges required on "chunkapi" to create chunks. DETAIL: Insert privileges required on "chunkapi" to create chunks.
\set ON_ERROR_STOP 1 \set ON_ERROR_STOP 1
SET ROLE :ROLE_DEFAULT_PERM_USER; 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 -- Test create_chunk_table for errors
\set ON_ERROR_STOP 0 \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 -- 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'); 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 ERROR: chunk table creation failed due to dimension slice collision

View File

@ -49,10 +49,13 @@ SELECT * FROM _timescaledb_internal.create_chunk('chunkapi',' {"time": [15150240
\set ON_ERROR_STOP 1 \set ON_ERROR_STOP 1
SET ROLE :ROLE_DEFAULT_PERM_USER; 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 -- Test create_chunk_table for errors
\set ON_ERROR_STOP 0 \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 -- 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'); SELECT * FROM _timescaledb_internal.create_chunk_table('chunkapi',' {"time": [1514419600000000, 1515024000000000], "device": [-9223372036854775808, 1073741823]}', '_timescaledb_internal','_hyper_1_1_chunk');
-- Missing dimension -- Missing dimension