mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-17 19:13:16 +08:00
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.
36 lines
1.1 KiB
PL/PgSQL
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
|