Skip to main content
このページは、C++タイプ操作ビルダーのリファレンスです。カスタムタイプのチュートリアルレベルの導入については、C++でのカスタム型を参照してください。 カスタムタイプには、エンジンが内部的に呼び出す3つの操作が必要です。エンコード(文字列からバイナリ)、デコード(バイナリから文字列)、および比較です。ハッシュはオプションです。これらのC++シグネチャに対して実装します(すべて<villagesql/vsql.h>から利用可能)。

固定長タイプ

これらの操作は、vsql::make_type<kTypeName>()を使用して登録します。タイプ名は、非型テンプレートパラメータ(NTTP)として渡されます。static constexpr const char[]配列です。ビルダーは、このNTTPからTYPE::method形式(例:"MYTYPE::from_string")のVDF名を自動生成するため、手動での文字列マッチングは不要です。ビルドされたタイプオブジェクトを、拡張ビルダーの.type()に渡します。タイプ操作用の個別の.func()呼び出しは必要ありません。
タイプ名はstatic constexpr const char[]変数でなければなりません。文字列リテラルは、非型テンプレートパラメータとして使用できません。"MYTYPE"を直接渡すと、次のようなコンパイルエラーが発生します。
以下に示すように、名前を名前付き配列として宣言します。
from_stringto_string、またはcompareが欠落している場合、build()はコンパイル時に失敗します。各テンプレートメソッドは、static_assertを使用して関数ポインタのシグネチャを検証します。

組み込みデフォルト

NOT NULLのカスタムタイプカラムがIGNOREモード(例:INSERT IGNOREまたはUPDATE IGNORE)でNULLを受け取った場合、サーバーはエラーを発生させる代わりに、組み込みデフォルトを呼び出してフォールバック値を生成します。組み込みデフォルトは文字列表現を提供し、サーバーはタイプのfrom_string関数を使用してそれをバイナリに変換します。
.intrinsic_default_str().intrinsic_default_vdf()の両方を省略すると、サーバーはフォールバックとしてfrom_string("")を呼び出します。これは、タイプが最初に使用されるとき(テーブル作成時)に発生し、INSTALL EXTENSION時ではありません。エンコード関数が空の文字列を拒否する場合、または間違ったバイト数にエンコードする場合、タイプの初期化はSQLクライアントに表示されるエラーで失敗します。
固定長タイプの場合、デフォルト文字列は正確にpersisted_lengthバイトにエンコードされる必要があります。空の文字列が有効な入力ではないタイプには、明示的なデフォルトを設定してください。
文字列リテラル:.intrinsic_default_str() 定数のデフォルトの場合は、タイプビルダーで文字列を直接渡します(上記の固定長の例で.intrinsic_default_str("0")として示されています)。 VDFベース:.intrinsic_default_vdf() + make_intrinsic_default デフォルト値がタイプパラメータに依存する場合は、次のいずれかのシグネチャに対して関数を実装します(<villagesql/vsql.h>から利用可能)。
破壊的変更IntrinsicDefaultFuncIntrinsicDefaultWithParamsFuncは、const char*ではなくstd::stringを返します。 既存の組み込みデフォルトの実装を更新して、直接std::stringを返すようにしてください。
デフォルト値のstd::string表現を返します。エラーが発生した場合は、error_msgにメッセージを書き込み、任意の値を返します(SDKはエラーを検出するためにerror_msg[0] != '\0'をチェックします)。make_intrinsic_default<&fn>("vdf_name")(引数1つ:VDF名)で登録し、その名前をタイプビルダーの.intrinsic_default_vdf()で参照します。以下のパラメータ化されたタイプの例に、完全な登録パターンを示します。

パラメータ化されたタイプ

