diff --git a/scripts-available/CDB_GhostTables.sql b/scripts-available/CDB_GhostTables.sql index 21b3d95..2f9e40e 100644 --- a/scripts-available/CDB_GhostTables.sql +++ b/scripts-available/CDB_GhostTables.sql @@ -1,8 +1,5 @@ --- Table to store the transaction id from DDL events to avoid multiple executions -CREATE TABLE IF NOT EXISTS cartodb.cdb_ddl_execution(txid integer PRIMARY KEY, tag text); - --- Enqueues a job to run Ghost tables linking process for the provided user_id -CREATE OR REPLACE FUNCTION _CDB_LinkGhostTables(username text, db_name text, ddl_tag text) +-- Enqueues a job to run Ghost tables linking process for the provided username +CREATE OR REPLACE FUNCTION _CDB_LinkGhostTables(username text, db_name text, event_name text) RETURNS void AS $$ if not username: @@ -37,7 +34,7 @@ AS $$ break try: - client.execute_command('DBSCH', db_name, username, ddl_tag) + client.execute_command('DBSCH', db_name, username, event_name) break except Exception as err: error = "request_error - %s" % str(err) @@ -49,20 +46,18 @@ AS $$ $$ LANGUAGE 'plpythonu' VOLATILE PARALLEL UNSAFE; -- Enqueues a job to run Ghost tables linking process for the current user -CREATE OR REPLACE FUNCTION CDB_LinkGhostTables() +CREATE OR REPLACE FUNCTION CDB_LinkGhostTables(event_name text DEFAULT 'USER') RETURNS void AS $$ DECLARE username TEXT; db_name TEXT; - ddl_tag TEXT; BEGIN EXECUTE 'SELECT CDB_Username();' INTO username; EXECUTE 'SELECT current_database();' INTO db_name; - EXECUTE 'SELECT tag FROM cartodb.cdb_ddl_execution WHERE txid = txid_current();' INTO ddl_tag; - PERFORM _CDB_LinkGhostTables(username, db_name, ddl_tag); - DELETE FROM cartodb.cdb_ddl_execution WHERE txid = txid_current(); - RAISE NOTICE '_CDB_LinkGhostTables() called with username=%, ddl_tag=%', username, ddl_tag; + + PERFORM _CDB_LinkGhostTables(username, db_name, event_name); + RAISE NOTICE '_CDB_LinkGhostTables() called with username=%, event_name=%', username, event_name; END; $$ LANGUAGE plpgsql VOLATILE PARALLEL UNSAFE SECURITY DEFINER; @@ -70,8 +65,12 @@ $$ LANGUAGE plpgsql VOLATILE PARALLEL UNSAFE SECURITY DEFINER; CREATE OR REPLACE FUNCTION _CDB_LinkGhostTablesTrigger() RETURNS trigger AS $$ + DECLARE + ddl_tag TEXT; BEGIN - PERFORM CDB_LinkGhostTables(); + EXECUTE 'SELECT tag FROM cartodb.cdb_ddl_execution WHERE txid = txid_current();' INTO ddl_tag; + DELETE FROM cartodb.cdb_ddl_execution WHERE txid = txid_current(); + PERFORM CDB_LinkGhostTables(ddl_tag); RETURN NULL; END; $$ LANGUAGE plpgsql VOLATILE PARALLEL UNSAFE SECURITY DEFINER; @@ -93,6 +92,9 @@ AS $$ DROP EVENT TRIGGER IF EXISTS link_ghost_tables; DROP TRIGGER IF EXISTS check_ddl_update ON cartodb.cdb_ddl_execution; + -- Table to store the transaction id from DDL events to avoid multiple executions + CREATE TABLE IF NOT EXISTS cartodb.cdb_ddl_execution(txid integer PRIMARY KEY, tag text); + CREATE CONSTRAINT TRIGGER check_ddl_update AFTER INSERT ON cartodb.cdb_ddl_execution INITIALLY DEFERRED @@ -113,5 +115,6 @@ AS $$ BEGIN DROP EVENT TRIGGER IF EXISTS link_ghost_tables; DROP TRIGGER IF EXISTS check_ddl_update ON cartodb.cdb_ddl_execution; + DROP TABLE IF EXISTS cartodb.cdb_ddl_execution; END; $$ LANGUAGE plpgsql VOLATILE PARALLEL UNSAFE; diff --git a/test/CDB_GhostTables.sql b/test/CDB_GhostTables.sql index e9aa8fa..33fae5b 100644 --- a/test/CDB_GhostTables.sql +++ b/test/CDB_GhostTables.sql @@ -1,12 +1,12 @@ -- Create user and enable Ghost tables trigger \set QUIET on SET client_min_messages TO error; +SELECT CDB_EnableGhostTablesTrigger(); CREATE ROLE "fulano" LOGIN; GRANT ALL ON SCHEMA cartodb TO "fulano"; GRANT SELECT ON cartodb.cdb_ddl_execution TO "fulano"; GRANT EXECUTE ON FUNCTION CDB_Username() TO "fulano"; -GRANT EXECUTE ON FUNCTION CDB_LinkGhostTables() TO "fulano"; -SELECT CDB_EnableGhostTablesTrigger(); +GRANT EXECUTE ON FUNCTION CDB_LinkGhostTables(text) TO "fulano"; INSERT INTO cdb_conf (key, value) VALUES ('api_keys_fulano', '{"username": "fulanito", "permissions":[]}'); INSERT INTO cdb_conf (key, value) VALUES ('invalidation_service', '{"host": "fake-tis-host"}'); SET SESSION AUTHORIZATION "fulano"; @@ -16,6 +16,7 @@ SET client_min_messages TO notice; SELECT CDB_LinkGhostTables(); -- _CDB_LinkGhostTables called BEGIN; +SELECT to_regclass('cartodb.cdb_ddl_execution'); -- exists SELECT COUNT(*) FROM cartodb.cdb_ddl_execution; -- 0 CREATE TABLE tmp(id INT); SELECT COUNT(*) FROM cartodb.cdb_ddl_execution; -- 1 @@ -28,18 +29,14 @@ SELECT CDB_DisableGhostTablesTrigger(); SET SESSION AUTHORIZATION "fulano"; \set QUIET off -BEGIN; -SELECT COUNT(*) FROM cartodb.cdb_ddl_execution; -- 0 -DROP TABLE tmp; -SELECT COUNT(*) FROM cartodb.cdb_ddl_execution; -- 0 -END; -- _CDB_LinkGhostTables not called +SELECT to_regclass('cartodb.cdb_ddl_execution'); -- not exists +DROP TABLE tmp; -- _CDB_LinkGhostTables not called --- Clean up +-- Cleanup \set QUIET on SET SESSION AUTHORIZATION postgres; -REVOKE EXECUTE ON FUNCTION CDB_LinkGhostTables() FROM "fulano"; +REVOKE EXECUTE ON FUNCTION CDB_LinkGhostTables(text) FROM "fulano"; REVOKE EXECUTE ON FUNCTION CDB_Username() FROM "fulano"; -REVOKE SELECT ON cartodb.cdb_ddl_execution FROM "fulano"; REVOKE ALL ON SCHEMA cartodb FROM "fulano"; DROP ROLE "fulano"; DELETE FROM cdb_conf WHERE key = 'api_keys_fulano' OR key = 'invalidation_service'; diff --git a/test/CDB_GhostTables_expect b/test/CDB_GhostTables_expect index e6d6fb5..3e46518 100644 --- a/test/CDB_GhostTables_expect +++ b/test/CDB_GhostTables_expect @@ -1,17 +1,15 @@ WARNING: Invalidation Service error: Error -2 connecting fake-tis-host:3142. Name or service not known. -NOTICE: _CDB_LinkGhostTables() called with username=fulanito, ddl_tag= +NOTICE: _CDB_LinkGhostTables() called with username=fulanito, event_name=USER BEGIN +cdb_ddl_execution 0 CREATE TABLE 1 WARNING: Invalidation Service error: Error -2 connecting fake-tis-host:3142. Name or service not known. -NOTICE: _CDB_LinkGhostTables() called with username=fulanito, ddl_tag=CREATE TABLE +NOTICE: _CDB_LinkGhostTables() called with username=fulanito, event_name=CREATE TABLE COMMIT -BEGIN -0 + DROP TABLE -0 -COMMIT