这篇文章主要讲解了“PostgreSQL隐式类型转换中使用哪些操作符实现函数”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“PostgreSQL隐式类型转换中使用哪些操作符实现函数”吧!

一、数据结构

FuncCandidateList
该结构体存储检索得到的所有可能选中的函数或操作符链表.

/**Thisstructureholdsalistofpossiblefunctionsoroperators*foundbynamespacelookup.Eachfunction/operatorisidentified*byOIDandbyargumenttypes;thelistmustbeprunedbytype*resolutionrulesthatareembodiedintheparser,nothere.*SeeFuncnameGetCandidates'scommentsformoreinfo.*该结构体存储检索得到的所有可能选中的函数或操作符链表.*每一个函数/操作符通过OID和参数类型唯一确定,*通过集成到分析器中的typeresolutionrules来确定裁剪该链表(但不是在这里实现)*详细可参考FuncnameGetCandidates函数.*/typedefstruct_FuncCandidateList{struct_FuncCandidateList*next;//用于namespace检索内部使用intpathpos;/*forinternaluseofnamespacelookup*///OIDOidoid;/*thefunctionoroperator'sOID*///参数个数intnargs;/*numberofargtypesreturned*///variadicarray的参数个数intnvargs;/*numberofargstobecomevariadicarray*///默认参数个数intndargs;/*numberofdefaultedargs*///参数位置索引int*argnumbers;/*args'positionalindexes,ifnamedcall*///参数类型Oidargs[FLEXIBLE_ARRAY_MEMBER];/*argtypes*/}*FuncCandidateList;二、源码解读

func_match_argtypes
给定候选函数列表(正确的函数名称/参数个数匹配)和输入数据类型OIDs数组,生成实际可匹配输入数据类型(完全匹配或可转换)的候选函数链表,然后符合条件的候选函数个数.

/*func_match_argtypes()**Givenalistofcandidatefunctions(havingtherightnameandnumber*ofarguments)andanarrayofinputdatatypeOIDs,produceashortlistof*thosecandidatesthatactuallyaccepttheinputdatatypes(eitherexactly*orbycoercion),andreturnthenumberofsuchcandidates.*给定候选函数列表(正确的函数名称/参数个数匹配)和输入数据类型OIDs数组,*生成实际可匹配输入数据类型(完全匹配或可转换)的候选函数链表,然后符合条件的候选函数个数**Notethatcan_coerce_typewillassumethatUNKNOWNinputsarecoercibleto*anything,socandidateswillnotbeeliminatedonthatbasis.*can_coerce_type函数假定UNKNOWN输入可转换为任意类型.**NB:okaytomodifyinputliststructure,aslongaswefindatleast*onematch.Ifnomatchatall,thelistmustremainunmodified.*注意:如果只是找到一个匹配的候选函数,修改输入链表结构是OK的.如无匹配,则链表保持不变.*/intfunc_match_argtypes(intnargs,Oid*input_typeids,FuncCandidateListraw_candidates,FuncCandidateList*candidates)/*returnvalue*/{FuncCandidateListcurrent_candidate;//当前候选FuncCandidateListnext_candidate;//下一候选intncandidates=0;*candidates=NULL;for(current_candidate=raw_candidates;current_candidate!=NULL;current_candidate=next_candidate)//遍历候选函数{next_candidate=current_candidate->next;if(can_coerce_type(nargs,input_typeids,current_candidate->args,COERCION_IMPLICIT))//可匹配输入数据类型(完全匹配或可转换){current_candidate->next=*candidates;*candidates=current_candidate;ncandidates++;}}returnncandidates;}/*func_match_argtypes()*/

在pg_operator中,输入参数类型与operator的参数类型匹配或可转换,可进入候选函数链表.

三、跟踪分析

测试脚本

createcast(integerastext)withinoutasimplicit;selectid||'X'fromt_cast;

跟踪分析

(gdb)cContinuing.Breakpoint2,oper_select_candidate(nargs=2,input_typeids=0x7ffeb9cca190,candidates=0x13db8a0,operOid=0x7ffeb9cca22c)atparse_oper.c:330330ncandidates=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->nextCannotaccessmemoryataddress0x0(gdb)n334if(ncandidates==0)(gdb)339if(ncandidates==1)(gdb)349candidates=func_select_candidate(nargs,input_typeids,candidates);(gdb)pncandidates$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->nextCannotaccessmemoryataddress0x0(gdb)

感谢各位的阅读,以上就是“PostgreSQL隐式类型转换中使用哪些操作符实现函数”的内容了,经过本文的学习后,相信大家对PostgreSQL隐式类型转换中使用哪些操作符实现函数这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!