[アップデート] Amazon Aurora PostgreSQL 16.1 がリリースされたので、Babelfish 4.0 のアップデート内容を確認してみた

2024.02.04

いわさです。

先日 Aurora PostgreSQL 16.1 がリリースされました。

今回あれですね。16.0 が RDS プレビュー環境でリリースされてましたけど、運用リージョンでは 16.0 をスキップして 16.1 がリリースされましたね。
ちなみにプレビュー環境での 16.0 については以下の記事で確認していました。

今回 Aurora PostgreSQL 16.1 のリリースにあわせて、Babelfish 4.0.0 が使えるようになりました。
Aurora PostgreSQL がリリースされる度に Babelfish の新しい機能を確認していくのが私の中で恒例となっていまして、またやっていきたいと思います。

更新履歴

まず、バージョンごとの変更点はこちらのリリースノートを確認しましょう。

今回はこれまでのバージョンアップから比較するとアップデート量が印象です。 いつもは大量に機能追加されている印象です。

目新しい機能としてはフルテキスト検索や、これまで制限があって使えていなかった VIEW での INSTEAD OF Trigger のサポートです。

後者は実際に使ってみましたので本記事内でその様子も紹介します。

バージョンごとのサポート範囲の比較をしたい場合は以下も確認します。

こちらでも新たに使えるようになったのはFULL TEXT SEARCHINSTEAD OF triggers on viewsだけのようです。ちなみにINSTEAD OF triggers on tablesは以前から使えていたこともこのバージョン別サポート表から確認が可能です。

使ってみた

作成方法は Aurora PostgreSQL 16.1 のインスタンスを新規に作成し Babelfish をオンにするだけです。パラメータ設定など追加のオプションもまぁありますが。

新規作成ではなくバージョンアップを行う時ですが、Aurora 15 から 16 へのアップグレードは可能なのですが、14 から 16 への直接アップグレードはサポートされておらず失敗します。
先に 14 から 15 へアップグレードしてから 16 へアップグレードしましょう。

バージョン確認

いつものようにまずはpsqlで PostgreSQL として接続して Babelfish 拡張のバージョンを確認してみます。

% psql -h hoge0204babelfis.cluster-cpnu9ipu74g4.ap-northeast-1.rds.amazonaws.com -U postgres -d babelfish_db
Password for user postgres: 
psql (14.9 (Homebrew), server 16.1)
WARNING: psql major version 14, server major version 16.
         Some psql features might not work.
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.

babelfish_db=> SELECT aurora_version() AS aurora_version, version() AS postgresql_version, sys.version() AS Babelfish_compatibility, sys.SERVERPROPERTY('BabelfishVersion') AS Babelfish_Version;
 aurora_version |                                       postgresql_version                                        |                           babelfish_compatibility                           | babelfish_version 
----------------+-------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------+-------------------
 16.1.0         | PostgreSQL 16.1 on x86_64-pc-linux-gnu, compiled by x86_64-pc-linux-gnu-gcc (GCC) 9.5.0, 64-bit | Babelfish for Aurora PostgreSQL with SQL Server Compatibility - 12.0.2000.8+| 4.0.0
                |                                                                                                 | Jan 19 2024 00:09:54                                                       +| 
                |                                                                                                 | Copyright (c) Amazon Web Services                                          +| 
                |                                                                                                 | PostgreSQL 16.1 on x86_64-pc-linux-gnu (Babelfish 4.0.0)                    | 
(1 row)

Babelfish 4.0.0 ですね。SQL Server の互換性表記は12.0.2000.8+のまま。

INSTEAD OF triggers on views

新しくサポートされるようになった SQL Server の機能のうち、今回は「INSTEAD OF triggers on views」を確認してみます。

INSERT や UPDATE などの DML イベント発生時のトリガーとして SQL Server では AFTER トリガーと INSTEAD OF トリガーがサポートされています。

通常トリガーというと前者の AFTER トリガーを連想することが多い気がしますが(個人的に)、INSTEAD OF トリガーを使うと、トリガーとなったイベントの代わりの処理を実行することが出来ます。
おもしろいのが、INSTEAD OF トリガーの場合はテーブルだけでなくビューを対象にすることも出来ます。

ユースケースとしては、SQL Server では更新可能なビューを作成することが出来るのですが、一定の条件を満たす必要があります。

