ORDER BY、インデックス、および集計関数で機能するRATIONAL、VECTOR、またはINETのような新しいカラム型を定義できます。Rust SDKは、custom_type!マクロを通じて、またストレージサイズがカラムのパラメータに依存する型についてはparameterized_type!を通じて、これをサポートしています(パラメータ化された型を参照)。
このページでは、まずRustでの拡張機能の作成を完了していることを前提としています。セットアップ(Cargo.toml、manifest.json、cargo-vsql)は同じです。
カスタム型を使用するタイミング
次のいずれかの条件に該当する場合に、カスタム型を使用します。- 標準のSQL型では表現できないバイナリのオンディスクレイアウトが必要な場合(パックされた浮動小数点数、固定幅の整数、バイナリ識別子)
- 型に、辞書順の文字列の順序とは異なる独自の順序セマンティクスがある場合
ORDER BY、GROUP BY、DISTINCT、およびセット操作のために、サーバーに値を正しくインデックス化・ハッシュさせたい場合
STRING、INT、またはREALカラムに問題なく収まる場合は、カスタム型は必要ありません。
custom_type!マクロ
すべてのカスタム型には、3つのコールバック(エンコード、デコード、比較)とデフォルト値が必要で、オプションでハッシュのコールバックを指定できます。完全なマクロのシグネチャは次のとおりです。
type_name、persisted_length、max_decode_buffer_length、encode、decode、およびcompareは必須です。hashはオプションですが、正しいGROUP BY、DISTINCT、およびセット操作はこれに依存するため、推奨されます。型にはどちらかの方法でデフォルト値を与えてください。リテラルとして書ける値にはdefaultを、拡張機能が計算する必要がある値にはintrinsic_default_fnを使用します。両方を設定するとINSTALL EXTENSIONは失敗します。どちらも設定しない場合、拡張機能はインストールできますが、その型を指定する最初のステートメントが失敗します。
バイナリ値の受信と返却
カスタム型を受け取るか返す関数は、生のバイトで動作します。 入力 —InValue::Custom(b)は、保存されたバイナリを&[u8]として渡します。
VdfReturn::Binary(bytes)は、バイナリバイトをサーバーに返します。
func!宣言でカスタム型を参照するには、villagesql::custom!("type_name")を使用します。
例:有理数型
SDKリポジトリのexamples/vsql_rationalは、RATIONAL型を実装する動作する拡張機能です。有理数を、リトルエンディアンのバイト順で2つのi64値のペア(分子、分母)、合計16バイトとして格納し、算術関数を提供します。
エンコード、デコード、比較、およびハッシュの実装のコアは次のとおりです。
custom_type!登録、rational_encodeが呼び出すgcdおよびnormalizeヘルパー、および算術VDF(rational_add、rational_subなど)は、examples/vsql_rational/src/lib.rsの完全なソースにあります。
拡張機能がインストールされている場合:
rational_to_real(r RATIONAL) -> REALは、分子を分母で割ることによって、RATIONAL値を64ビット浮動小数点近似に変換します。表示または比較のために近似的な10進数が必要で、その値をカラムに精度が落ちる表現として保存したくない場合に便利です。
パラメータ化された型
パラメータ化された型は、ストレージサイズを知るために、CREATE TABLE時に
読み取られる値(VECTOR(3)の3など)を必要とします。custom_type!では
これを表現できません。そのpersisted_lengthは、すべてのカラムに対して
単一の固定された定数です。parameterized_type!は、そのパラメータ化された
対応物です。永続化される長さは、固定されるのではなく、int_to_paramsと
resolve_paramsを通じて、宣言されたパラメータからカラムごとに計算されます。
type_name、max_persisted_length、max_decode_buffer_length、encode、decode、compare、int_to_params、resolve_params、params_type、params_parse、およびparams_to_stringsは必須です。hashはオプションです。型にはどちらかの方法でデフォルト値を与えてください。リテラルとして書ける値にはdefaultを、拡張機能が計算する必要がある値にはintrinsic_default_fn(デフォルトがパラメータに依存する場合に、&Pからデフォルトを計算する関数)を使用します。両方を設定するとINSTALL EXTENSIONは失敗します。どちらも設定しない場合、拡張機能はインストールできますが、その型を指定する最初のステートメントが失敗します。
次はpadintです。固定の8バイトで格納されるi64で、ゼロ埋めされた表示幅を制御するwidthパラメータを持ちます。
InValue::Custom(bytes)ではなくInValue::CustomWithParams { bytes, params }を
受け取ります。paramsはTypeParamsであり、カラムに宣言されたkey=valueの
ペアに対する読み取り専用でゼロコピーのビューです。
型を含むextension!ブロック
関数と型を両方登録する場合、extension!ブロックには2つのセクションがあります。
types:を省略します。型のみの拡張機能はfuncs: []を保持し、それ以外は何も省略しません。
次のステップ
Rust APIリファレンス
InValue、VdfReturn、およびextension!、func!、agg_func!、varargs_func!、custom_type!、custom!マクロのリファレンス。Rust で拡張機能を作成する
はじめに — Cargoのセットアップ、最初の関数、パッケージング、およびテスト。
C++カスタム型
C++のカスタム型 —
make_type<>、エンコード/デコード/比較/ハッシュ、ALTER TABLEルール。拡張機能のアーキテクチャ
カスタム型が解決、キャッシュ、および保存される方法。

