Add support for custom hypertable dimension types

Previously, if a hypertable dimension type did not have a default
hash function, create_hypertable would throw an error.
However, this should not be the case if a custom partitioning
function is provided.
This commit addresses the issue making sure that arbitrary
custom types can be used as partitioning dimensions as long
as a valid partitioning function is provided.
Fixes #470.
This commit is contained in:
Narek Galstyan 2018-08-03 11:00:04 -04:00 committed by RobAtticus
parent dfe026c3b6
commit a97f2affef
4 changed files with 61 additions and 2 deletions

View File

@ -92,6 +92,13 @@ partitioning_func_get_default(void)
DEFAULT_PARTITIONING_FUNC_NAME);
}
bool
partitioning_func_is_default(const char *schema, const char *funcname)
{
return strcmp(DEFAULT_PARTITIONING_FUNC_SCHEMA, schema) == 0 &&
strcmp(DEFAULT_PARTITIONING_FUNC_NAME, funcname) == 0;
}
/*
* Resolve the partitioning function set for a hypertable.
*/
@ -166,8 +173,8 @@ partitioning_info_create(const char *schema,
columntype = get_atttype(relid, pinfo->column_attnum);
tce = lookup_type_cache(columntype, TYPECACHE_HASH_FLAGS);
if (tce->hash_proc == InvalidOid)
elog(ERROR, "could not find hash function for type %u", columntype);
if (tce->hash_proc == InvalidOid && partitioning_func_is_default(schema, partfunc))
elog(ERROR, "could not find hash function for type %s", format_type_be(columntype));
partitioning_func_set_func_fmgr(&pinfo->partfunc);

View File

@ -39,6 +39,7 @@ typedef struct PartitioningInfo
extern Oid partitioning_func_get_default(void);
extern bool partitioning_func_is_default(const char *schema, const char *funcname);
extern bool partitioning_func_is_valid(regproc funcoid);
extern PartitioningInfo *partitioning_info_create(const char *schema,

View File

@ -261,3 +261,31 @@ ERROR: cannot create a unique index without the column "device" (used in partit
\set ON_ERROR_STOP 1
-- NON-unique indexes can still be created
CREATE INDEX temp_index ON hyper_with_index(temp);
-- Make sure custom composite types are supported as dimensions
CREATE TYPE TUPLE as (val1 int4, val2 int4);
CREATE FUNCTION tuple_hash(value ANYELEMENT) RETURNS INT4
LANGUAGE PLPGSQL IMMUTABLE AS
$BODY$
BEGIN
RAISE NOTICE 'custom hash value is: %', value.val1+value.val2;
RETURN value.val1+value.val2;
END
$BODY$;
CREATE TABLE part_custom_dim (time TIMESTAMPTZ, combo TUPLE, device TEXT);
\set ON_ERROR_STOP 0
-- should fail because no partitioning function supplied and the given custom type
-- has no default hash function
SELECT create_hypertable('part_custom_dim', 'time', 'combo', 4);
NOTICE: adding not-null constraint to column "time"
ERROR: could not find hash function for type tuple
\set ON_ERROR_STOP 1
SELECT create_hypertable('part_custom_dim', 'time', 'combo', 4, partitioning_func=>'tuple_hash');
NOTICE: adding not-null constraint to column "time"
create_hypertable
-------------------
(1 row)
INSERT INTO part_custom_dim(time, combo) VALUES (now(), (1,2));
NOTICE: custom hash value is: 3
NOTICE: custom hash value is: 3

View File

@ -83,6 +83,7 @@ INSERT INTO part_custom_func VALUES ('2017-03-22T09:18:23', 23.4, 'dev1'),
('2017-03-22T09:18:23', 23.4, 'dev7');
SELECT * FROM test.show_subtables('part_custom_func');
-- Test that index creation is handled correctly.
CREATE TABLE hyper_with_index(time timestamptz, temp float, device int);
CREATE UNIQUE INDEX temp_index ON hyper_with_index(temp);
@ -126,3 +127,25 @@ SELECT add_dimension('hyper_with_primary', 'device', 4);
-- NON-unique indexes can still be created
CREATE INDEX temp_index ON hyper_with_index(temp);
-- Make sure custom composite types are supported as dimensions
CREATE TYPE TUPLE as (val1 int4, val2 int4);
CREATE FUNCTION tuple_hash(value ANYELEMENT) RETURNS INT4
LANGUAGE PLPGSQL IMMUTABLE AS
$BODY$
BEGIN
RAISE NOTICE 'custom hash value is: %', value.val1+value.val2;
RETURN value.val1+value.val2;
END
$BODY$;
CREATE TABLE part_custom_dim (time TIMESTAMPTZ, combo TUPLE, device TEXT);
\set ON_ERROR_STOP 0
-- should fail because no partitioning function supplied and the given custom type
-- has no default hash function
SELECT create_hypertable('part_custom_dim', 'time', 'combo', 4);
\set ON_ERROR_STOP 1
SELECT create_hypertable('part_custom_dim', 'time', 'combo', 4, partitioning_func=>'tuple_hash');
INSERT INTO part_custom_dim(time, combo) VALUES (now(), (1,2));