diff --git a/schema_cache.rst b/schema_cache.rst index 1e708876d..11d0f9510 100644 --- a/schema_cache.rst +++ b/schema_cache.rst @@ -160,4 +160,72 @@ To disable auto reloading, drop the trigger: .. code-block:: postgresql - DROP EVENT TRIGGER pgrst_watch \ No newline at end of file + DROP EVENT TRIGGER pgrst_watch + +Finer-Grained Event Trigger +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can refine the previous event trigger and only react to the events relevant to the schema cache. This also prevents unnecessary +reloading when creating temporary tables(``CREATE TEMP TABLE``) inside functions. + +.. code-block:: postgresql + + -- watch create and alter + CREATE OR REPLACE FUNCTION pgrst_ddl_watch() RETURNS event_trigger AS $$ + DECLARE + cmd record; + BEGIN + FOR cmd IN SELECT * FROM pg_event_trigger_ddl_commands() + LOOP + IF cmd.command_tag IN ( + 'CREATE SCHEMA', 'ALTER SCHEMA' + , 'CREATE TABLE', 'CREATE TABLE AS', 'SELECT INTO', 'ALTER TABLE' + , 'CREATE FOREIGN TABLE', 'ALTER FOREIGN TABLE' + , 'CREATE VIEW', 'ALTER VIEW' + , 'CREATE MATERIALIZED VIEW', 'ALTER MATERIALIZED VIEW' + , 'CREATE FUNCTION', 'ALTER FUNCTION' + , 'CREATE TRIGGER' + , 'CREATE TYPE' + , 'CREATE RULE' + , 'COMMENT' + ) + -- don't notify in case of CREATE TEMP table or other objects created on pg_temp + AND cmd.schema_name is distinct from 'pg_temp' + THEN + NOTIFY pgrst, 'reload schema'; + END IF; + END LOOP; + END; $$ LANGUAGE plpgsql; + + -- watch drop + CREATE OR REPLACE FUNCTION pgrst_drop_watch() RETURNS event_trigger AS $$ + DECLARE + obj record; + BEGIN + FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects() + LOOP + IF obj.object_type IN ( + 'schema' + , 'table' + , 'foreign table' + , 'view' + , 'materialized view' + , 'function' + , 'trigger' + , 'type' + , 'rule' + ) + AND obj.is_temporary IS false -- no pg_temp objects + THEN + NOTIFY pgrst, 'reload schema'; + END IF; + END LOOP; + END; $$ LANGUAGE plpgsql; + + CREATE EVENT TRIGGER pgrst_ddl_watch + ON ddl_command_end + EXECUTE PROCEDURE pgrst_ddl_watch(); + + CREATE EVENT TRIGGER pgrst_drop_watch + ON sql_drop + EXECUTE PROCEDURE pgrst_drop_watch();