例えばデータソースが複数のテーブルのビューの場合は直接更新が出来ないので、代替手段として INSTEAF OF トリガーを使う方法があります。

まずは、データベース、2 つのテーブル、それらを結合したビューを作成してみます。
ここからはsqlcmdを使って SQL Server としてアクセスしてみます。

% sqlcmd -S hoge0204babelfis.cluster-cpnu9ipu74g4.ap-northeast-1.rds.amazonaws.com -U postgres              
Password: 
1> create database hogedb;
2> go
1> use hogedb;
2> go
Changed database context to 'hogedb'.
1> CREATE TABLE fuga (col1 int, col2 char(10));
2> go
1> insert into fuga values (1, 'aaa');
2> insert into fuga values (2, 'bbb');
3> go

(1 rows affected)

(1 rows affected)
1> select * from fuga;
2> go
col1        col2      
----------- ----------
          1 aaa       
          2 bbb       

(2 rows affected)
1> CREATE TABLE piyo (col1 int, col2 char(10));
2> go
1> insert into piyo values (1, '111');
2> insert into piyo values (2, '222');
3> go

(1 rows affected)

(1 rows affected)
1> select *from piyo;
2> go
col1        col2      
----------- ----------
          1 111       
          2 222       

(2 rows affected)


1> create view fugapiyo as
2> select f.col1 as vcol1, trim(f.col2) + trim(p.col2) as vcol2 from fuga f inner join piyo p on f.col1 = p.col1
3> go
1> select * from fugapiyo;
2> go
vcol1       vcol2                                                                                                                                                                                                                                                           
----------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
          1 aaa111                                                                                                                                                                                                                                                          
          2 bbb222                                                                                                                                                                                                                                                          

(2 rows affected)

良いですね。

で、このビューに対しての INSERT は今は出来ません。

1> insert into fugapiyo values (3, 'ccc333');
2> go
Msg 33557097, Level 16, State 1, Server hoge0204babelfis-instance-1, Line 1
cannot insert into view "fugapiyo"

エラーになりましたね。
ここで、INSTEAD OF トリガーを作成してやりましょう。

トリガーを作成

次の公式ドキュメントを参考にトリガーを作成します。

inserted というビューと同じレイアウトの一時的なテーブルからビューのトリガーとなったレコードにアクセス出来るので、そちらのデータを基に 2 つのテーブルに分割して INSERT を発行してみます。
適当なんですが、こんな感じで作成してみました。

1> create trigger fugapiyotrigger on fugapiyo instead of insert as
2> begin
3>     insert into fuga (col1, col2) select vcol1, substring(vcol2, 1, 3) from inserted;
4>     insert into piyo (col1, col2) select vcol1, substring(vcol2, 4, 3) from inserted;
5> end
6> go

では、改めてビューに対して INSERT を実行してみましょう。

1> insert into fugapiyo values (3, 'ccc333');
2> go

(1 rows affected)

(1 rows affected)

(1 rows affected)
1> select * from fugapiyo;
2> go
vcol1       vcol2                                                                                                                                                                                                                                                           
----------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
          1 aaa111                                                                                                                                                                                                                                                          
          2 bbb222                                                                                                                                                                                                                                                          
          3 ccc333                                                                                                                                                                                                                                                          

(3 rows affected)

良いんじゃないでしょうか。

ちなみに Aurora PostgreSQL 15.5 の Babelfish 3.4 だとトリガーの作成に失敗します。

1> create trigger fugapiyotrigger on fugapiyo instead of insert as
2> begin
3>     insert into fuga (col1, col2) select vcol1, substring(vcol2, 1, 3) from inserted;
4>     insert into piyo (col1, col2) select vcol1, substring(vcol2, 4, 3) from inserted;
5> end
6> go
Msg 33557097, Level 16, State 1, Server hoge0204babel-prev-instance-1, Line 1
"fugapiyo" is a view

さいごに

本日は Amazon Aurora PostgreSQL 16.1 がリリースされたので、Babelfish 4.0 のアップデート内容を確認してみました。

気のせいかいつもよりアップデート量が少なかった気がしますね。
ペースダウンせずに Babelfish がアップデートされ、SQL Server を前提としたアプリケーションが当たり前のようにそのまま Aurora を使うことを期待しているのですが、このままいけるだろうか。
引き続きウォッチしていきたいと思います。