timescaledb/sql/hypertable_triggers.sql
Erik Nordström 1f3dcd814f Make INSERTs use a custom plan instead of triggers
With this change, hypertables no longer rely on an INSERT trigger to
dispatch tuples to chunks. While an INSERT trigger worked well for
both INSERTs and COPYs, it caused issues with supporting some regular
triggers on hypertables, and didn't support RETURNING statements and
upserts (ON CONFLICT DO UPDATE).

INSERTs are now handled by modifying the plan for INSERT statements. A
custom plan node is inserted as a subplan to a ModifyTable plan node,
taking care of dispatching tuples to chunks by setting the result
table for every tuple scanned.

COPYs are handled by modifying the regular copy code. Unfortunately,
this required copying a significant amount of regular PostgreSQL
source code since there are no hooks to add modifications. However,
since the modifications are small it should be fairly easy to keep the
code in sync with upstream changes.
2017-07-27 15:49:01 +02:00

36 lines
1.1 KiB
PL/PgSQL

-- This file contains triggers that act on the main 'hypertable' table as
-- well as triggers for newly created hypertables.
CREATE OR REPLACE FUNCTION _timescaledb_internal.on_change_hypertable()
RETURNS TRIGGER LANGUAGE PLPGSQL AS
$BODY$
DECLARE
BEGIN
IF TG_OP = 'INSERT' THEN
DECLARE
cnt INTEGER;
BEGIN
EXECUTE format(
$$
CREATE SCHEMA IF NOT EXISTS %I
$$, NEW.associated_schema_name);
EXCEPTION
WHEN insufficient_privilege THEN
SELECT COUNT(*) INTO cnt
FROM pg_namespace
WHERE nspname = NEW.associated_schema_name;
IF cnt = 0 THEN
RAISE;
END IF;
END;
RETURN NEW;
ELSIF TG_OP = 'DELETE' THEN
RETURN OLD;
ELSIF TG_OP = 'UPDATE' THEN
RETURN NEW;
END IF;
PERFORM _timescaledb_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