timescaledb/sql/main/hypertable_triggers.sql
Matvey Arye 67ad21ee36 Cache hypertable metadata information for faster inserts.
Add caches for hypertable metadata to make it faster to map
INSERT rows to the chunk they should go into.
2017-03-02 12:24:53 +01:00

99 lines
3.4 KiB
PL/PgSQL

-- This file contains triggers that act on the main 'hypertable' table as
-- well as triggers for newly created hypertables.
-- Trigger to prevent unsupported operations on the main table.
-- Our C code should rewrite a DELETE or UPDATE to apply to the replica and not main table.
-- The only exception is if we use ONLY, which should be an error.
CREATE OR REPLACE FUNCTION _iobeamdb_internal.on_unsupported_main_table()
RETURNS TRIGGER LANGUAGE PLPGSQL AS
$BODY$
BEGIN
IF TG_OP = 'UPDATE' THEN
RAISE EXCEPTION 'UPDATE ONLY not supported on hypertables'
USING ERRCODE = 'IO101';
ELSIF TG_OP = 'DELETE' AND current_setting('io.ignore_delete_in_trigger', true) IS DISTINCT FROM 'true' THEN
RAISE EXCEPTION 'DELETE ONLY not currently supported on hypertables'
USING ERRCODE = 'IO101';
END IF;
RETURN NEW;
END
$BODY$;
--Trigger for when stuff is inserted into main table (error because everything should go through a temp table)
CREATE OR REPLACE FUNCTION _iobeamdb_internal.on_modify_main_table()
RETURNS TRIGGER LANGUAGE PLPGSQL AS
$BODY$
BEGIN
RAISE EXCEPTION 'Should never be inserting data directly into main table'
USING ERRCODE = 'IO501';
END
$BODY$;
-- Trigger for handling the addition of new hypertables.
CREATE OR REPLACE FUNCTION _iobeamdb_internal.on_change_hypertable()
RETURNS TRIGGER LANGUAGE PLPGSQL AS
$BODY$
DECLARE
remote_node _iobeamdb_catalog.node;
BEGIN
IF TG_OP = 'INSERT' THEN
EXECUTE format(
$$
CREATE SCHEMA IF NOT EXISTS %I
$$, NEW.associated_schema_name);
PERFORM _iobeamdb_internal.create_table(NEW.root_schema_name, NEW.root_table_name);
IF NEW.created_on <> current_database() THEN
PERFORM _iobeamdb_internal.create_schema(NEW.schema_name);
PERFORM _iobeamdb_internal.create_table(NEW.schema_name, NEW.table_name);
END IF;
-- UPDATE not supported, so do them before action
EXECUTE format(
$$
CREATE TRIGGER modify_trigger BEFORE UPDATE OR DELETE ON %I.%I
FOR EACH STATEMENT EXECUTE PROCEDURE _iobeamdb_internal.on_unsupported_main_table();
$$, NEW.schema_name, NEW.table_name);
EXECUTE format(
$$
CREATE TRIGGER insert_trigger AFTER INSERT ON %I.%I
FOR EACH STATEMENT EXECUTE PROCEDURE _iobeamdb_internal.on_modify_main_table();
$$, NEW.schema_name, NEW.table_name);
RETURN NEW;
END IF;
PERFORM _iobeamdb_internal.on_trigger_error(TG_OP, TG_TABLE_SCHEMA, TG_TABLE_NAME);
END
$BODY$
SET client_min_messages = WARNING; --suppress NOTICE on IF EXISTS schema
/*
Drops public hypertable when hypertable rows deleted (row created in deleted_hypertable table).
*/
CREATE OR REPLACE FUNCTION _iobeamdb_internal.on_change_deleted_hypertable()
RETURNS TRIGGER LANGUAGE PLPGSQL AS
$BODY$
DECLARE
hypertable_row _iobeamdb_catalog.hypertable;
BEGIN
IF TG_OP <> 'INSERT' THEN
PERFORM _iobeamdb_internal.on_trigger_error(TG_OP, TG_TABLE_SCHEMA, TG_TABLE_NAME);
END IF;
--drop index on all chunks
PERFORM _iobeamdb_internal.drop_root_table(NEW.root_schema_name, NEW.root_table_name);
IF new.deleted_on <> current_database() THEN
PERFORM set_config('io.ignore_ddl_in_trigger', 'true', true);
EXECUTE format('DROP TABLE %I.%I', NEW.schema_name, NEW.table_name);
END IF;
RETURN NEW;
END
$BODY$
;