若要新增原生 MySQL 函數,請使用此處描述的程序,此程序要求您使用原始碼發行版。您無法將原生函數新增至二進位發行版,因為必須修改 MySQL 原始碼並從修改後的原始碼編譯 MySQL。如果您遷移至另一個版本的 MySQL(例如,當發布新版本時),您必須使用新版本重複此程序。
如果原生函數將在會複製到複本的語句中引用,您必須確保每個複本也都有該函數可用。否則,當複本嘗試調用該函數時,複寫將在複本上失敗。
若要新增原生函數,請依照下列步驟修改 sql
目錄中的原始碼檔案
-
在
item_create.cc
中為函數建立子類別如果函數採用固定數量的引數,請分別建立
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
類別定義了一個val()
函數,該函數在::str()
傳回的值上執行atof()
。 -
如果函數是不確定的,請在項目建構函式中包含下列語句,以指出不應快取函數結果
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
。除非絕對必要,否則目前所有字串函數都會盡力避免分配任何記憶體!