共計 5616 個字符,預(yù)計需要花費 15 分鐘才能閱讀完成。
這篇文章主要講解了“PostgreSQL 隱式類型轉(zhuǎn)換中使用哪些操作符實現(xiàn)函數(shù)”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著丸趣 TV 小編的思路慢慢深入,一起來研究和學(xué)習(xí)“PostgreSQL 隱式類型轉(zhuǎn)換中使用哪些操作符實現(xiàn)函數(shù)”吧!
一、數(shù)據(jù)結(jié)構(gòu)
FuncCandidateList
該結(jié)構(gòu)體存儲檢索得到的所有可能選中的函數(shù)或操作符鏈表.
/*
* This structure holds a list of possible functions or operators
* found by namespace lookup. Each function/operator is identified
* by OID and by argument types; the list must be pruned by type
* resolution rules that are embodied in the parser, not here.
* See FuncnameGetCandidates s comments for more info.
* 該結(jié)構(gòu)體存儲檢索得到的所有可能選中的函數(shù)或操作符鏈表.
* 每一個函數(shù) / 操作符通過 OID 和參數(shù)類型唯一確定,
* 通過集成到分析器中的 type resolution rules 來確定裁剪該鏈表(但不是在這里實現(xiàn))
* 詳細(xì)可參考 FuncnameGetCandidates 函數(shù).
*/
typedef struct _FuncCandidateList
struct _FuncCandidateList *next;
// 用于 namespace 檢索內(nèi)部使用
int pathpos; /* for internal use of namespace lookup */
//OID
Oid oid; /* the function or operator s OID */
// 參數(shù)個數(shù)
int nargs; /* number of arg types returned */
//variadic array 的參數(shù)個數(shù)
int nvargs; /* number of args to become variadic array */
// 默認(rèn)參數(shù)個數(shù)
int ndargs; /* number of defaulted args */
// 參數(shù)位置索引
int *argnumbers; /* args positional indexes, if named call */
// 參數(shù)類型
Oid args[FLEXIBLE_ARRAY_MEMBER]; /* arg types */
} *FuncCandidateList;
二、源碼解讀
func_match_argtypes
給定候選函數(shù)列表 (正確的函數(shù)名稱 / 參數(shù)個數(shù)匹配) 和輸入數(shù)據(jù)類型 OIDs 數(shù)組, 生成實際可匹配輸入數(shù)據(jù)類型 (完全匹配或可轉(zhuǎn)換) 的候選函數(shù)鏈表, 然后符合條件的候選函數(shù)個數(shù).
/* func_match_argtypes()
*
* Given a list of candidate functions (having the right name and number
* of arguments) and an array of input datatype OIDs, produce a shortlist of
* those candidates that actually accept the input datatypes (either exactly
* or by coercion), and return the number of such candidates.
* 給定候選函數(shù)列表 (正確的函數(shù)名稱 / 參數(shù)個數(shù)匹配) 和輸入數(shù)據(jù)類型 OIDs 數(shù)組,
* 生成實際可匹配輸入數(shù)據(jù)類型 (完全匹配或可轉(zhuǎn)換) 的候選函數(shù)鏈表, 然后符合條件的候選函數(shù)個數(shù)
*
* Note that can_coerce_type will assume that UNKNOWN inputs are coercible to
* anything, so candidates will not be eliminated on that basis.
* can_coerce_type 函數(shù)假定 UNKNOWN 輸入可轉(zhuǎn)換為任意類型.
*
* NB: okay to modify input list structure, as long as we find at least
* one match. If no match at all, the list must remain unmodified.
* 注意: 如果只是找到一個匹配的候選函數(shù), 修改輸入鏈表結(jié)構(gòu)是 OK 的. 如無匹配, 則鏈表保持不變.
*/
func_match_argtypes(int nargs,
Oid *input_typeids,
FuncCandidateList raw_candidates,
FuncCandidateList *candidates) /* return value */
FuncCandidateList current_candidate;// 當(dāng)前候選
FuncCandidateList next_candidate;// 下一候選
int ncandidates = 0;
*candidates = NULL;
for (current_candidate = raw_candidates;
current_candidate != NULL;
current_candidate = next_candidate)// 遍歷候選函數(shù)
{
next_candidate = current_candidate- next;
if (can_coerce_type(nargs, input_typeids, current_candidate- args,
COERCION_IMPLICIT))// 可匹配輸入數(shù)據(jù)類型(完全匹配或可轉(zhuǎn)換)
{
current_candidate- next = *candidates;
*candidates = current_candidate;
ncandidates++;
}
}
return ncandidates;
} /* func_match_argtypes() */
在 pg_operator 中, 輸入?yún)?shù)類型與 operator 的參數(shù)類型匹配或可轉(zhuǎn)換, 可進入候選函數(shù)鏈表.
三、跟蹤分析
測試腳本
create cast(integer as text) with inout as implicit;
select id|| X from t_cast;
跟蹤分析
(gdb) c
Continuing.
Breakpoint 2, oper_select_candidate (nargs=2, input_typeids=0x7ffeb9cca190, candidates=0x13db8a0, operOid=0x7ffeb9cca22c)
at parse_oper.c:330
330 ncandidates = func_match_argtypes(nargs, input_typeids,
(gdb) p *candidates
$1 = {next = 0x13db870, pathpos = 0, oid = 3284, nargs = 2, nvargs = 0, ndargs = 0, argnumbers = 0x0, args = 0x13db8c8}
(gdb) p *candidates- next
$2 = {next = 0x13db840, pathpos = 0, oid = 3681, nargs = 2, nvargs = 0, ndargs = 0, argnumbers = 0x0, args = 0x13db898}
(gdb) p *candidates- next- next
$3 = {next = 0x13db810, pathpos = 0, oid = 3633, nargs = 2, nvargs = 0, ndargs = 0, argnumbers = 0x0, args = 0x13db868}
(gdb) p *candidates- next- next- next
$4 = {next = 0x13db7e0, pathpos = 0, oid = 2780, nargs = 2, nvargs = 0, ndargs = 0, argnumbers = 0x0, args = 0x13db838}
(gdb) p *candidates- next- next- next- next
$5 = {next = 0x13db7b0, pathpos = 0, oid = 374, nargs = 2, nvargs = 0, ndargs = 0, argnumbers = 0x0, args = 0x13db808}
(gdb) p *candidates- next- next- next- next- next
$6 = {next = 0x13db780, pathpos = 0, oid = 349, nargs = 2, nvargs = 0, ndargs = 0, argnumbers = 0x0, args = 0x13db7d8}
(gdb) p *candidates- next- next- next- next- next- next
$7 = {next = 0x13db750, pathpos = 0, oid = 375, nargs = 2, nvargs = 0, ndargs = 0, argnumbers = 0x0, args = 0x13db7a8}
(gdb) p *candidates- next- next- next- next- next- next- next
$8 = {next = 0x13db720, pathpos = 0, oid = 1797, nargs = 2, nvargs = 0, ndargs = 0, argnumbers = 0x0, args = 0x13db778}
(gdb) p *candidates- next- next- next- next- next- next- next- next
$9 = {next = 0x13db6f0, pathpos = 0, oid = 2779, nargs = 2, nvargs = 0, ndargs = 0, argnumbers = 0x0, args = 0x13db748}
(gdb) p *candidates- next- next- next- next- next- next- next- next- next
$10 = {next = 0x13db6c0, pathpos = 0, oid = 654, nargs = 2, nvargs = 0, ndargs = 0, argnumbers = 0x0, args = 0x13db718}
(gdb) p *candidates- next- next- next- next- next- next- next- next- next- next
$11 = {next = 0x0, pathpos = 0, oid = 2018, nargs = 2, nvargs = 0, ndargs = 0, argnumbers = 0x0, args = 0x13db6e8}
(gdb) p *candidates- next- next- next- next- next- next- next- next- next- next- next
Cannot access memory at address 0x0
(gdb) n
334 if (ncandidates == 0)
(gdb)
339 if (ncandidates == 1)
(gdb)
349 candidates = func_select_candidate(nargs, input_typeids, candidates);
(gdb) p ncandidates
$12 = 2
(gdb) p *candidates
$13 = {next = 0x13db810, pathpos = 0, oid = 374, nargs = 2, nvargs = 0, ndargs = 0, argnumbers = 0x0, args = 0x13db808}
(gdb) p *candidates- next
$14 = {next = 0x0, pathpos = 0, oid = 2780, nargs = 2, nvargs = 0, ndargs = 0, argnumbers = 0x0, args = 0x13db838}
(gdb) p *candidates- next- next
Cannot access memory at address 0x0
(gdb)
感謝各位的閱讀,以上就是“PostgreSQL 隱式類型轉(zhuǎn)換中使用哪些操作符實現(xiàn)函數(shù)”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對 PostgreSQL 隱式類型轉(zhuǎn)換中使用哪些操作符實現(xiàn)函數(shù)這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是丸趣 TV,丸趣 TV 小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!