Trusted Language Extensions for PostgreSQLをJavaScriptで試してみた

2022.12.01

Trusted Language Extensions(TLE)とは?

re:Invent2022で発表されたAmazon AuroraおよびAmazon RDSのアップデートです。

速報記事はこちら⇒[速報]AuroraやRDSの拡張機能を生産的に作成できる!Trusted Language Extensions for PostgreSQLの一般提供開始(GA)が発表されました! #reinvent

PostgreSQLには利用者が独自でスクリプトを開発して拡張機能として組み込める仕組みがあります。しかし、拡張機能の作成にはファイルシステムへのアクセスというリスクがあります。従来のAuroraやRDSでは用意された拡張機能を使うことができるのみで、拡張機能を新しく作ることはできませんでした。

今回のアップデートにより、ファイルシステムへアクセスすることなく安全に拡張機能を作成することができるようになりました。そのための開発キットがTrusted Language Extensions for PostgreSQLです。

では、早速試してみます。

準備

パラメータグループの作成

TLEを使うには、まずパラメータグループのshared_preload_librariesの値を変更します。これはサーバ起動時にプリロードされるライブラリを設定する項目です。pg_tleがプリロードされるように変更します。

パラメータグループを新規作成します。パラメータグループファミリーには、Auroraの場合はaurora-postgresql14、RDSの場合はpostgres14を指定します。この記事ではAuroraを使用するので、aurora-postgresql14を指定しています。

作成したパラメータグループのshared_preload_librariesを探し、値にpg_tleと入力します。カンマ区切りで複数の値を入力できるので、もし他に使いたいライブラリがある場合は任意で入力します。

今回はpg_tleだけを入力して変更の保存をします。

DBインスタンスの作成

AuroraまたはRDS PostgreSQLのインスタンスを作成します。

以下の点に注意してください。

  • 利用可能なバージョンでPostgreSQL14.5のものを選択
  • DBパラメータグループで先ほど作成したものを選択

pg_tleライブラリのインストール

Auroraに接続するためのEC2インスタンスを用意し、PostgreSQLのセットアップをします。

amazon-linux-extras install postgresql14
yum install postgresql-server
/usr/bin/postgresql-setup initdb
systemctl start postgresql

以下のコマンドでPostgreSQLに接続できればOKです。

psql --host=database-1.cluster-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=postgres

パラメータグループで指定したpg_tleライブラリがプリロードされているかを確認します。

SHOW shared_preload_libraries;

pg_tleが返ってくればOKです。続いてインストールします。

CREATE EXTENSION pg_tle;

以下のコマンドで、インストールされたことを確認します。

SELECT * FROM pg_extension;

最後に、権限の設定です。新しく拡張機能を作成する場合は、プライマリユーザーに権限を付与する必要があります。

GRANT pgtle_admin TO postgres;

これで準備ができました。

拡張機能の作成

拡張機能をインストールするには、pgtle.install_extension関数の実行⇒CREATE EXTENSIONという流れになります。

スクリプト作成

早速拡張機能を作ってみます。任意の名前でファイルを作成し、以下のように記述します。

SELECT pgtle.install_extension
(
 'pg_decimal_classification',
 '0.1',
  'tle sample',
$_pg_tle_$
    CREATE FUNCTION classify(code int)
    RETURNS text
    AS $$
        switch(code){
            case 0:
                return '総記';
            case 1:
                return '哲学・宗教';
            case 2:
                return '歴史・地理';
            case 3:
                return '社会科学';
            case 4:
                return '自然科学';
            case 5:
                return '技術、家庭、工業';
            case 6:
                return '産業';
            case 7:
                return '芸術、体育';
            case 8:
                return '言語';
            case 9:
                return '文学';
            default:
                return '該当なし';
        }
    $$ LANGUAGE plv8 IMMUTABLE PARALLEL SAFE;
$_pg_tle_$
);

pgtle.install_extension関数の各引数の意味は次のようになっています。

pgtle.install_extension(name text, version text, description text, ext text, requires text[] DEFAULT NULL::text[])
  • name:CREATE EXTENSIONで呼び出される名前
  • version:拡張機能のバージョン
  • description:拡張機能の説明
  • ext:拡張機能の処理本体
  • requires:依存関係の指定

参考:Functions reference for Trusted Language Extensions for PostgreSQL

ファイルを保存したら実行します。-fオプションでファイル名を指定しています。

psql --host=database-1.cluster-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=postgres -f ./sample_tle.sql

このようなテーブルが表示されます。

拡張機能のインストール

続いてCREATE EXTENSION文でインストールを行いますが、このままではエラーになってしまいます。

CREATE EXTENSION pg_decimal_classification;

plv8という言語が存在していないのでロードしてね、と言われます。

現在、何の言語が存在しているか確認してみます。

SELECT * FROM pg_language;

plv8が存在していないので、CREATE LANGUAGE文でインストールします。

CREATE LANGUAGE plv8;

先ほどのCREATE EXTENSION文を再度実行すると、無事に作成した拡張機能がインストールできました。

拡張機能の実行

拡張機能pg_decimal_classificationには、classifyという関数を一つ定義していました。この関数を呼び出してみます。

SELECT classify(1);

作成した拡張機能を実行することができました。

おわりに

今回の記事ではJavaScriptを使用しましたが、SQL、PL/pgSQL、Perlといった言語も使用できます。各言語のサンプルが公式のGitHubにあるので参考にしてみてください。

また、フックを作成することもできます。公式では、ユーザが作成したパスワードがbad passwordsのリストに存在するかどうかをチェックするフックのサンプルが公開されています。

PostgreSQLの特徴でもある柔軟な拡張機能がRDSで使えるようになったのは嬉しいですね。よかったら試してみてはいかがでしょうか。