Postgresql
PostgreSQL 事件觸發器強制將擴展安裝到特定模式中
我有一個專用架構
extensions
(PostgreSQL v 9.6.3),我打算在其中為我的數據庫安裝所有擴展。我想以某種方式禁止(或至少提醒)使用者在未指定特定架構的情況下安裝擴展。所以這應該失敗
CREATE EXTENSION tablefunc;
但這應該成功:
CREATE EXTENSION tablefunc SCHEMA extensions;
為此,我嘗試創建事件觸發器:
CREATE EVENT TRIGGER e010_verify_extension_schema_et ON ddl_command_end WHEN TAG IN ('CREATE EXTENSION') EXECUTE PROCEDURE verify_extension_schema();
在
verify_extension_schema()
功能上我試圖利用pg_catalog.pg_event_trigger_ddl_commands()
. 但是,該函式不會返回任何我可以用來檢查是否已指定架構或與此相關的架構…有誰知道我如何做到這一點?
確保您正在使用
ddl_command_end
,它仍然會失敗或提醒使用者您想要什麼。從文件中,類似地,如果**
ddl_command_end
觸發器因錯誤而失敗,則 DDL 語句的效果將被回滾**,就像在包含事務中止的任何其他情況下一樣。不幸的是,在那之後你有兩個選擇
- 處理它可能會做出假設,但只知道安裝擴展的位置。例如,
CREATE EXTENSION x WITH SCHEMA CURRENT_SCHEMA
和CREATE EXTENSION x
將被混為一談。無法簡單訪問執行的命令,因為一些簡單的命令發出多個命令(例如,serial
作為宏)。pg_ddl_command
使用 C 函式處理內部。因為第二個選項聽起來不那麼快樂,所以讓我們選擇第一個。
查看Capturing Changes at Command End下的列表,該列表支持
objid
從 SRF 返回pg_event_trigger_ddl_commands()
。注意,schema_name
不是你所追求的。CREATE OR REPLACE FUNCTION verify_extension_schema() RETURNS event_trigger AS $$ DECLARE schemafail bool; BEGIN schemafail = ( SELECT n.nspname = 'public' FROM pg_event_trigger_ddl_commands() AS ev INNER JOIN pg_catalog.pg_extension AS e ON ev.objid = e.oid INNER JOIN pg_catalog.pg_namespace AS n ON e.extnamespace = n.oid ); IF schemafail THEN RAISE EXCEPTION 'Creating extensions into "public" is disabled'; END IF; END; $$ LANGUAGE plpgsql; CREATE EVENT TRIGGER nag_my_users ON ddl_command_end WHEN TAG IN ('CREATE EXTENSION') EXECUTE PROCEDURE verify_extension_schema();
現在你可以
test=# CREATE EXTENSION intarray ; ERROR: Creating extensions into "public" is disabled test=# CREATE EXTENSION intarray WITH SCHEMA public; ERROR: Creating extensions into "public" is disabled test=# CREATE EXTENSION intarray WITH SCHEMA foo; CREATE EXTENSION
如果您只想要一個通知,您可以將其更改為
RAISE NOTICE