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;