S-JIS[2026-01-04]

Tsurugi UDF protoファイル

TsurugiSQLユーザー定義関数(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を使用できない。
なので、引数の型に応じて戻り値の型を変えるようなことは出来ない。


引数が2つの関数の例

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;」のようにして呼び出す。


引数にoneofを使った例

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_types.protoは、Tsurugiのデータ型のうち、protobuf標準では扱えない型を提供しているファイル。

DECIMALの例

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オプション相当)


UDFへ戻る / SQLへ戻る / Tsurugiへ戻る / 技術メモへ戻る
メールの送信先:ひしだま