PostgreSQL隐式类型转换中选择操作符的实现函数是什么
这篇文章主要讲解了“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_select_candidate
处理逻辑与PG文档中的类型转换规则一样,其规则详见参考资料中的Operator部分.
/*createtablet_tmp(c1int,c2int);insertintot_tmpvalues(1,1);createcast(integerastext)withinoutasimplicit;testdb=#selectc1||'-'||c2fromt_tmp;psql:ERROR:operatorisnotunique:integer||unknownLINE1:selectc1||'-'||c2fromt_tmp;^HINT:Couldnotchooseabestcandidateoperator.Youmightneedtoaddexplicittypecasts.*//*func_select_candidate()*Giventheinputargtypearrayandmorethanonecandidate*forthefunction,attempttoresolvetheconflict.*给定参数类型和多于1个的候选函数,尝试解决冲突选中合适的函数.**Returnstheselectedcandidateiftheconflictcanberesolved,*otherwisereturnsNULL.*如冲突解决,则返回选中的函数,否则返回NULL.**Notethatthecallerhasalreadydeterminedthatthereisnocandidate*exactlymatchingtheinputargtypes,andhasprunedawayany"candidates"*thataren'tactuallycoercion-compatiblewiththeinputtypes.*注意:调用者已确定没有那个函数完全满足输入的参数类型,*已清除了所有与输入参数类型不兼容的函数.**Thisisalsousedforresolvingambiguousoperatorreferences.Formerly*parse_oper.chaditsown,essentiallyduplicatecodeforthepurpose.*Thefollowingcomments(formerlyinparse_oper.c)arekepttorecordsome*ofthehistoryoftheseheuristics.*本例程同时用于解决模糊操作符引用.以前parse_oper.c有自己的代码,本质上是重复的代码.*接下来的注释(先前在parse_oper.c中)保留用于记录这些启发式的历史.**OLDCOMMENTS:**Thisroutineisnewcode,replacingbinary_oper_select_candidate()*whichdatesfromv4.2/v1.0.xdays.Ittriesveryhardtomatchup*operatorswithtypes,includingallowingtypecoercionsifnecessary.*Theimportantthingisthatthecodedoasmuchaspossible,*while_never_doingthewrongthing,where"thewrongthing"would*bereturninganoperatorwhenotherbetterchoicesareavailable,*orreturninganoperatorwhichisanon-intuitivepossibility.*-thomas1998-05-21*本例程努力的通过类型与operators进行匹配,包括在需要时允许类型强制转换.**Thecommentsbelowcamefrombinary_oper_select_candidate(),and*illustratetheissuesandchoiceswhicharepossible:*-thomas1998-05-20**currentwisdomholdsthatthedefaultoperatorshouldbeoneinwhich*bothoperandshavethesametype(therewillonlybeonesuch*operator)*当前我们认为:默认操作符应该是两个操作数具有相同类型的操作符(只有一个这样的操作符).**7.27.93-Ihavedecidednottodothis;it'stoohardtojustify,and*it'seasyenoughtotypecastexplicitly-avi*[therestofthisroutinewascommentedoutsincethen-ay]**6/23/95-Idon'tcompleteagreewithavi.Inparticular,casting*floatsisapainforusers.Whatevertherationalebehindnotdoing*thisis,Ineedthefollowingspecialcasetowork.**IntheWHEREclauseofaquery,ifafloatisspecifiedwithout*quotes,wetreatitasfloat8.Iaddedthefloat48*operatorsso*thatwecanoperateonfloat4andfloat8.Butnowwehavemorethan*onematchingoperatoriftherightargisunknown(eg.float*specifiedwithquotes).Thisbreaksomestuffintheregression*testwheretherearefloatsinquotesnotproperlycasted.Belowis*thesolution.Inadditiontorequiringtheoperatoroperatesonthe*sametypeforbothoperands[asinthecodeAvioriginally*commentedout],wealsorequirethattheoperatorsbeequivalentin*somesense.(seeequivalentOpersAfterPromotionfordetails.)*-ay6/95*在WHERE语句中,如果float不带引号,PG会把该值视为float8类型.*添加了float48*操作符的目的是可以处理float4和float8两种类型.*但如果右操作数的类型是unknown(如带有引号的浮点数)的话,会有超过一个匹配的operator存在.*这会导致回归测试中出现浮点数使用引号引住而没有被正确转换的情况而失败.*除了要求操作符在同样类型的操作数外,还要求操作符在某些场景是等价的.*/FuncCandidateListfunc_select_candidate(intnargs,Oid*input_typeids,FuncCandidateListcandidates){FuncCandidateListcurrent_candidate,first_candidate,last_candidate;Oid*current_typeids;Oidcurrent_type;inti;intncandidates;intnbestMatch,nmatch,nunknowns;Oidinput_base_typeids[FUNC_MAX_ARGS];TYPCATEGORYslot_category[FUNC_MAX_ARGS],current_category;boolcurrent_is_preferred;boolslot_has_preferred_type[FUNC_MAX_ARGS];boolresolved_unknowns;/*protectlocalfixed-sizearrays*///校验if(nargs>FUNC_MAX_ARGS)ereport(ERROR,(errcode(ERRCODE_TOO_MANY_ARGUMENTS),errmsg_plural("cannotpassmorethan%dargumenttoafunction","cannotpassmorethan%dargumentstoafunction",FUNC_MAX_ARGS,FUNC_MAX_ARGS)));/**Ifanyinputtypesaredomains,reducethemtotheirbasetypes.This*ensuresthatwewillconsiderfunctionsonthebasetypetobe"exact*matches"intheexact-matchheuristic;italsomakesitpossibletodo*somethingusefulwiththetype-categoryheuristics.Notethatthis*makesitdifficult,butnotimpossible,tousefunctionsdeclaredto*takeadomainasaninputdatatype.Suchafunctionwillbeselected*overthebase-typefunctiononlyifitisanexactmatchatall*argumentpositions,andsowasalreadychosenbyourcaller.**Whilewe'reatit,countthenumberofunknown-typeargumentsforuse*later.*计算unknown类型的参数个数*//*Ifanyinputargumentisofadomaintype,treatitasbeingofthedomain'sbasetypeforallsubsequentsteps.Thisensuresthatdomainsactliketheirbasetypesforpurposesofambiguous-operatorresolution.*/nunknowns=0;for(i=0;i<nargs;i++){if(input_typeids[i]!=UNKNOWNOID)input_base_typeids[i]=getBaseType(input_typeids[i]);//基本类型else{//unknown类型/*noneedtocallgetBaseTypeonUNKNOWNOID*/input_base_typeids[i]=UNKNOWNOID;nunknowns++;}}/**Runthroughallcandidatesandkeepthosewiththemostmatcheson*exacttypes.Keepallcandidatesifnonematch.*遍历所有候选,保留那些类型一致的那些.如无匹配的,保留所有候选.*//*Runthroughallcandidatesandkeepthosewiththemostexactmatchesoninputtypes.Keepallcandidatesifnonehaveexactmatches.Ifonlyonecandidateremains,useit;elsecontinuetothenextstep.*/ncandidates=0;//候选数nbestMatch=0;//最佳匹配数last_candidate=NULL;//最后一个候选for(current_candidate=candidates;current_candidate!=NULL;current_candidate=current_candidate->next)//遍历{//获取候选函数的参数current_typeids=current_candidate->args;nmatch=0;for(i=0;i<nargs;i++){//计算参数匹配个数if(input_base_typeids[i]!=UNKNOWNOID&¤t_typeids[i]==input_base_typeids[i])nmatch++;}/*takethisoneasthebestchoicesofar?*///就拿这个作为最好的选择?if((nmatch>nbestMatch)||(last_candidate==NULL)){//1.比最佳参数匹配个数要大,调整最佳匹配数(参数个数)//2.last_candidate==NULL,第一次循环nbestMatch=nmatch;candidates=current_candidate;last_candidate=current_candidate;ncandidates=1;}/*noworsethanthelastchoice,sokeepthisonetoo?*///不会比最后一个选项更糟,所以也保留这个选项elseif(nmatch==nbestMatch){//放到链表中last_candidate->next=current_candidate;last_candidate=current_candidate;ncandidates++;}/*otherwise,don'tbotherkeepingthisone...*///否则,无需保留}if(last_candidate)/*terminaterebuiltlist*/last_candidate->next=NULL;if(ncandidates==1)//只有一个候选,返回returncandidates;/**Stilltoomanycandidates?Nowlookforcandidateswhichhaveeither*exactmatchesorpreferredtypesattheargsthatwillrequire*coercion.(Restrictionaddedin7.4:preferredtypemustbeofsame*categoryasinputtype;givenopreferencetocross-category*conversionstopreferredtypes.)Keepallcandidatesifnonematch.*仍有太多的候选?*检索args精确匹配或强制类型转换后有首选类型的候选项.*(首选类型必须与输入类型是相同的目录).*如无匹配,保留所有候选.*//*Runthroughallcandidatesandkeepthosethatacceptpreferredtypes(oftheinputdatatype'stypecategory)atthemostpositionswheretypeconversionwillberequired.Keepallcandidatesifnoneacceptpreferredtypes.Ifonlyonecandidateremains,useit;elsecontinuetothenextstep.*/for(i=0;i<nargs;i++)/*avoidmultiplelookups*/slot_category[i]=TypeCategory(input_base_typeids[i]);//获取类型目录ncandidates=0;nbestMatch=0;last_candidate=NULL;for(current_candidate=candidates;current_candidate!=NULL;current_candidate=current_candidate->next)//遍历{current_typeids=current_candidate->args;//参数nmatch=0;for(i=0;i<nargs;i++){if(input_base_typeids[i]!=UNKNOWNOID){if(current_typeids[i]==input_base_typeids[i]||IsPreferredType(slot_category[i],current_typeids[i]))nmatch++;//不要求精确匹配,存在首选项一样的参数也可以了}}if((nmatch>nbestMatch)||(last_candidate==NULL)){//1.比最佳参数匹配个数要大,调整最佳匹配数(参数个数)//2.last_candidate==NULL,第一次循环nbestMatch=nmatch;candidates=current_candidate;last_candidate=current_candidate;ncandidates=1;}elseif(nmatch==nbestMatch){//保留跟最佳匹配一样的候选last_candidate->next=current_candidate;last_candidate=current_candidate;ncandidates++;}}if(last_candidate)/*terminaterebuiltlist*/last_candidate->next=NULL;if(ncandidates==1)returncandidates;///**Stilltoomanycandidates?Tryassigningtypesfortheunknowninputs.*仍有过多的候选?尝试为unknown类型赋值**Iftherearenounknowninputs,wehavenomoreheuristicsthatapply,*andmustfail.*如无unknown类型,没有更多的启发式可用,就此失败*/if(nunknowns==0)//失败returnNULL;/*failedtoselectabestcandidate*//**Thenextstepexamineseachunknownargumentpositiontoseeifwecan*determinea"typecategory"forit.Ifanycandidatehasaninput*datatypeofSTRINGcategory,useSTRINGcategory(thisbiastowards*STRINGisappropriatesinceunknown-typeliteralslooklikestrings).*Otherwise,ifallthecandidatesagreeonthetypecategoryofthis*argumentposition,usethatcategory.Otherwise,failbecausewe*cannotdetermineacategory.*下一步,检查每一个unknown类型的参数位置来确定是否可以找到该参数的类型目录.*如果候选存在STRING目录的输入数据类型,使用STRING目录(因为unknownliterals看起来像是string)*否则,如果所有候选认同该参数位置上的类型目录,则使用此目录.*不能确定目录,则失败.**Ifweareabletodetermineatypecategory,alsonoticewhetheranyof*thecandidatestakesapreferreddatatypewithinthecategory.*如果可以确定类型目录,还要注意候选项中是否有一个在目录中采用首选数据类型.**Havingcompletedthisexamination,removecandidatesthatacceptthe*wrongcategoryatanyunknownposition.Also,ifatleastone*candidateacceptedapreferredtypeataposition,removecandidates*thatacceptnon-preferredtypes.Ifjustonecandidateremains,return*thatone.However,ifthisruleturnsouttorejectallcandidates,*keepthemallinstead.*完成该检查后,去掉在unknown位置上接受错误目录的候选.*同时,如果至少有一个候选接受该位置上的首选类型,去掉无首选类型的候选.*如果只有一个候选保留,则返回该候选.*否则,拒绝所有的候选,保留所有.*//*Ifanyinputargumentsareunknown,checkthetypecategoriesacceptedatthoseargumentpositionsbytheremainingcandidates.Ateachposition,selectthestringcategoryifanycandidateacceptsthatcategory.(Thisbiastowardsstringisappropriatesinceanunknown-typeliterallookslikeastring.)Otherwise,ifalltheremainingcandidatesacceptthesametypecategory,selectthatcategory;otherwisefailbecausethecorrectchoicecannotbededucedwithoutmoreclues.Nowdiscardcandidatesthatdonotaccepttheselectedtypecategory.Furthermore,ifanycandidateacceptsapreferredtypeinthatcategory,discardcandidatesthatacceptnon-preferredtypesforthatargument.Keepallcandidatesifnonesurvivethesetests.Ifonlyonecandidateremains,useit;elsecontinuetothenextstep.*/resolved_unknowns=false;//是否已解决unknown类型标记for(i=0;i<nargs;i++)//遍历参数{boolhave_conflict;//是否存在冲突标记if(input_base_typeids[i]!=UNKNOWNOID)continue;//非unknown类型resolved_unknowns=true;/*假定可以搞掂assumewecandoit*/slot_category[i]=TYPCATEGORY_INVALID;slot_has_preferred_type[i]=false;have_conflict=false;for(current_candidate=candidates;current_candidate!=NULL;current_candidate=current_candidate->next)//遍历所有候选{current_typeids=current_candidate->args;current_type=current_typeids[i];get_type_category_preferred(current_type,¤t_category,¤t_is_preferred);if(slot_category[i]==TYPCATEGORY_INVALID){/*firstcandidate*///第一个候选slot_category[i]=current_category;slot_has_preferred_type[i]=current_is_preferred;}elseif(current_category==slot_category[i]){/*morecandidatesinsamecategory*///同样的目录有更多的候选slot_has_preferred_type[i]|=current_is_preferred;}else{/*categoryconflict!*///目录冲突if(current_category==TYPCATEGORY_STRING){/*STRINGalwayswinsifavailable*///如可能,首选STRINGslot_category[i]=current_category;slot_has_preferred_type[i]=current_is_preferred;}else{/**Rememberconflict,butkeepgoing(mightfindSTRING)*存在冲突,但继续处理*/have_conflict=true;}}}if(have_conflict&&slot_category[i]!=TYPCATEGORY_STRING){//存在冲突,并且目录不是STRING/*Failedtoresolvecategoryconflictatthisposition*///无法解决冲突resolved_unknowns=false;break;}}if(resolved_unknowns){//已解决了冲突/*Stripnon-matchingcandidates*/ncandidates=0;first_candidate=candidates;last_candidate=NULL;for(current_candidate=candidates;current_candidate!=NULL;current_candidate=current_candidate->next)//再次遍历{boolkeepit=true;//如果至少有一个候选接受该位置上的首选类型,去掉无首选类型的候选.current_typeids=current_candidate->args;for(i=0;i<nargs;i++)//遍历参数{if(input_base_typeids[i]!=UNKNOWNOID)continue;//非unknown参数,跳过current_type=current_typeids[i];//当前类型get_type_category_preferred(current_type,¤t_category,¤t_is_preferred);//首选类型if(current_category!=slot_category[i]){//当前目录不等于slot中的目录,退出参数循环keepit=false;break;}if(slot_has_preferred_type[i]&&!current_is_preferred){//存在首选类型但当前首选类型为NULL,退出参数循环keepit=false;break;}}if(keepit){/*keepthiscandidate*///保留该候选last_candidate=current_candidate;ncandidates++;}else{/*forgetthiscandidate*///if(last_candidate)last_candidate->next=current_candidate->next;elsefirst_candidate=current_candidate->next;}}/*ifwefoundanymatches,restrictourattentiontothose*/if(last_candidate){candidates=first_candidate;/*terminaterebuiltlist*/last_candidate->next=NULL;}if(ncandidates==1)returncandidates;}/**Lastgasp:iftherearebothknown-andunknown-typeinputs,andall*theknowntypesarethesame,assumetheunknowninputsarealsothat*type,andseeifthatgivesusauniquematch.Ifso,usethatmatch.*最后:如果存在known和unknown类型同时存在,*并且已知类型是一样的,那么假定unknown输入也是该类型,然后看看是否有唯一匹配,如有则使用该候选.**NOTE:forabinaryoperatorwithoneunknownandonenon-unknowninput,*wealreadytriedthisheuristicinbinary_oper_exact().However,that*codeonlyfindsexactmatches,whereasherewewillhandlematchesthat*involvecoercion,polymorphictyperesolution,etc.*注意:对于带有一个unknown和一个已知类型参数的二元操作符,*已在binary_oper_exact()函数中使用该启发式.*但是,那些代码只能发现准确的匹配,而这里我们将处理涉及强制、多态类型解析等的匹配。*//*Iftherearebothunknownandknown-typearguments,andalltheknown-typeargumentshavethesametype,assumethattheunknownargumentsarealsoofthattype,andcheckwhichcandidatescanacceptthattypeattheunknown-argumentpositions.Ifexactlyonecandidatepassesthistest,useit.Otherwise,fail.*/if(nunknowns<nargs){Oidknown_type=UNKNOWNOID;for(i=0;i<nargs;i++)//找到基本类型,找不到则失败{if(input_base_typeids[i]==UNKNOWNOID)continue;if(known_type==UNKNOWNOID)/*firstknownarg?*/known_type=input_base_typeids[i];elseif(known_type!=input_base_typeids[i]){/*oops,notallmatch*/known_type=UNKNOWNOID;break;}}if(known_type!=UNKNOWNOID)//找到了基本类型{/*okay,justoneknowntype,applytheheuristic*/for(i=0;i<nargs;i++)input_base_typeids[i]=known_type;//使用该基本类型ncandidates=0;last_candidate=NULL;for(current_candidate=candidates;current_candidate!=NULL;current_candidate=current_candidate->next)//遍历{current_typeids=current_candidate->args;if(can_coerce_type(nargs,input_base_typeids,current_typeids,COERCION_IMPLICIT)){if(++ncandidates>1)break;/*notunique,giveup*/last_candidate=current_candidate;}}if(ncandidates==1){/*successfullyidentifiedauniquematch*///成功!last_candidate->next=NULL;returnlast_candidate;}}}//返回NULLreturnNULL;/*failedtoselectabestcandidate*/}/*func_select_candidate()*/三、跟踪分析
测试脚本
createcast(integerastext)withinoutasimplicit;selectid||'X'fromt_cast;
跟踪分析
Breakpoint1,func_select_candidate(nargs=2,input_typeids=0x7fff5f3ac6c0,candidates=0x2daa6f0)atparse_func.c:10211021if(nargs>FUNC_MAX_ARGS)(gdb)p*input_typeids$6=23(gdb)p*candidates$7={next=0x2daa720,pathpos=0,oid=654,nargs=2,nvargs=0,ndargs=0,argnumbers=0x0,args=0x2daa718}(gdb)p*candidates->next$8={next=0x2daa7e0,pathpos=0,oid=2779,nargs=2,nvargs=0,ndargs=0,argnumbers=0x0,args=0x2daa748}(gdb)p*candidates->next->next$9={next=0x2daa810,pathpos=0,oid=374,nargs=2,nvargs=0,ndargs=0,argnumbers=0x0,args=0x2daa808}(gdb)p*candidates->next->next->next$10={next=0x0,pathpos=0,oid=2780,nargs=2,nvargs=0,ndargs=0,argnumbers=0x0,args=0x2daa838}(gdb)p*candidates->next->next->next->nextCannotaccessmemoryataddress0x0(gdb)n1042nunknowns=0;(gdb)1043for(i=0;i<nargs;i++)(gdb)1045if(input_typeids[i]!=UNKNOWNOID)(gdb)1046input_base_typeids[i]=getBaseType(input_typeids[i]);(gdb)1043for(i=0;i<nargs;i++)(gdb)pinput_base_typeids[0]$12=23(gdb)n1045if(input_typeids[i]!=UNKNOWNOID)(gdb)1050input_base_typeids[i]=UNKNOWNOID;(gdb)pinput_typeids[i]$13=705(gdb)pUNKNOWNOID$14=705(gdb)n1051nunknowns++;(gdb)1043for(i=0;i<nargs;i++)(gdb)1059ncandidates=0;(gdb)1060nbestMatch=0;(gdb)1061last_candidate=NULL;(gdb)1062for(current_candidate=candidates;(gdb)1066current_typeids=current_candidate->args;(gdb)1067nmatch=0;(gdb)1068for(i=0;i<nargs;i++)(gdb)1070if(input_base_typeids[i]!=UNKNOWNOID&&(gdb)1071current_typeids[i]==input_base_typeids[i])(gdb)pcurrent_typeids[i]$15=25(gdb)pinput_base_typeids[i]$16=23(gdb)n1070if(input_base_typeids[i]!=UNKNOWNOID&&(gdb)1068for(i=0;i<nargs;i++)(gdb)1070if(input_base_typeids[i]!=UNKNOWNOID&&(gdb)1068for(i=0;i<nargs;i++)(gdb)1076if((nmatch>nbestMatch)||(last_candidate==NULL))(gdb)1078nbestMatch=nmatch;(gdb)1079candidates=current_candidate;(gdb)1080last_candidate=current_candidate;(gdb)1081ncandidates=1;(gdb)1064current_candidate=current_candidate->next)(gdb)1062for(current_candidate=candidates;(gdb)1066current_typeids=current_candidate->args;(gdb)1067nmatch=0;(gdb)1068for(i=0;i<nargs;i++)(gdb)1070if(input_base_typeids[i]!=UNKNOWNOID&&(gdb)1071current_typeids[i]==input_base_typeids[i])(gdb)1070if(input_base_typeids[i]!=UNKNOWNOID&&(gdb)1068for(i=0;i<nargs;i++)(gdb)1070if(input_base_typeids[i]!=UNKNOWNOID&&(gdb)1068for(i=0;i<nargs;i++)(gdb)1076if((nmatch>nbestMatch)||(last_candidate==NULL))(gdb)1084elseif(nmatch==nbestMatch)(gdb)1086last_candidate->next=current_candidate;(gdb)p*last_candidate$17={next=0x2daa720,pathpos=0,oid=654,nargs=2,nvargs=0,ndargs=0,argnumbers=0x0,args=0x2daa718}(gdb)p*current_candidate$18={next=0x2daa7e0,pathpos=0,oid=2779,nargs=2,nvargs=0,ndargs=0,argnumbers=0x0,args=0x2daa748}(gdb)n1087last_candidate=current_candidate;(gdb)1088ncandidates++;(gdb)1064current_candidate=current_candidate->next)(gdb)1062for(current_candidate=candidates;(gdb)1066current_typeids=current_candidate->args;(gdb)1067nmatch=0;(gdb)1068for(i=0;i<nargs;i++)(gdb)1070if(input_base_typeids[i]!=UNKNOWNOID&&(gdb)1071current_typeids[i]==input_base_typeids[i])(gdb)1070if(input_base_typeids[i]!=UNKNOWNOID&&(gdb)1068for(i=0;i<nargs;i++)(gdb)1070if(input_base_typeids[i]!=UNKNOWNOID&&(gdb)1068for(i=0;i<nargs;i++)(gdb)1076if((nmatch>nbestMatch)||(last_candidate==NULL))(gdb)p*candidates$19={next=0x2daa720,pathpos=0,oid=654,nargs=2,nvargs=0,ndargs=0,argnumbers=0x0,args=0x2daa718}(gdb)n1084elseif(nmatch==nbestMatch)(gdb)1086last_candidate->next=current_candidate;(gdb)1087last_candidate=current_candidate;(gdb)1088ncandidates++;(gdb)n1064current_candidate=current_candidate->next)(gdb)1062for(current_candidate=candidates;(gdb)1066current_typeids=current_candidate->args;(gdb)1067nmatch=0;(gdb)1068for(i=0;i<nargs;i++)(gdb)1070if(input_base_typeids[i]!=UNKNOWNOID&&(gdb)1071current_typeids[i]==input_base_typeids[i])(gdb)1070if(input_base_typeids[i]!=UNKNOWNOID&&(gdb)1068for(i=0;i<nargs;i++)(gdb)1070if(input_base_typeids[i]!=UNKNOWNOID&&(gdb)1068for(i=0;i<nargs;i++)(gdb)1076if((nmatch>nbestMatch)||(last_candidate==NULL))(gdb)1084elseif(nmatch==nbestMatch)(gdb)1086last_candidate->next=current_candidate;(gdb)1087last_candidate=current_candidate;(gdb)1088ncandidates++;(gdb)1064current_candidate=current_candidate->next)(gdb)1062for(current_candidate=candidates;(gdb)1093if(last_candidate)/*terminaterebuiltlist*/(gdb)1094last_candidate->next=NULL;(gdb)1096if(ncandidates==1)(gdb)p*last_candidate$20={next=0x0,pathpos=0,oid=2780,nargs=2,nvargs=0,ndargs=0,argnumbers=0x0,args=0x2daa838}(gdb)n1106for(i=0;i<nargs;i++)/*avoidmultiplelookups*/(gdb)1107slot_category[i]=TypeCategory(input_base_typeids[i]);(gdb)1106for(i=0;i<nargs;i++)/*avoidmultiplelookups*/(gdb)pslot_category[i]$21=78'N'(gdb)n1107slot_category[i]=TypeCategory(input_base_typeids[i]);(gdb)1106for(i=0;i<nargs;i++)/*avoidmultiplelookups*/(gdb)pslot_category[i]$22=88'X'(gdb)n1108ncandidates=0;(gdb)1109nbestMatch=0;(gdb)1110last_candidate=NULL;(gdb)1111for(current_candidate=candidates;(gdb)1115current_typeids=current_candidate->args;(gdb)1116nmatch=0;(gdb)1117for(i=0;i<nargs;i++)(gdb)1119if(input_base_typeids[i]!=UNKNOWNOID)(gdb)1121if(current_typeids[i]==input_base_typeids[i]||(gdb)pcurrent_typeids[i]$23=25(gdb)n1122IsPreferredType(slot_category[i],current_typeids[i]))(gdb)1121if(current_typeids[i]==input_base_typeids[i]||(gdb)1117for(i=0;i<nargs;i++)(gdb)1119if(input_base_typeids[i]!=UNKNOWNOID)(gdb)1117for(i=0;i<nargs;i++)(gdb)1127if((nmatch>nbestMatch)||(last_candidate==NULL))(gdb)1129nbestMatch=nmatch;(gdb)1130candidates=current_candidate;(gdb)1131last_candidate=current_candidate;(gdb)1132ncandidates=1;(gdb)1113current_candidate=current_candidate->next)(gdb)1111for(current_candidate=candidates;(gdb)1115current_typeids=current_candidate->args;(gdb)1116nmatch=0;(gdb)1117for(i=0;i<nargs;i++)(gdb)1119if(input_base_typeids[i]!=UNKNOWNOID)(gdb)1121if(current_typeids[i]==input_base_typeids[i]||(gdb)1122IsPreferredType(slot_category[i],current_typeids[i]))(gdb)1121if(current_typeids[i]==input_base_typeids[i]||(gdb)1117for(i=0;i<nargs;i++)(gdb)1119if(input_base_typeids[i]!=UNKNOWNOID)(gdb)1117for(i=0;i<nargs;i++)(gdb)1127if((nmatch>nbestMatch)||(last_candidate==NULL))(gdb)1134elseif(nmatch==nbestMatch)(gdb)1136last_candidate->next=current_candidate;(gdb)1137last_candidate=current_candidate;(gdb)1138ncandidates++;(gdb)1113current_candidate=current_candidate->next)(gdb)1111for(current_candidate=candidates;(gdb)1115current_typeids=current_candidate->args;(gdb)1116nmatch=0;(gdb)1117for(i=0;i<nargs;i++)(gdb)1119if(input_base_typeids[i]!=UNKNOWNOID)(gdb)1121if(current_typeids[i]==input_base_typeids[i]||(gdb)1122IsPreferredType(slot_category[i],current_typeids[i]))(gdb)p*last_candidate$24={next=0x2daa7e0,pathpos=0,oid=2779,nargs=2,nvargs=0,ndargs=0,argnumbers=0x0,args=0x2daa748}(gdb)n1121if(current_typeids[i]==input_base_typeids[i]||(gdb)1117for(i=0;i<nargs;i++)(gdb)1119if(input_base_typeids[i]!=UNKNOWNOID)(gdb)1117for(i=0;i<nargs;i++)(gdb)1127if((nmatch>nbestMatch)||(last_candidate==NULL))(gdb)1134elseif(nmatch==nbestMatch)(gdb)1136last_candidate->next=current_candidate;(gdb)1137last_candidate=current_candidate;(gdb)1138ncandidates++;(gdb)1113current_candidate=current_candidate->next)(gdb)1111for(current_candidate=candidates;(gdb)1115current_typeids=current_candidate->args;(gdb)1116nmatch=0;(gdb)1117for(i=0;i<nargs;i++)(gdb)1119if(input_base_typeids[i]!=UNKNOWNOID)(gdb)1121if(current_typeids[i]==input_base_typeids[i]||(gdb)1122IsPreferredType(slot_category[i],current_typeids[i]))(gdb)1121if(current_typeids[i]==input_base_typeids[i]||(gdb)1117for(i=0;i<nargs;i++)(gdb)1119if(input_base_typeids[i]!=UNKNOWNOID)(gdb)1117for(i=0;i<nargs;i++)(gdb)1127if((nmatch>nbestMatch)||(last_candidate==NULL))(gdb)1134elseif(nmatch==nbestMatch)(gdb)1136last_candidate->next=current_candidate;(gdb)1137last_candidate=current_candidate;(gdb)1138ncandidates++;(gdb)1113current_candidate=current_candidate->next)(gdb)1111for(current_candidate=candidates;(gdb)1142if(last_candidate)/*terminaterebuiltlist*/(gdb)1143last_candidate->next=NULL;(gdb)1145if(ncandidates==1)(gdb)1154if(nunknowns==0)(gdb)1176resolved_unknowns=false;(gdb)1177for(i=0;i<nargs;i++)(gdb)1181if(input_base_typeids[i]!=UNKNOWNOID)(gdb)1182continue;(gdb)1177for(i=0;i<nargs;i++)(gdb)1181if(input_base_typeids[i]!=UNKNOWNOID)(gdb)1183resolved_unknowns=true;/*assumewecandoit*/(gdb)1184slot_category[i]=TYPCATEGORY_INVALID;(gdb)1185slot_has_preferred_type[i]=false;(gdb)1186have_conflict=false;(gdb)1187for(current_candidate=candidates;(gdb)1191current_typeids=current_candidate->args;(gdb)1192current_type=current_typeids[i];(gdb)1193get_type_category_preferred(current_type,(gdb)1196if(slot_category[i]==TYPCATEGORY_INVALID)(gdb)pcurrent_type$25=25(gdb)pcurrent_category$26=83'S'(gdb)pcurrent_is_preferred$27=true(gdb)pslot_category[i]$28=0'\000'(gdb)n1199slot_category[i]=current_category;(gdb)1200slot_has_preferred_type[i]=current_is_preferred;(gdb)1189current_candidate=current_candidate->next)(gdb)pcurrent_category$29=83'S'(gdb)pcurrent_is_preferred$30=true(gdb)n1187for(current_candidate=candidates;(gdb)1191current_typeids=current_candidate->args;(gdb)1192current_type=current_typeids[i];(gdb)1193get_type_category_preferred(current_type,(gdb)1196if(slot_category[i]==TYPCATEGORY_INVALID)(gdb)pcurrent_category$31=80'P'(gdb)pcurrent_is_preferred$32=false(gdb)n1202elseif(current_category==slot_category[i])(gdb)1210if(current_category==TYPCATEGORY_STRING)(gdb)1221have_conflict=true;(gdb)1189current_candidate=current_candidate->next)(gdb)1187for(current_candidate=candidates;(gdb)1191current_typeids=current_candidate->args;(gdb)1192current_type=current_typeids[i];(gdb)1193get_type_category_preferred(current_type,(gdb)1196if(slot_category[i]==TYPCATEGORY_INVALID)(gdb)pcurrent_type$33=2277(gdb)pcurrent_is_preferred$34=false(gdb)pcurrent_category$35=80'P'(gdb)n1202elseif(current_category==slot_category[i])(gdb)1210if(current_category==TYPCATEGORY_STRING)(gdb)1221have_conflict=true;(gdb)1189current_candidate=current_candidate->next)(gdb)1187for(current_candidate=candidates;(gdb)1191current_typeids=current_candidate->args;(gdb)1192current_type=current_typeids[i];(gdb)1193get_type_category_preferred(current_type,(gdb)1196if(slot_category[i]==TYPCATEGORY_INVALID)(gdb)1202elseif(current_category==slot_category[i])(gdb)1205slot_has_preferred_type[i]|=current_is_preferred;(gdb)pcurrent_category$36=83'S'(gdb)n1189current_candidate=current_candidate->next)(gdb)1187for(current_candidate=candidates;(gdb)1225if(have_conflict&&slot_category[i]!=TYPCATEGORY_STRING)(gdb)1177for(i=0;i<nargs;i++)(gdb)presolved_unknowns$37=true(gdb)n1233if(resolved_unknowns)(gdb)1236ncandidates=0;(gdb)1237first_candidate=candidates;(gdb)1238last_candidate=NULL;(gdb)1239for(current_candidate=candidates;(gdb)1243boolkeepit=true;(gdb)1245current_typeids=current_candidate->args;(gdb)1246for(i=0;i<nargs;i++)(gdb)1248if(input_base_typeids[i]!=UNKNOWNOID)(gdb)1249continue;(gdb)1246for(i=0;i<nargs;i++)(gdb)1248if(input_base_typeids[i]!=UNKNOWNOID)(gdb)1250current_type=current_typeids[i];(gdb)1251get_type_category_preferred(current_type,(gdb)pcurrent_type$38=25(gdb)n1254if(current_category!=slot_category[i])(gdb)pcurrent_category$39=83'S'(gdb)pslot_category[i]$40=83'S'(gdb)n1259if(slot_has_preferred_type[i]&&!current_is_preferred)(gdb)1246for(i=0;i<nargs;i++)(gdb)1265if(keepit)(gdb)1268last_candidate=current_candidate;(gdb)p*current_candidate$41={next=0x2daa720,pathpos=0,oid=654,nargs=2,nvargs=0,ndargs=0,argnumbers=0x0,args=0x2daa718}(gdb)n1269ncandidates++;(gdb)1241current_candidate=current_candidate->next)(gdb)n1239for(current_candidate=candidates;(gdb)1243boolkeepit=true;(gdb)1245current_typeids=current_candidate->args;(gdb)1246for(i=0;i<nargs;i++)(gdb)1248if(input_base_typeids[i]!=UNKNOWNOID)(gdb)1249continue;(gdb)1246for(i=0;i<nargs;i++)(gdb)1248if(input_base_typeids[i]!=UNKNOWNOID)(gdb)1250current_type=current_typeids[i];(gdb)1251get_type_category_preferred(current_type,(gdb)1254if(current_category!=slot_category[i])(gdb)pcurrent_type$42=2776(gdb)pcurrent_category$43=80'P'(gdb)n1256keepit=false;(gdb)1257break;(gdb)1265if(keepit)(gdb)1274if(last_candidate)(gdb)1275last_candidate->next=current_candidate->next;(gdb)1241current_candidate=current_candidate->next)(gdb)p*last_candidate$44={next=0x2daa7e0,pathpos=0,oid=654,nargs=2,nvargs=0,ndargs=0,argnumbers=0x0,args=0x2daa718}(gdb)n1239for(current_candidate=candidates;(gdb)1243boolkeepit=true;(gdb)1245current_typeids=current_candidate->args;(gdb)1246for(i=0;i<nargs;i++)(gdb)1248if(input_base_typeids[i]!=UNKNOWNOID)(gdb)1249continue;(gdb)1246for(i=0;i<nargs;i++)(gdb)1248if(input_base_typeids[i]!=UNKNOWNOID)(gdb)1250current_type=current_typeids[i];(gdb)1251get_type_category_preferred(current_type,(gdb)pcurrent_type$45=2277(gdb)pcurrent_category$46=80'P'(gdb)n1254if(current_category!=slot_category[i])(gdb)1256keepit=false;(gdb)1257break;(gdb)1265if(keepit)(gdb)1274if(last_candidate)(gdb)1275last_candidate->next=current_candidate->next;(gdb)1241current_candidate=current_candidate->next)(gdb)1239for(current_candidate=candidates;(gdb)1243boolkeepit=true;(gdb)1245current_typeids=current_candidate->args;(gdb)1246for(i=0;i<nargs;i++)(gdb)1248if(input_base_typeids[i]!=UNKNOWNOID)(gdb)1249continue;(gdb)1246for(i=0;i<nargs;i++)(gdb)1248if(input_base_typeids[i]!=UNKNOWNOID)(gdb)1250current_type=current_typeids[i];(gdb)1251get_type_category_preferred(current_type,(gdb)1254if(current_category!=slot_category[i])(gdb)1259if(slot_has_preferred_type[i]&&!current_is_preferred)(gdb)pcurrent_category$47=83'S'(gdb)p*current_candidate$48={next=0x0,pathpos=0,oid=2780,nargs=2,nvargs=0,ndargs=0,argnumbers=0x0,args=0x2daa838}(gdb)n1246for(i=0;i<nargs;i++)(gdb)1265if(keepit)(gdb)1268last_candidate=current_candidate;(gdb)1269ncandidates++;(gdb)1241current_candidate=current_candidate->next)(gdb)1239for(current_candidate=candidates;(gdb)1282if(last_candidate)(gdb)1284candidates=first_candidate;(gdb)p*first_candidate$49={next=0x2daa810,pathpos=0,oid=654,nargs=2,nvargs=0,ndargs=0,argnumbers=0x0,args=0x2daa718}(gdb)p*last_candidate$50={next=0x0,pathpos=0,oid=2780,nargs=2,nvargs=0,ndargs=0,argnumbers=0x0,args=0x2daa838}(gdb)n1286last_candidate->next=NULL;(gdb)n1289if(ncandidates==1)(gdb)1303if(nunknowns<nargs)(gdb)p*candidates$51={next=0x2daa810,pathpos=0,oid=654,nargs=2,nvargs=0,ndargs=0,argnumbers=0x0,args=0x2daa718}(gdb)p*candidates->next$52={next=0x0,pathpos=0,oid=2780,nargs=2,nvargs=0,ndargs=0,argnumbers=0x0,args=0x2daa838}(gdb)n1305Oidknown_type=UNKNOWNOID;(gdb)1307for(i=0;i<nargs;i++)(gdb)1309if(input_base_typeids[i]==UNKNOWNOID)(gdb)1311if(known_type==UNKNOWNOID)/*firstknownarg?*/(gdb)1312known_type=input_base_typeids[i];(gdb)1307for(i=0;i<nargs;i++)(gdb)pknown_type$53=23(gdb)n1309if(input_base_typeids[i]==UNKNOWNOID)(gdb)1310continue;(gdb)1307for(i=0;i<nargs;i++)(gdb)1321if(known_type!=UNKNOWNOID)(gdb)1324for(i=0;i<nargs;i++)(gdb)1325input_base_typeids[i]=known_type;(gdb)1324for(i=0;i<nargs;i++)(gdb)pknown_type$54=23(gdb)n1325input_base_typeids[i]=known_type;(gdb)1324for(i=0;i<nargs;i++)(gdb)1326ncandidates=0;(gdb)1327last_candidate=NULL;(gdb)1328for(current_candidate=candidates;(gdb)1332current_typeids=current_candidate->args;(gdb)1333if(can_coerce_type(nargs,input_base_typeids,current_typeids,(gdb)1336if(++ncandidates>1)(gdb)n1338last_candidate=current_candidate;(gdb)1330current_candidate=current_candidate->next)(gdb)1328for(current_candidate=candidates;(gdb)1332current_typeids=current_candidate->args;(gdb)1333if(can_coerce_type(nargs,input_base_typeids,current_typeids,(gdb)1336if(++ncandidates>1)(gdb)1337break;/*notunique,giveup*/(gdb)1341if(ncandidates==1)(gdb)1350returnNULL;/*failedtoselectabestcandidate*/(gdb)
感谢各位的阅读,以上就是“PostgreSQL隐式类型转换中选择操作符的实现函数是什么”的内容了,经过本文的学习后,相信大家对PostgreSQL隐式类型转换中选择操作符的实现函数是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。