パラメータ化されたタイプは、割り当てサイズとレイアウトを決定するために、エンコード、デコード、比較、およびハッシュの時点でカラムの宣言されたパラメータを必要とします。パース関数と逆のto_strings関数を持つパラメータ構造体を定義し、.params<P, &ParseFunc, &ToStringsFunc>()でタイプビルダーに両方を登録し、タイプ操作関数の最初の引数としてconst P&を使用します。SDKは一意のパラメータの組み合わせごとにパース結果をキャッシュするため、パース関数はタイプのインスタンス化ごとに最大1回だけ実行されます。to_strings関数はparseの逆です。型Pのインスタンスを正規のキー/値の文字列形式に書き戻すため、サーバーはparseが消費するのと同じ形状で推論されたパラメータを公開できます。
タイプビルダーに.params<>()を登録します。MYTYPE(N)整数構文を処理するには.int_to_params<&mytype_int_to_params_fn>()を、パラメータを検証してストレージサイズを計算するには.resolve_params<&mytype_resolve_params_fn>()を使用します。すべての有効なパラメータ化にわたる永続化されるバイトサイズの上限を指定して.max_persisted_length(N)を呼び出します。サーバーはこれをタイプパラメータ推論のパスでのみ使用します。そこではまだパラメータを推論しておらず、エンコードバッファーのサイズを決定するためにresolve_paramsを参照できないためです。VDFベースの組み込みデフォルトの場合は、VDF名を指定して.intrinsic_default_vdf()を使用し、make_intrinsic_default<&mytype_default>()を介してVDFを個別に登録します。
.max_persisted_length()にはVEFプロトコル3以上が必要です。これを使用するタイプは、プロトコル3より前のサーバーではロードできません。
パラメータ化されたバリアント — TypeEncodeWithParamsFunc<P>TypeDecodeWithParamsFunc<P>TypeCompareWithParamsFunc<P>、および TypeHashWithParamsFunc<P> — は、ParamsToStringsFunc<P>void fn(const P&, std::map<std::string,std::string>&))とともに、 <villagesql/vsql.h>から利用可能です。 vsql::make_typeのテンプレートメソッドは、パラメータ引数を検出し、 パラメータキャッシュを自動的に経由します。エンコード関数は、 最初の引数としてvsql::MaybeParams<P> &を取ります。is_known()は実行時に常に真であり、 value()const P&を返します。デコード、比較、およびハッシュの バリアントは、params()アクセサがconst P&を返すvsql::CustomArgWith<P>を取ります。 SQLでのパラメータの指定。 2つの構文がresolve_paramsに到達します。
  • 整数MYTYPE(N)。サーバーはNint_to_paramsを通してルーティングし、 パラメータマップを構築します。.int_to_params<>()が必要です。
  • 文字列MYTYPE('key=value,...')。サーバーは文字列を正規化し、 resolve_paramsを直接呼び出します。int_to_paramsは関与しません。 .resolve_params<>()が登録されていれば常に利用可能です — 追加のビルダー呼び出しは不要です。
.resolve_params<>()のみを登録するタイプは、文字列形式を受け入れ、 MYTYPE(N)を拒否します。SHOW CREATE TABLEは、書き込まれた形式を保持します。
int_to_paramsが生成し、resolve_paramsが消費する シリアライズされたkey=value,...パラメータ文字列は、 VEF_MAX_TYPE_PARAMS_STRING_LEN(1024バイト)で上限が設定されています。 正規の文字列がその制限を超えるパラメータ化は、 黙って切り詰められるのではなく、定義されたエラーで拒否されます — 単一のタイプのパラメータ名と値を合わせて1024バイト以内に収めてください。

パラメータの書き換えとデフォルトの指定

resolve_paramsには、2つ目の変更用オーバーロードがあります。パラメータマップを 非const参照で受け取るため、タイプがそれを書き換えることができます — 通常は、 作者が省略したデフォルトを埋めるためです。同じ方法で登録します (.resolve_params<&fn>()はどちらの形式も受け入れます。1つだけ登録してください)。
書き換えられたマップは、サーバーが永続化し、SHOW CREATE TABLEが出力する 正規のパラメータ文字列になるため、書き換えは冪等でなければなりません。素の 宣言(MYTYPE、長さやパラメータなし)は、それをスキップするのではなく、 空のマップでresolve_paramsを呼び出すようになったため、デフォルトを提供するタイプは、 すべてのカラムに明示的なパラメータを与えます — vsql_bitfield_testBITFIELDは、 素のカラムをmax_number_of_bits=4096に解決します。

可変長タイプ

可変長カスタムタイプは、単一の固定フットプリントを使用するのではなく、 値ごとに永続化されるサイズを決定します。タイプビルダーで.variable_length_type()を 呼び出して宣言します。これはタイプのvariable_lengthフラグを設定します。
.variable_length_type()は、タイプの必須プロトコルをVEFプロトコル4に引き上げます。 サーバーは、プロトコル4以上でのみvariable_lengthフラグを読み取ります。 オプトインの開発ABIヘッダー(-DVSQL_USE_DEV_ABI=ON)に対してビルドします。古いサーバーは フラグを読み取りません。
可変長タイプは、.max_persisted_length(N)も呼び出す必要があります。これが省略されると、 build()はコンパイル時に失敗します — サーバーは、バッキングフィールドのバッファーを 割り当てるために上限を必要とします。 .variable_length_type()は一方向で、一度引き上げられたプロトコル要件は下がりません。プロトコル3のセッター (max_persisted_length()params()int_to_params())の前後に呼び出しても、 プロトコル要件がプロトコル4より下に戻ることはありません。
すべてのカスタムタイプと同様に、可変長タイプは使用可能な 組み込みデフォルトを生成する必要があります。デフォルトは フィールドの最大容量にエンコードされ、1からmax_persisted_lengthバイトまでの 空でない結果はすべて受け入れられます。空の文字列のエンコードがゼロバイトを生成する タイプ — 空の配列やビットセットなど — には使用可能なデフォルトがないため、 空でない値にエンコードされる明示的なデフォルトを宣言してください。
そうしないと、NOT NULLカラムが最初にそれを参照するとき、CREATE TABLE時に タイプの初期化に失敗します — from_string("")をエンコードできない固定長タイプと 同じです。

ストアドプロシージャでのカスタムタイプ

カスタム拡張タイプは、ストアドプロシージャのパラメータタイプとして、および DECLARE変数宣言で使用できます。サーバーは、インストールされた拡張機能の タイプメタデータを使用して、ルーチンの実行時にカスタムタイプを解決します。

関連項目