S-JIS[2026-01-04]
TsurugiのSQLのユーザー定義関数(UDF)のprotoファイルの書き方。
TsurugiのUDFは、拡張子protoのファイル(Protocol Buffers、protobuf)で定義する。
そのprotoファイルをビルドすることで、gRPCサーバーの骨格およびTsurugiに登録するファイルを生成する。
syntax = "proto3";
package example.tsurugi.udf;
option java_package = "com.example.tsurugi.udf.proto";
option java_multiple_files = true;
message MyFunctionRequest {
int32 value = 1;
}
message MyFunctionResponse {
int32 value = 1;
}
service ExampleService {
rpc my_function(MyFunctionRequest) returns (MyFunctionResponse);
}
syntaxでproto3を指定しておく必要があるらしい。
packageは無くてもいいが、付けておいた方が良いだろう。
protobufのパッケージ名の命名ルールは、Javaとは違い、URLの逆順とかではないらしい。
Tsurugi UDFのルールとして、「tsurugidb.」から始まるパッケージ名は使ってはいけない。(Tsurugi自身が提供するパッケージで使用される為)
serviceのrpcで関数(UDF)を定義する。
関数名は、TsurugiのSQLから使う際には大文字小文字は無視される。
関数の引数および戻り値の型は、messageとして定義しておく必要がある。
UDFの引数が複数ある場合は、message内に複数のフィールドを定義する。
戻り値は(今のところ)1つのフィールドのみ。
引数用のmessageでは、oneofを使ってひとつの引数で異なる型を受け入れられる。
しかし戻り値用のmessageではoneofを使用できない。
なので、引数の型に応じて戻り値の型を変えるようなことは出来ない。
syntax = "proto3";
package example.tsurugi.udf;
option java_multiple_files = true;
option java_package = "com.example.tsurugi.udf.proto";
message MyAddRequest {
int64 value1 = 1;
int64 value2 = 2;
}
message MyAddResponse {
int64 value = 1;
}
service ExampleService {
rpc my_add(MyAddRequest) returns (MyAddResponse);
}
この例だと、「select my_add(100, 2) from test;」のようにして呼び出す。
syntax = "proto3";
package example.tsurugi.udf;
option java_multiple_files = true;
option java_package = "com.example.tsurugi.udf.proto";
message ToStringRequest {
oneof value {
int64 int_value = 1;
double float_value = 2;
string string_value = 3;
}
}
message ToStringResponse {
string value = 1;
}
service ExampleService {
rpc to_string(ToStringRequest) returns (ToStringResponse);
}
この例では、to_string関数の引数としてBIGINT、DOUBLE、CHAR/VARCHARが使用できる。
messageで使用できるデータ型は、Tsurugi UDFで規定されているもののみ。
→データ型の対応付け
主な対応関係は以下の通り。
| Tsurugi | proto |
|---|---|
INT |
int32 |
BIGINT |
int64 |
REAL, FLOAT |
float |
DOUBLE |
double |
CHAR, VARCHAR |
string |
BINARY, VARBINARY |
bytes |
DECIMAL |
tsurugidb.udf.Decimal |
DATE |
tsurugidb.udf.Date |
TIME |
tsurugidb.udf.LocalTime |
TIMESTAMP |
tsurugidb.udf.LocalDatetime |
TIMESTAMP WITH TIME ZONE |
tsurugidb.udf.OffsetDatetime |
BLOB |
tsurugidb.udf.BlobReference |
CLOB |
tsurugidb.udf.ClobReference |
パッケージがtsurugidb.udfでないデータ型はprotobuf標準なので、特に気にせず使える。
パッケージがtsurugidb.udfのデータ型はTsurugi UDFが提供しているmessageなので、tsurugi_types.protoをインポートしないと使用できない。
tsurugi_types.protoは、Tsurugiのデータ型のうち、protobuf標準では扱えない型を提供しているファイル。
syntax = "proto3";
import "tsurugidb/udf/tsurugi_types.proto";
message IncDecimalRequest {
tsurugidb.udf.Decimal value = 1;
}
message IncDecimalResponse {
tsurugidb.udf.Decimal value = 1;
}
service ExampleService {
rpc inc_decimal(IncDecimalRequest) returns (IncDecimalResponse);
}
protoファイル上の記述はこれでいいが、ビルド時にはtsurugi_types.protoファイルが必要になる。
tsurugi_types.protoはudf-pluginのソースアーカイブの中に含まれている。
(Tsurugi UDF 0.1.0の場合、tsurugi-udf-0.1.0/proto/tsurugidb/udf/tsurugi_types.proto)
gRPCサーバーを作る際(protoファイルをコンパイルする際)には、このファイルを加える必要がある。
udf-plugin-builderでビルドする際も、tsurugi_types.protoを指定する必要がある。
cd udf-example TSURUGI_UDF_DIR=/path/to/tsurugi-udf-0.1.0 ~/.local/bin/udf-plugin-builder \ --proto-file example2.proto $TSURUGI_UDF_DIR/proto/tsurugidb/udf/tsurugi_types.proto \ --proto-path . $TSURUGI_UDF_DIR/proto \ --output-dir $TSURUGI_HOME/var/plugins/
--proto-fileの後ろに、自分のprotoファイルとtsurugi_types.protoを空白区切りで指定する。
また、--proto-pathの後ろに、自分のprotoファイルのあるディレクトリーとtsurugi_types.protoのルートディレクトリーを空白区切りで指定する。
(--proto-pathは、protocの-Iオプション相当)