要新增原生 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
。目前所有字串函數都會嘗試避免分配任何記憶體,除非絕對必要!