Initial experiments with schema_triggers
This commit is contained in:
@@ -2,3 +2,9 @@ cartodb-postgresql
|
||||
==================
|
||||
|
||||
PostgreSQL extension for CartoDB
|
||||
|
||||
Depdenencies
|
||||
------------
|
||||
|
||||
* PostgreSQL 9.3+
|
||||
* [Schema triggers extension](https://bitbucket.org/malloclabs/pg_schema_triggers)
|
||||
|
||||
160
cartodb_hooks.sql
Normal file
160
cartodb_hooks.sql
Normal file
@@ -0,0 +1,160 @@
|
||||
LOAD 'schema_triggers.so';
|
||||
CREATE EXTENSION IF NOT EXISTS schema_triggers;
|
||||
|
||||
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA schema_triggers TO public;
|
||||
|
||||
BEGIN;
|
||||
|
||||
-- Table creation
|
||||
-- {
|
||||
CREATE OR REPLACE FUNCTION cdb_handle_create_table ()
|
||||
RETURNS event_trigger SECURITY DEFINER LANGUAGE plpgsql AS $$
|
||||
DECLARE
|
||||
event_info RECORD;
|
||||
BEGIN
|
||||
event_info := schema_triggers.get_relation_create_eventinfo();
|
||||
|
||||
-- We're only interested in real relations
|
||||
IF (event_info.new).relkind != 'r' THEN RETURN; END IF;
|
||||
|
||||
RAISE NOTICE 'Relation % of kind % created in namespace oid %',
|
||||
event_info.relation, (event_info.new).relkind, (event_info.new).relnamespace;
|
||||
|
||||
-- We don't want to react to alters triggered by superuser,
|
||||
-- or we'd enter an infinite loop here
|
||||
IF current_setting('is_superuser') = 'on' THEN
|
||||
RAISE DEBUG 'no ddl trigger for superuser';
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
-- CDB_CartodbfyTable must not create tables, or infinite loop will happen
|
||||
PERFORM public.CDB_CartodbfyTable(event_info.relation);
|
||||
|
||||
END; $$;
|
||||
-- }
|
||||
|
||||
-- Column alter
|
||||
-- {
|
||||
CREATE OR REPLACE FUNCTION cdb_handle_alter_column ()
|
||||
RETURNS event_trigger SECURITY DEFINER LANGUAGE plpgsql AS $$
|
||||
DECLARE
|
||||
event_info RECORD;
|
||||
rel RECORD;
|
||||
BEGIN
|
||||
event_info := schema_triggers.get_column_alter_eventinfo();
|
||||
|
||||
SELECT oid,* FROM pg_class WHERE oid = event_info.relation INTO rel;
|
||||
|
||||
RAISE NOTICE 'Column % altered by % (superuser? %) in relation % of kind %',
|
||||
(event_info.old).attname, current_user, current_setting('is_superuser'), event_info.relation::regclass, rel.relkind;
|
||||
|
||||
-- We're only interested in real relations
|
||||
IF rel.relkind != 'r' THEN RETURN; END IF;
|
||||
|
||||
-- We don't want to react to alters triggered by superuser,
|
||||
-- or we'd enter an infinite loop here
|
||||
IF current_setting('is_superuser') = 'on' THEN
|
||||
RAISE DEBUG 'no ddl trigger for superuser';
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
PERFORM cdb_disable_ddl_hooks();
|
||||
|
||||
PERFORM public.CDB_CartodbfyTable(event_info.relation);
|
||||
|
||||
PERFORM cdb_enable_ddl_hooks();
|
||||
|
||||
-- TODO: invalidate varnish ?
|
||||
|
||||
END; $$;
|
||||
-- }
|
||||
|
||||
-- Column drop
|
||||
-- {
|
||||
CREATE OR REPLACE FUNCTION cdb_handle_drop_column ()
|
||||
RETURNS event_trigger SECURITY DEFINER LANGUAGE plpgsql AS $$
|
||||
DECLARE
|
||||
event_info RECORD;
|
||||
rel RECORD;
|
||||
BEGIN
|
||||
event_info := schema_triggers.get_column_drop_eventinfo();
|
||||
|
||||
SELECT oid,* FROM pg_class WHERE oid = event_info.relation INTO rel;
|
||||
|
||||
RAISE NOTICE 'Column % drop by % (superuser? %) in relation % of kind %',
|
||||
(event_info.old).attname, current_user, current_setting('is_superuser'), event_info.relation::regclass, rel.relkind;
|
||||
|
||||
-- We're only interested in real relations
|
||||
IF rel.relkind != 'r' THEN RETURN; END IF;
|
||||
|
||||
-- We don't want to react to drops triggered by superuser,
|
||||
-- or we'd enter an infinite loop here
|
||||
IF current_setting('is_superuser') = 'on' THEN
|
||||
RAISE DEBUG 'no ddl trigger for superuser';
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
PERFORM cdb_disable_ddl_hooks();
|
||||
|
||||
PERFORM public.CDB_CartodbfyTable(event_info.relation);
|
||||
|
||||
PERFORM cdb_enable_ddl_hooks();
|
||||
|
||||
-- TODO: invalidate varnish ?
|
||||
|
||||
END; $$;
|
||||
-- }
|
||||
|
||||
-- Column add
|
||||
-- {
|
||||
CREATE OR REPLACE FUNCTION cdb_handle_add_column ()
|
||||
RETURNS event_trigger SECURITY DEFINER LANGUAGE plpgsql AS $$
|
||||
DECLARE
|
||||
event_info RECORD;
|
||||
rel RECORD;
|
||||
BEGIN
|
||||
event_info := schema_triggers.get_column_add_eventinfo();
|
||||
|
||||
SELECT oid,* FROM pg_class WHERE oid = event_info.relation INTO rel;
|
||||
|
||||
RAISE NOTICE 'Column % add by % (superuser? %) in relation % of kind %',
|
||||
(event_info.old).attname, current_user, current_setting('is_superuser'), event_info.relation::regclass, rel.relkind;
|
||||
|
||||
-- We're only interested in real relations
|
||||
IF rel.relkind != 'r' THEN RETURN; END IF;
|
||||
|
||||
-- We don't want to react to drops triggered by superuser,
|
||||
-- or we'd enter an infinite loop here
|
||||
IF current_setting('is_superuser') = 'on' THEN
|
||||
RAISE DEBUG 'no ddl trigger for superuser';
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
--PERFORM cdb_disable_ddl_hooks();
|
||||
--PERFORM public.CDB_CartodbfyTable(event_info.relation);
|
||||
--PERFORM cdb_enable_ddl_hooks();
|
||||
|
||||
-- TODO: invalidate varnish ?
|
||||
|
||||
END; $$;
|
||||
-- }
|
||||
|
||||
CREATE OR REPLACE FUNCTION cdb_disable_ddl_hooks() returns void AS $$
|
||||
DROP EVENT TRIGGER IF EXISTS cdb_on_relation_create;
|
||||
DROP EVENT TRIGGER IF EXISTS cdb_on_alter_column;
|
||||
DROP EVENT TRIGGER IF EXISTS cdb_on_drop_column;
|
||||
DROP EVENT TRIGGER IF EXISTS cdb_on_add_column;
|
||||
$$ LANGUAGE sql;
|
||||
|
||||
CREATE OR REPLACE FUNCTION cdb_enable_ddl_hooks() returns void AS $$
|
||||
SELECT cdb_disable_ddl_hooks();
|
||||
CREATE EVENT TRIGGER cdb_on_relation_create ON "relation_create" EXECUTE PROCEDURE cdb_handle_create_table();
|
||||
CREATE EVENT TRIGGER cdb_on_alter_column ON "column_alter" EXECUTE PROCEDURE cdb_handle_alter_column();
|
||||
CREATE EVENT TRIGGER cdb_on_drop_column ON "column_drop" EXECUTE PROCEDURE cdb_handle_drop_column();
|
||||
CREATE EVENT TRIGGER cdb_on_add_column ON "column_drop" EXECUTE PROCEDURE cdb_handle_add_column();
|
||||
$$ LANGUAGE sql;
|
||||
|
||||
SELECT cdb_enable_ddl_hooks();
|
||||
|
||||
END;
|
||||
|
||||
19
hook_on_table_create.sql
Normal file
19
hook_on_table_create.sql
Normal file
@@ -0,0 +1,19 @@
|
||||
\i cartodb_hooks.sql
|
||||
\set VERBOSITY terse
|
||||
|
||||
SET SESSION AUTHORIZATION 'development_cartodb_user_1';
|
||||
|
||||
SELECT session_user, current_user;
|
||||
|
||||
|
||||
create schema c;
|
||||
--create table c.t3(a int);
|
||||
select 1 as i INTO c.t3;
|
||||
select * from c.t3;
|
||||
alter table c.t3 rename column the_geom_webmercator to webmerc;
|
||||
select * from c.t3;
|
||||
alter table c.t3 rename column the_geom_webmercator to webmerc2;
|
||||
select * from c.t3;
|
||||
alter table c.t3 drop column the_geom_webmercator;
|
||||
select * from c.t3;
|
||||
drop schema c cascade;
|
||||
Reference in New Issue
Block a user