mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-18 19:59:48 +08:00
164 lines
5.2 KiB
PL/PgSQL
164 lines
5.2 KiB
PL/PgSQL
-- This file defines DDL functions for adding and manipulating hypertables.
|
|
|
|
-- Converts a regular postgres table to a hypertable.
|
|
--
|
|
-- main_table - The OID of the table to be converted
|
|
-- time_column_name - Name of the column that contains time for a given record
|
|
-- partitioning_column - Name of the column to partition data by
|
|
-- replication_factor -- (Optional) Number of replicas for data
|
|
-- number_partitions - (Optional) Number of partitions for data
|
|
-- associated_schema_name - (Optional) Schema for internal hypertable tables
|
|
-- associated_table_prefix - (Optional) Prefix for internal hypertable table names
|
|
CREATE OR REPLACE FUNCTION create_hypertable(
|
|
main_table REGCLASS,
|
|
time_column_name NAME,
|
|
partitioning_column NAME = NULL,
|
|
replication_factor SMALLINT = 1,
|
|
number_partitions SMALLINT = NULL,
|
|
associated_schema_name NAME = NULL,
|
|
associated_table_prefix NAME = NULL,
|
|
placement _iobeamdb_catalog.chunk_placement_type = 'STICKY',
|
|
chunk_size_bytes BIGINT = 1073741824 -- 1 GB
|
|
)
|
|
RETURNS VOID LANGUAGE PLPGSQL VOLATILE AS
|
|
$BODY$
|
|
DECLARE
|
|
hypertable_row _iobeamdb_catalog.hypertable;
|
|
table_name NAME;
|
|
schema_name NAME;
|
|
time_column_type REGTYPE;
|
|
att_row pg_attribute;
|
|
main_table_has_items BOOLEAN;
|
|
BEGIN
|
|
SELECT relname, nspname
|
|
INTO STRICT table_name, schema_name
|
|
FROM pg_class c
|
|
INNER JOIN pg_namespace n ON (n.OID = c.relnamespace)
|
|
WHERE c.OID = main_table;
|
|
|
|
BEGIN
|
|
SELECT atttypid
|
|
INTO STRICT time_column_type
|
|
FROM pg_attribute
|
|
WHERE attrelid = main_table AND attname = time_column_name;
|
|
EXCEPTION
|
|
WHEN NO_DATA_FOUND THEN
|
|
RAISE EXCEPTION 'column "%" does not exist', time_column_name
|
|
USING ERRCODE = 'IO102';
|
|
END;
|
|
|
|
IF time_column_type NOT IN ('BIGINT', 'INTEGER', 'SMALLINT', 'TIMESTAMP', 'TIMESTAMPTZ') THEN
|
|
RAISE EXCEPTION 'illegal type for time column "%": %', time_column_name, time_column_type
|
|
USING ERRCODE = 'IO102';
|
|
END IF;
|
|
|
|
IF partitioning_column IS NOT NULL THEN
|
|
PERFORM atttypid
|
|
FROM pg_attribute
|
|
WHERE attrelid = main_table AND attname = partitioning_column;
|
|
|
|
IF NOT FOUND THEN
|
|
RAISE EXCEPTION 'column "%" does not exist', partitioning_column
|
|
USING ERRCODE = 'IO102';
|
|
END IF;
|
|
END IF;
|
|
|
|
EXECUTE format('SELECT TRUE FROM %s LIMIT 1', main_table) INTO main_table_has_items;
|
|
|
|
IF main_table_has_items THEN
|
|
RAISE EXCEPTION 'the table being converted to a hypertable must be empty'
|
|
USING ERRCODE = 'IO102';
|
|
END IF;
|
|
|
|
BEGIN
|
|
SELECT *
|
|
INTO hypertable_row
|
|
FROM _iobeamdb_meta_api.create_hypertable(
|
|
schema_name,
|
|
table_name,
|
|
time_column_name,
|
|
time_column_type,
|
|
partitioning_column,
|
|
replication_factor,
|
|
number_partitions,
|
|
associated_schema_name,
|
|
associated_table_prefix,
|
|
placement,
|
|
chunk_size_bytes
|
|
);
|
|
EXCEPTION
|
|
WHEN unique_violation THEN
|
|
RAISE EXCEPTION 'hypertable % already exists', main_table
|
|
USING ERRCODE = 'IO110';
|
|
WHEN foreign_key_violation THEN
|
|
RAISE EXCEPTION 'database not configured for hypertable storage (not setup as a data-node)'
|
|
USING ERRCODE = 'IO101';
|
|
END;
|
|
|
|
FOR att_row IN SELECT *
|
|
FROM pg_attribute att
|
|
WHERE attrelid = main_table AND attnum > 0 AND NOT attisdropped
|
|
LOOP
|
|
PERFORM _iobeamdb_internal.create_column_from_attribute(hypertable_row.id, att_row);
|
|
END LOOP;
|
|
|
|
|
|
PERFORM 1
|
|
FROM pg_index,
|
|
LATERAL _iobeamdb_meta_api.add_index(
|
|
hypertable_row.id,
|
|
hypertable_row.schema_name,
|
|
(SELECT relname FROM pg_class WHERE oid = indexrelid::regclass),
|
|
_iobeamdb_internal.get_general_index_definition(indexrelid, indrelid)
|
|
)
|
|
WHERE indrelid = main_table;
|
|
END
|
|
$BODY$;
|
|
|
|
-- Sets the is_distinct flag for column on a hypertable.
|
|
-- The is_distinct flag determines whether the system keep a materialized list
|
|
-- of distinct values for the column.
|
|
CREATE OR REPLACE FUNCTION set_is_distinct_flag(
|
|
main_table REGCLASS,
|
|
column_name NAME,
|
|
is_distinct BOOLEAN
|
|
|
|
)
|
|
RETURNS VOID LANGUAGE PLPGSQL VOLATILE AS
|
|
$BODY$
|
|
DECLARE
|
|
t_name NAME;
|
|
s_name NAME;
|
|
hypertable_row _iobeamdb_catalog.hypertable;
|
|
BEGIN
|
|
SELECT relname, nspname
|
|
INTO STRICT t_name, s_name
|
|
FROM pg_class c
|
|
INNER JOIN pg_namespace n ON (n.OID = c.relnamespace)
|
|
WHERE c.OID = main_table;
|
|
|
|
SELECT * INTO hypertable_row
|
|
FROM _iobeamdb_catalog.hypertable h
|
|
WHERE h.schema_name = s_name AND h.table_name = t_name;
|
|
|
|
PERFORM atttypid
|
|
FROM pg_attribute
|
|
WHERE attrelid = main_table AND attname = column_name;
|
|
|
|
IF NOT FOUND THEN
|
|
RAISE EXCEPTION 'column "%" does not exist', column_name
|
|
USING ERRCODE = 'IO100';
|
|
END IF;
|
|
|
|
|
|
PERFORM _iobeamdb_internal.meta_transaction_exec(
|
|
format('SELECT _iobeamdb_meta.alter_column_set_is_distinct(%L, %L, %L, %L)',
|
|
hypertable_row.id,
|
|
column_name,
|
|
is_distinct,
|
|
current_database()
|
|
)
|
|
);
|
|
END
|
|
$BODY$;
|