MySQL 5.6 リファレンスマニュアル  /  ...  /  新しいネイティブ関数の追加

24.3.3 新しいネイティブ関数の追加

新しいネイティブ MySQL 関数を追加するには、ここで説明している手順を使用します。この手順では、ソース配布を使用する必要があります。ネイティブ関数をバイナリ配布に追加することはできません。その場合、MySQL ソースコードを変更して、変更されたソースから MySQL をコンパイルする必要があるためです。別のバージョンの MySQL に移行する場合 (たとえば、新しいバージョンがリリースされたとき) は、新しいバージョンを使用してこの手順を繰り返す必要があります。

スレーブサーバーにレプリケートされるステートメントで新しいネイティブ関数が参照される場合は、すべてのスレーブサーバーで関数を使用できるようにする必要があります。そうしないと、スレーブでその関数を呼び出そうとしたときに、レプリケーションがスレーブで失敗します。

新しいネイティブ関数を追加するには、次のステップに従って、sql ディレクトリ内のソースファイルを変更します。

  1. item_create.cc に関数のためのサブクラスを作成します。

    • 関数が固定された数の引数を受け取る場合は、関数が受け取る引数の数 (0、1、2、または 3 個) に応じて、Create_func_arg0Create_func_arg1Create_func_arg2、または Create_func_arg3 のサブクラスをそれぞれ作成します。たとえば、Create_func_uuidCreate_func_absCreate_func_pow、および Create_func_lpad クラスを参照してください。

    • 関数が受け取る引数の数が可変の場合は、Create_native_func のサブクラスを作成します。たとえば、Create_func_concat を参照してください。

  2. SQL ステートメントで関数を参照できる名前を指定するには、次の配列に行を追加することによって item_create.cc に名前を登録します。

    static Native_func_registry func_array[]
    

    同じ関数に対して複数の名前を登録できます。たとえば、"LCASE" および "LOWER" の行を参照してください。これらは Create_func_lcase のエイリアスです。

  3. item_func.h に、関数が数値または文字列のいずれを返すかに応じて、Item_num_func または Item_str_func から継承するクラスを宣言します。

  4. item_func.cc に、数値関数または文字列関数のいずれを定義するかに応じて、次のいずれかの宣言を追加します。

    double   Item_func_newname::val()
    longlong Item_func_newname::val_int()
    String  *Item_func_newname::Str(String *str)
    

    標準的な項目 (Item_num_func など) からオブジェクトを継承する場合は、それらの関数のいずれかを定義するだけで、多くの場合、親オブジェクトによってほかの関数が提供されます。たとえば、Item_str_func クラスは、::str() によって返された値に対して atof() を実行する val() 関数を定義しています。

  5. 関数に決定性がない場合は、関数の結果をキャッシュしないことを示すために、次のステートメントを項目のコンストラクタに含めます。

    current_thd->lex->safe_to_cache_query=0;
    

    関数に決定性がない状態とは、引数の値が固定されていても、呼び出しごとに異なる結果が返されることがある場合です。

  6. 多くの場合、次のオブジェクト関数も定義します。

    void Item_func_newname::fix_length_and_dec()
    

    この関数は、指定された引数に基づいて、少なくとも max_length を計算します。max_length は関数が返すことができる最大文字数です。メイン関数が NULL 値を返せない場合は、この関数で maybe_null = 0 も設定します。この関数は、引数の maybe_null 変数をチェックすることによって、関数のいずれかの引数が NULL を返すことがあるかどうかをチェックできます。これを実行する方法の典型的な例については、Item_func_mod::fix_length_and_dec を参照してください。

すべての関数はスレッドセーフである必要があります。言い換えると、関数内で相互排他ロックで保護せずにグローバル変数または静的変数を使用しないでください。

::val()::val_int()、または ::str() から NULL を返す場合は、null_value を 1 に設定して 0 を返します。

::str() オブジェクト関数については、注意すべき追加の考慮事項があります。

  • String *str 引数は、結果を保持するために使用できる文字列バッファーを提供します。(String 型の詳細は、sql_string.h ファイルを参照してください。)

  • ::str() 関数では、結果が保持されている文字列を返すか、結果が NULL の場合は (char*) 0 を返します。

  • 現在のすべての文字列関数は、絶対に必要である場合を除き、メモリーの割り当てを回避しようとします。


User Comments
Sign Up Login You must be logged in to post a comment.