timescaledb/sql/main/data_table_triggers.sql
2016-11-07 11:25:58 -05:00

120 lines
3.7 KiB
PL/PgSQL

CREATE OR REPLACE FUNCTION _sysinternal.create_data_table_index(
table_oid REGCLASS,
field_name NAME,
index_type field_index_type
)
RETURNS VOID LANGUAGE PLPGSQL AS
$BODY$
DECLARE
index_name NAME;
prefix BIGINT;
BEGIN
prefix = nextval('data_table_index_name_prefix');
IF index_type = 'TIME-VALUE' THEN
index_name := format('%s-time-%s', prefix, field_name);
ELSIF index_type = 'VALUE-TIME' THEN
index_name := format('%s-%s-time', prefix, field_name);
ELSE
RAISE EXCEPTION 'Unknown index type %', index_type
USING ERRCODE = 'IO103';
END IF;
INSERT INTO data_table_index (table_oid, field_name, index_name, index_type) VALUES
(table_oid, field_name, index_name, index_type)
ON CONFLICT DO NOTHING;
END
$BODY$;
CREATE OR REPLACE FUNCTION _sysinternal.on_create_data_table()
RETURNS TRIGGER LANGUAGE PLPGSQL AS
$BODY$
DECLARE
field_row field;
BEGIN
IF TG_OP = 'UPDATE' THEN
IF (
(OLD.start_time IS NULL AND new.start_time IS NOT NULL)
OR
(OLD.end_time IS NULL AND new.end_time IS NOT NULL)
)
AND (
OLD.table_oid = NEW.table_oid AND
OLD.namespace_name = NEW.namespace_name AND
OLD.partition_number = NEW.partition_number AND
OLD.total_partitions = NEW.total_partitions AND
OLD.partitioning_field = NEW.partitioning_field
) THEN
RETURN NEW;
ELSE
RAISE EXCEPTION 'This type of update not allowed on data_table'
USING ERRCODE = 'IO101';
END IF;
END IF;
IF TG_OP <> 'INSERT' THEN
RAISE EXCEPTION 'Only inserts and updates supported on data_table table'
USING ERRCODE = 'IO101';
END IF;
FOR field_row IN SELECT f.*
FROM field AS f
WHERE f.namespace_name = NEW.namespace_name LOOP
PERFORM _sysinternal.create_data_table_index(NEW.table_oid, field_row.name, index_type)
FROM unnest(field_row.index_types) AS index_type;
END LOOP;
RETURN NEW;
END
$BODY$
SET SEARCH_PATH = 'public';
BEGIN;
DROP TRIGGER IF EXISTS trigger_on_create_data_table
ON data_table;
CREATE TRIGGER trigger_on_create_data_table AFTER INSERT OR UPDATE OR DELETE ON data_table
FOR EACH ROW EXECUTE PROCEDURE _sysinternal.on_create_data_table();
COMMIT;
CREATE OR REPLACE FUNCTION _sysinternal.on_create_data_table_index()
RETURNS TRIGGER LANGUAGE PLPGSQL AS
$BODY$
DECLARE
BEGIN
IF TG_OP <> 'INSERT' THEN
RAISE EXCEPTION 'Only inserts supported on namespace table'
USING ERRCODE = 'IO101';
END IF;
IF NEW.index_type = 'TIME-VALUE' THEN
EXECUTE format(
$$
CREATE INDEX %1$I ON %2$s
USING BTREE(time DESC NULLS LAST, %3$I)
WHERE %3$I IS NOT NULL
$$,
NEW.index_name, NEW.table_oid, NEW.field_name);
ELSIF NEW.index_type = 'VALUE-TIME' THEN
EXECUTE format(
$$
CREATE INDEX %1$I ON %2$s
USING BTREE(%3$I, time DESC NULLS LAST)
WHERE %3$I IS NOT NULL
$$,
NEW.index_name, NEW.table_oid, NEW.field_name);
ELSE
RAISE EXCEPTION 'Unknown index type %', index_type
USING ERRCODE = 'IO103';
END IF;
RETURN NEW;
END
$BODY$
SET SEARCH_PATH = 'public';
BEGIN;
DROP TRIGGER IF EXISTS trigger_on_create_data_table_index
ON data_table_index;
CREATE TRIGGER trigger_on_create_data_table_index AFTER INSERT OR UPDATE OR DELETE ON data_table_index
FOR EACH ROW EXECUTE PROCEDURE _sysinternal.on_create_data_table_index();
COMMIT;