新しいネイティブ MySQL 関数を追加するには、ここで説明している手順を使用します。この手順では、ソース配布を使用する必要があります。ネイティブ関数をバイナリ配布に追加することはできません。その場合、MySQL ソースコードを変更して、変更されたソースから MySQL をコンパイルする必要があるためです。別のバージョンの MySQL に移行する場合 (たとえば、新しいバージョンがリリースされたとき) は、新しいバージョンを使用してこの手順を繰り返す必要があります。
スレーブサーバーにレプリケートされるステートメントで新しいネイティブ関数が参照される場合は、すべてのスレーブサーバーで関数を使用できるようにする必要があります。そうしないと、スレーブでその関数を呼び出そうとしたときに、レプリケーションがスレーブで失敗します。
新しいネイティブ関数を追加するには、次のステップに従って、sql
ディレクトリ内のソースファイルを変更します。
-
item_create.cc
に関数のためのサブクラスを作成します。関数が固定された数の引数を受け取る場合は、関数が受け取る引数の数 (0、1、2、または 3 個) に応じて、
Create_func_arg0
、Create_func_arg1
、Create_func_arg2
、またはCreate_func_arg3
のサブクラスをそれぞれ作成します。たとえば、Create_func_uuid
、Create_func_abs
、Create_func_pow
、およびCreate_func_lpad
クラスを参照してください。関数が受け取る引数の数が可変の場合は、
Create_native_func
のサブクラスを作成します。たとえば、Create_func_concat
を参照してください。
-
SQL ステートメントで関数を参照できる名前を指定するには、次の配列に行を追加することによって
item_create.cc
に名前を登録します。static Native_func_registry func_array[]
同じ関数に対して複数の名前を登録できます。たとえば、
"LCASE"
および"LOWER"
の行を参照してください。これらはCreate_func_lcase
のエイリアスです。 item_func.h
に、関数が数値または文字列のいずれを返すかに応じて、Item_num_func
またはItem_str_func
から継承するクラスを宣言します。-
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()
関数を定義しています。 -
関数に決定性がない場合は、関数の結果をキャッシュしないことを示すために、次のステートメントを項目のコンストラクタに含めます。
current_thd->lex->safe_to_cache_query=0;
関数に決定性がない状態とは、引数の値が固定されていても、呼び出しごとに異なる結果が返されることがある場合です。
-
多くの場合、次のオブジェクト関数も定義します。
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
を返します。現在のすべての文字列関数は、絶対に必要である場合を除き、メモリーの割り当てを回避しようとします。