web-dev-qa-db-ja.com

拡張機能のインストールを特定のスキーマに強制するPostgreSQLイベントトリガー

専用スキーマextensions(PostgreSQL v 9.6.3)を使用しており、DBのすべての拡張機能をインストールするつもりです。特定のスキーマを指定せずに拡張機能をインストールするユーザーを何らかの形で許可しない(または少なくとも思い出させる)ようにしたい.

これは失敗するはずです

_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()を利用しようとしています。ただし、関数は、スキーマが指定されているかどうか、またはどのスキーマが問題であるかを確認するために使用できるものを返しません...

私がこれをどのように達成できるかについて誰かが何かアイデアを持っていますか?

4
zam6ak

_ddl_command_end_を使用していることを確認してください。それでも失敗したり、ユーザーに通知したりすることができます。 ドキュメントから

同様に、_ddl_command_end_トリガーがエラーで失敗した場合、DDLステートメントの効果がロールバックされます。それを含むトランザクションが異常終了するその他の場合。

残念ながら、その後には2つのオプションがあります

  1. 想定を基に処理しますが、拡張機能がインストールされた場所を知っているだけです。たとえば、_CREATE EXTENSION x WITH SCHEMA CURRENT_SCHEMA_と_CREATE EXTENSION x_は統合されます。一部の単純なコマンドは複数のコマンドを発行するため、実行されたコマンドへの単純なアクセスは使用できません(例:serialはマクロです)。
  2. 内部 _pg_ddl_command_ をC関数で処理します。

2番目のオプションは喜びが少ないように聞こえるので、最初のオプションから始めましょう。

SRFから返されるobjidをサポートする コマンド終了時のキャプチャ変更 の下のリストを確認してください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_に変更できます。

1
Evan Carroll