文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

PostgreSQL隐式类型转换中选择操作符的实现函数是什么

2024-04-02 19:55

关注

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

一、数据结构

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


typedef struct _FuncCandidateList
{
    struct _FuncCandidateList *next;
    //用于namespace检索内部使用
    int         pathpos;        
    //OID
    Oid         oid;            
    //参数个数 
    int         nargs;          
    //variadic array的参数个数
    int         nvargs;         
    //默认参数个数
    int         ndargs;         
    //参数位置索引
    int        *argnumbers;     
    //参数类型
    Oid         args[FLEXIBLE_ARRAY_MEMBER];    
}          *FuncCandidateList;

二、源码解读

func_select_candidate
处理逻辑与PG文档中的类型转换规则一样,其规则详见参考资料中的Operator部分.



FuncCandidateList
func_select_candidate(int nargs,
                      Oid *input_typeids,
                      FuncCandidateList candidates)
{
    FuncCandidateList current_candidate,
                first_candidate,
                last_candidate;
    Oid        *current_typeids;
    Oid         current_type;
    int         i;
    int         ncandidates;
    int         nbestMatch,
                nmatch,
                nunknowns;
    Oid         input_base_typeids[FUNC_MAX_ARGS];
    TYPCATEGORY slot_category[FUNC_MAX_ARGS],
                current_category;
    bool        current_is_preferred;
    bool        slot_has_preferred_type[FUNC_MAX_ARGS];
    bool        resolved_unknowns;
    
    //校验
    if (nargs > FUNC_MAX_ARGS)
        ereport(ERROR,
                (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
                 errmsg_plural("cannot pass more than %d argument to a function",
                               "cannot pass more than %d arguments to a function",
                               FUNC_MAX_ARGS,
                               FUNC_MAX_ARGS)));
    
    
    nunknowns = 0;
    for (i = 0; i < nargs; i++)
    {
        if (input_typeids[i] != UNKNOWNOID)
            input_base_typeids[i] = getBaseType(input_typeids[i]);//基本类型
        else
        {
            //unknown 类型
            
            input_base_typeids[i] = UNKNOWNOID;
            nunknowns++;
        }
    }
    
    
    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 &&
                current_typeids[i] == input_base_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;
        }
        
        //不会比最后一个选项更糟,所以也保留这个选项
        else if (nmatch == nbestMatch)
        {
            //放到链表中
            last_candidate->next = current_candidate;
            last_candidate = current_candidate;
            ncandidates++;
        }
        
        //否则,无需保留
    }
    if (last_candidate)         
        last_candidate->next = NULL;
    if (ncandidates == 1)//只有一个候选,返回
        return candidates;
    
    
    for (i = 0; i < nargs; i++) 
        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;
        }
        else if (nmatch == nbestMatch)
        {
            //保留跟最佳匹配一样的候选
            last_candidate->next = current_candidate;
            last_candidate = current_candidate;
            ncandidates++;
        }
    }
    if (last_candidate)         
        last_candidate->next = NULL;
    if (ncandidates == 1)
        return candidates;//
    
    if (nunknowns == 0)//失败
        return NULL;            
    
    
    resolved_unknowns = false;//是否已解决unknown类型标记
    for (i = 0; i < nargs; i++)//遍历参数
    {
        bool        have_conflict;//是否存在冲突标记
        if (input_base_typeids[i] != UNKNOWNOID)
            continue;//非unknown类型
        resolved_unknowns = true;   
        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,
                                        &current_category,
                                        &current_is_preferred);
            if (slot_category[i] == TYPCATEGORY_INVALID)
            {
                
                //第一个候选
                slot_category[i] = current_category;
                slot_has_preferred_type[i] = current_is_preferred;
            }
            else if (current_category == slot_category[i])
            {
                
                //同样的目录有更多的候选
                slot_has_preferred_type[i] |= current_is_preferred;
            }
            else
            {
                
                //目录冲突
                if (current_category == TYPCATEGORY_STRING)
                {
                    
                    //如可能,首选STRING
                    slot_category[i] = current_category;
                    slot_has_preferred_type[i] = current_is_preferred;
                }
                else
                {
                    
                    have_conflict = true;
                }
            }
        }
        if (have_conflict && slot_category[i] != TYPCATEGORY_STRING)
        {
            //存在冲突,并且目录不是STRING
            
            //无法解决冲突
            resolved_unknowns = false;
            break;
        }
    }
    if (resolved_unknowns)
    {
        //已解决了冲突
        
        ncandidates = 0;
        first_candidate = candidates;
        last_candidate = NULL;
        for (current_candidate = candidates;
             current_candidate != NULL;
             current_candidate = current_candidate->next)//再次遍历
        {
            bool        keepit = 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,
                                            &current_category,
                                            &current_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)
            {
                
                //保留该候选
                last_candidate = current_candidate;
                ncandidates++;
            }
            else
            {
                
                //
                if (last_candidate)
                    last_candidate->next = current_candidate->next;
                else
                    first_candidate = current_candidate->next;
            }
        }
        
        if (last_candidate)
        {
            candidates = first_candidate;
            
            last_candidate->next = NULL;
        }
        if (ncandidates == 1)
            return candidates;
    }
    
    
    if (nunknowns < nargs)
    {
        Oid         known_type = UNKNOWNOID;
        for (i = 0; i < nargs; i++)//找到基本类型,找不到则失败
        {
            if (input_base_typeids[i] == UNKNOWNOID)
                continue;
            if (known_type == UNKNOWNOID)   
                known_type = input_base_typeids[i];
            else if (known_type != input_base_typeids[i])
            {
                
                known_type = UNKNOWNOID;
                break;
            }
        }
        if (known_type != UNKNOWNOID)//找到了基本类型
        {
            
            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;  
                    last_candidate = current_candidate;
                }
            }
            if (ncandidates == 1)
            {
                
                //成功!
                last_candidate->next = NULL;
                return last_candidate;
            }
        }
    }
    //返回NULL
    return NULL;                
}                               

三、跟踪分析

测试脚本

create cast(integer as text) with inout as implicit;
select id||'X' from t_cast;

跟踪分析

Breakpoint 1, func_select_candidate (nargs=2, input_typeids=0x7fff5f3ac6c0, candidates=0x2daa6f0) at parse_func.c:1021
1021        if (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->next
Cannot access memory at address 0x0
(gdb) n
1042        nunknowns = 0;
(gdb) 
1043        for (i = 0; i < nargs; i++)
(gdb) 
1045            if (input_typeids[i] != UNKNOWNOID)
(gdb) 
1046                input_base_typeids[i] = getBaseType(input_typeids[i]);
(gdb) 
1043        for (i = 0; i < nargs; i++)
(gdb) p input_base_typeids[0]
$12 = 23
(gdb) n
1045            if (input_typeids[i] != UNKNOWNOID)
(gdb) 
1050                input_base_typeids[i] = UNKNOWNOID;
(gdb) p input_typeids[i]
$13 = 705
(gdb) p UNKNOWNOID
$14 = 705
(gdb) n
1051                nunknowns++;
(gdb) 
1043        for (i = 0; i < nargs; i++)
(gdb) 
1059        ncandidates = 0;
(gdb) 
1060        nbestMatch = 0;
(gdb) 
1061        last_candidate = NULL;
(gdb) 
1062        for (current_candidate = candidates;
(gdb) 
1066            current_typeids = current_candidate->args;
(gdb) 
1067            nmatch = 0;
(gdb) 
1068            for (i = 0; i < nargs; i++)
(gdb) 
1070                if (input_base_typeids[i] != UNKNOWNOID &&
(gdb) 
1071                    current_typeids[i] == input_base_typeids[i])
(gdb) p current_typeids[i]
$15 = 25
(gdb) p input_base_typeids[i]
$16 = 23
(gdb) n
1070                if (input_base_typeids[i] != UNKNOWNOID &&
(gdb) 
1068            for (i = 0; i < nargs; i++)
(gdb) 
1070                if (input_base_typeids[i] != UNKNOWNOID &&
(gdb) 
1068            for (i = 0; i < nargs; i++)
(gdb) 
1076            if ((nmatch > nbestMatch) || (last_candidate == NULL))
(gdb) 
1078                nbestMatch = nmatch;
(gdb) 
1079                candidates = current_candidate;
(gdb) 
1080                last_candidate = current_candidate;
(gdb) 
1081                ncandidates = 1;
(gdb) 
1064             current_candidate = current_candidate->next)
(gdb) 
1062        for (current_candidate = candidates;
(gdb) 
1066            current_typeids = current_candidate->args;
(gdb) 
1067            nmatch = 0;
(gdb) 
1068            for (i = 0; i < nargs; i++)
(gdb) 
1070                if (input_base_typeids[i] != UNKNOWNOID &&
(gdb) 
1071                    current_typeids[i] == input_base_typeids[i])
(gdb) 
1070                if (input_base_typeids[i] != UNKNOWNOID &&
(gdb) 
1068            for (i = 0; i < nargs; i++)
(gdb) 
1070                if (input_base_typeids[i] != UNKNOWNOID &&
(gdb) 
1068            for (i = 0; i < nargs; i++)
(gdb) 
1076            if ((nmatch > nbestMatch) || (last_candidate == NULL))
(gdb) 
1084            else if (nmatch == nbestMatch)
(gdb) 
1086                last_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) n
1087                last_candidate = current_candidate;
(gdb) 
1088                ncandidates++;
(gdb) 
1064             current_candidate = current_candidate->next)
(gdb) 
1062        for (current_candidate = candidates;
(gdb) 
1066            current_typeids = current_candidate->args;
(gdb) 
1067            nmatch = 0;
(gdb) 
1068            for (i = 0; i < nargs; i++)
(gdb) 
1070                if (input_base_typeids[i] != UNKNOWNOID &&
(gdb) 
1071                    current_typeids[i] == input_base_typeids[i])
(gdb) 
1070                if (input_base_typeids[i] != UNKNOWNOID &&
(gdb) 
1068            for (i = 0; i < nargs; i++)
(gdb) 
1070                if (input_base_typeids[i] != UNKNOWNOID &&
(gdb) 
1068            for (i = 0; i < nargs; i++)
(gdb) 
1076            if ((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) n
1084            else if (nmatch == nbestMatch)
(gdb) 
1086                last_candidate->next = current_candidate;
(gdb) 
1087                last_candidate = current_candidate;
(gdb) 
1088                ncandidates++;
(gdb) n
1064             current_candidate = current_candidate->next)
(gdb) 
1062        for (current_candidate = candidates;
(gdb) 
1066            current_typeids = current_candidate->args;
(gdb) 
1067            nmatch = 0;
(gdb) 
1068            for (i = 0; i < nargs; i++)
(gdb) 
1070                if (input_base_typeids[i] != UNKNOWNOID &&
(gdb) 
1071                    current_typeids[i] == input_base_typeids[i])
(gdb) 
1070                if (input_base_typeids[i] != UNKNOWNOID &&
(gdb) 
1068            for (i = 0; i < nargs; i++)
(gdb) 
1070                if (input_base_typeids[i] != UNKNOWNOID &&
(gdb) 
1068            for (i = 0; i < nargs; i++)
(gdb) 
1076            if ((nmatch > nbestMatch) || (last_candidate == NULL))
(gdb) 
1084            else if (nmatch == nbestMatch)
(gdb) 
1086                last_candidate->next = current_candidate;
(gdb) 
1087                last_candidate = current_candidate;
(gdb) 
1088                ncandidates++;
(gdb) 
1064             current_candidate = current_candidate->next)
(gdb) 
1062        for (current_candidate = candidates;
(gdb) 
1093        if (last_candidate)         
(gdb) 
1094            last_candidate->next = NULL;
(gdb) 
1096        if (ncandidates == 1)
(gdb) p *last_candidate
$20 = {next = 0x0, pathpos = 0, oid = 2780, nargs = 2, nvargs = 0, ndargs = 0, argnumbers = 0x0, args = 0x2daa838}
(gdb) n
1106        for (i = 0; i < nargs; i++) 
(gdb) 
1107            slot_category[i] = TypeCategory(input_base_typeids[i]);
(gdb) 
1106        for (i = 0; i < nargs; i++) 
(gdb) p slot_category[i] 
$21 = 78 'N'
(gdb) n
1107            slot_category[i] = TypeCategory(input_base_typeids[i]);
(gdb) 
1106        for (i = 0; i < nargs; i++) 
(gdb) p slot_category[i] 
$22 = 88 'X'
(gdb) n
1108        ncandidates = 0;
(gdb) 
1109        nbestMatch = 0;
(gdb) 
1110        last_candidate = NULL;
(gdb) 
1111        for (current_candidate = candidates;
(gdb) 
1115            current_typeids = current_candidate->args;
(gdb) 
1116            nmatch = 0;
(gdb) 
1117            for (i = 0; i < nargs; i++)
(gdb) 
1119                if (input_base_typeids[i] != UNKNOWNOID)
(gdb) 
1121                    if (current_typeids[i] == input_base_typeids[i] ||
(gdb) p current_typeids[i]
$23 = 25
(gdb) n
1122                        IsPreferredType(slot_category[i], current_typeids[i]))
(gdb) 
1121                    if (current_typeids[i] == input_base_typeids[i] ||
(gdb) 
1117            for (i = 0; i < nargs; i++)
(gdb) 
1119                if (input_base_typeids[i] != UNKNOWNOID)
(gdb) 
1117            for (i = 0; i < nargs; i++)
(gdb) 
1127            if ((nmatch > nbestMatch) || (last_candidate == NULL))
(gdb) 
1129                nbestMatch = nmatch;
(gdb) 
1130                candidates = current_candidate;
(gdb) 
1131                last_candidate = current_candidate;
(gdb) 
1132                ncandidates = 1;
(gdb) 
1113             current_candidate = current_candidate->next)
(gdb) 
1111        for (current_candidate = candidates;
(gdb) 
1115            current_typeids = current_candidate->args;
(gdb) 
1116            nmatch = 0;
(gdb) 
1117            for (i = 0; i < nargs; i++)
(gdb) 
1119                if (input_base_typeids[i] != UNKNOWNOID)
(gdb) 
1121                    if (current_typeids[i] == input_base_typeids[i] ||
(gdb) 
1122                        IsPreferredType(slot_category[i], current_typeids[i]))
(gdb) 
1121                    if (current_typeids[i] == input_base_typeids[i] ||
(gdb) 
1117            for (i = 0; i < nargs; i++)
(gdb) 
1119                if (input_base_typeids[i] != UNKNOWNOID)
(gdb) 
1117            for (i = 0; i < nargs; i++)
(gdb) 
1127            if ((nmatch > nbestMatch) || (last_candidate == NULL))
(gdb) 
1134            else if (nmatch == nbestMatch)
(gdb) 
1136                last_candidate->next = current_candidate;
(gdb) 
1137                last_candidate = current_candidate;
(gdb) 
1138                ncandidates++;
(gdb) 
1113             current_candidate = current_candidate->next)
(gdb) 
1111        for (current_candidate = candidates;
(gdb) 
1115            current_typeids = current_candidate->args;
(gdb) 
1116            nmatch = 0;
(gdb) 
1117            for (i = 0; i < nargs; i++)
(gdb) 
1119                if (input_base_typeids[i] != UNKNOWNOID)
(gdb) 
1121                    if (current_typeids[i] == input_base_typeids[i] ||
(gdb) 
1122                        IsPreferredType(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) n
1121                    if (current_typeids[i] == input_base_typeids[i] ||
(gdb) 
1117            for (i = 0; i < nargs; i++)
(gdb) 
1119                if (input_base_typeids[i] != UNKNOWNOID)
(gdb) 
1117            for (i = 0; i < nargs; i++)
(gdb) 
1127            if ((nmatch > nbestMatch) || (last_candidate == NULL))
(gdb) 
1134            else if (nmatch == nbestMatch)
(gdb) 
1136                last_candidate->next = current_candidate;
(gdb) 
1137                last_candidate = current_candidate;
(gdb) 
1138                ncandidates++;
(gdb) 
1113             current_candidate = current_candidate->next)
(gdb) 
1111        for (current_candidate = candidates;
(gdb) 
1115            current_typeids = current_candidate->args;
(gdb) 
1116            nmatch = 0;
(gdb) 
1117            for (i = 0; i < nargs; i++)
(gdb) 
1119                if (input_base_typeids[i] != UNKNOWNOID)
(gdb) 
1121                    if (current_typeids[i] == input_base_typeids[i] ||
(gdb) 
1122                        IsPreferredType(slot_category[i], current_typeids[i]))
(gdb) 
1121                    if (current_typeids[i] == input_base_typeids[i] ||
(gdb) 
1117            for (i = 0; i < nargs; i++)
(gdb) 
1119                if (input_base_typeids[i] != UNKNOWNOID)
(gdb) 
1117            for (i = 0; i < nargs; i++)
(gdb) 
1127            if ((nmatch > nbestMatch) || (last_candidate == NULL))
(gdb) 
1134            else if (nmatch == nbestMatch)
(gdb) 
1136                last_candidate->next = current_candidate;
(gdb) 
1137                last_candidate = current_candidate;
(gdb) 
1138                ncandidates++;
(gdb) 
1113             current_candidate = current_candidate->next)
(gdb) 
1111        for (current_candidate = candidates;
(gdb) 
1142        if (last_candidate)         
(gdb) 
1143            last_candidate->next = NULL;
(gdb) 
1145        if (ncandidates == 1)
(gdb) 
1154        if (nunknowns == 0)
(gdb) 
1176        resolved_unknowns = false;
(gdb) 
1177        for (i = 0; i < nargs; i++)
(gdb) 
1181            if (input_base_typeids[i] != UNKNOWNOID)
(gdb) 
1182                continue;
(gdb) 
1177        for (i = 0; i < nargs; i++)
(gdb) 
1181            if (input_base_typeids[i] != UNKNOWNOID)
(gdb) 
1183            resolved_unknowns = true;   
(gdb) 
1184            slot_category[i] = TYPCATEGORY_INVALID;
(gdb) 
1185            slot_has_preferred_type[i] = false;
(gdb) 
1186            have_conflict = false;
(gdb) 
1187            for (current_candidate = candidates;
(gdb) 
1191                current_typeids = current_candidate->args;
(gdb) 
1192                current_type = current_typeids[i];
(gdb) 
1193                get_type_category_preferred(current_type,
(gdb) 
1196                if (slot_category[i] == TYPCATEGORY_INVALID)
(gdb) p current_type
$25 = 25
(gdb) p current_category
$26 = 83 'S'
(gdb) p current_is_preferred
$27 = true
(gdb) p slot_category[i]
$28 = 0 '\000'
(gdb) n
1199                    slot_category[i] = current_category;
(gdb) 
1200                    slot_has_preferred_type[i] = current_is_preferred;
(gdb) 
1189                 current_candidate = current_candidate->next)
(gdb) p current_category
$29 = 83 'S'
(gdb) p current_is_preferred
$30 = true
(gdb) n
1187            for (current_candidate = candidates;
(gdb) 
1191                current_typeids = current_candidate->args;
(gdb) 
1192                current_type = current_typeids[i];
(gdb) 
1193                get_type_category_preferred(current_type,
(gdb) 
1196                if (slot_category[i] == TYPCATEGORY_INVALID)
(gdb) p current_category
$31 = 80 'P'
(gdb) p current_is_preferred
$32 = false
(gdb) n
1202                else if (current_category == slot_category[i])
(gdb) 
1210                    if (current_category == TYPCATEGORY_STRING)
(gdb) 
1221                        have_conflict = true;
(gdb) 
1189                 current_candidate = current_candidate->next)
(gdb) 
1187            for (current_candidate = candidates;
(gdb) 
1191                current_typeids = current_candidate->args;
(gdb) 
1192                current_type = current_typeids[i];
(gdb) 
1193                get_type_category_preferred(current_type,
(gdb) 
1196                if (slot_category[i] == TYPCATEGORY_INVALID)
(gdb) p current_type
$33 = 2277
(gdb) p current_is_preferred
$34 = false
(gdb) p current_category
$35 = 80 'P'
(gdb) n
1202                else if (current_category == slot_category[i])
(gdb) 
1210                    if (current_category == TYPCATEGORY_STRING)
(gdb) 
1221                        have_conflict = true;
(gdb) 
1189                 current_candidate = current_candidate->next)
(gdb) 
1187            for (current_candidate = candidates;
(gdb) 
1191                current_typeids = current_candidate->args;
(gdb) 
1192                current_type = current_typeids[i];
(gdb) 
1193                get_type_category_preferred(current_type,
(gdb) 
1196                if (slot_category[i] == TYPCATEGORY_INVALID)
(gdb) 
1202                else if (current_category == slot_category[i])
(gdb) 
1205                    slot_has_preferred_type[i] |= current_is_preferred;
(gdb) p current_category
$36 = 83 'S'
(gdb) n
1189                 current_candidate = current_candidate->next)
(gdb) 
1187            for (current_candidate = candidates;
(gdb) 
1225            if (have_conflict && slot_category[i] != TYPCATEGORY_STRING)
(gdb) 
1177        for (i = 0; i < nargs; i++)
(gdb) p resolved_unknowns
$37 = true
(gdb) n
1233        if (resolved_unknowns)
(gdb) 
1236            ncandidates = 0;
(gdb) 
1237            first_candidate = candidates;
(gdb) 
1238            last_candidate = NULL;
(gdb) 
1239            for (current_candidate = candidates;
(gdb) 
1243                bool        keepit = true;
(gdb) 
1245                current_typeids = current_candidate->args;
(gdb) 
1246                for (i = 0; i < nargs; i++)
(gdb) 
1248                    if (input_base_typeids[i] != UNKNOWNOID)
(gdb) 
1249                        continue;
(gdb) 
1246                for (i = 0; i < nargs; i++)
(gdb) 
1248                    if (input_base_typeids[i] != UNKNOWNOID)
(gdb) 
1250                    current_type = current_typeids[i];
(gdb) 
1251                    get_type_category_preferred(current_type,
(gdb) p current_type
$38 = 25
(gdb) n
1254                    if (current_category != slot_category[i])
(gdb) p current_category
$39 = 83 'S'
(gdb) p slot_category[i]
$40 = 83 'S'
(gdb) n
1259                    if (slot_has_preferred_type[i] && !current_is_preferred)
(gdb) 
1246                for (i = 0; i < nargs; i++)
(gdb) 
1265                if (keepit)
(gdb) 
1268                    last_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) n
1269                    ncandidates++;
(gdb) 
1241                 current_candidate = current_candidate->next)
(gdb) n
1239            for (current_candidate = candidates;
(gdb) 
1243                bool        keepit = true;
(gdb) 
1245                current_typeids = current_candidate->args;
(gdb) 
1246                for (i = 0; i < nargs; i++)
(gdb) 
1248                    if (input_base_typeids[i] != UNKNOWNOID)
(gdb) 
1249                        continue;
(gdb) 
1246                for (i = 0; i < nargs; i++)
(gdb) 
1248                    if (input_base_typeids[i] != UNKNOWNOID)
(gdb) 
1250                    current_type = current_typeids[i];
(gdb) 
1251                    get_type_category_preferred(current_type,
(gdb) 
1254                    if (current_category != slot_category[i])
(gdb) p current_type
$42 = 2776
(gdb) p current_category
$43 = 80 'P'
(gdb) n
1256                        keepit = false;
(gdb) 
1257                        break;
(gdb) 
1265                if (keepit)
(gdb) 
1274                    if (last_candidate)
(gdb) 
1275                        last_candidate->next = current_candidate->next;
(gdb) 
1241                 current_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) n
1239            for (current_candidate = candidates;
(gdb) 
1243                bool        keepit = true;
(gdb) 
1245                current_typeids = current_candidate->args;
(gdb) 
1246                for (i = 0; i < nargs; i++)
(gdb) 
1248                    if (input_base_typeids[i] != UNKNOWNOID)
(gdb) 
1249                        continue;
(gdb) 
1246                for (i = 0; i < nargs; i++)
(gdb) 
1248                    if (input_base_typeids[i] != UNKNOWNOID)
(gdb) 
1250                    current_type = current_typeids[i];
(gdb) 
1251                    get_type_category_preferred(current_type,
(gdb) p current_type
$45 = 2277
(gdb) p current_category
$46 = 80 'P'
(gdb) n
1254                    if (current_category != slot_category[i])
(gdb) 
1256                        keepit = false;
(gdb) 
1257                        break;
(gdb) 
1265                if (keepit)
(gdb) 
1274                    if (last_candidate)
(gdb) 
1275                        last_candidate->next = current_candidate->next;
(gdb) 
1241                 current_candidate = current_candidate->next)
(gdb) 
1239            for (current_candidate = candidates;
(gdb) 
1243                bool        keepit = true;
(gdb) 
1245                current_typeids = current_candidate->args;
(gdb) 
1246                for (i = 0; i < nargs; i++)
(gdb) 
1248                    if (input_base_typeids[i] != UNKNOWNOID)
(gdb) 
1249                        continue;
(gdb) 
1246                for (i = 0; i < nargs; i++)
(gdb) 
1248                    if (input_base_typeids[i] != UNKNOWNOID)
(gdb) 
1250                    current_type = current_typeids[i];
(gdb) 
1251                    get_type_category_preferred(current_type,
(gdb) 
1254                    if (current_category != slot_category[i])
(gdb) 
1259                    if (slot_has_preferred_type[i] && !current_is_preferred)
(gdb) p current_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) n
1246                for (i = 0; i < nargs; i++)
(gdb) 
1265                if (keepit)
(gdb) 
1268                    last_candidate = current_candidate;
(gdb) 
1269                    ncandidates++;
(gdb) 
1241                 current_candidate = current_candidate->next)
(gdb) 
1239            for (current_candidate = candidates;
(gdb) 
1282            if (last_candidate)
(gdb) 
1284                candidates = 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) n
1286                last_candidate->next = NULL;
(gdb) n
1289            if (ncandidates == 1)
(gdb) 
1303        if (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) n
1305            Oid         known_type = UNKNOWNOID;
(gdb) 
1307            for (i = 0; i < nargs; i++)
(gdb) 
1309                if (input_base_typeids[i] == UNKNOWNOID)
(gdb) 
1311                if (known_type == UNKNOWNOID)   
(gdb) 
1312                    known_type = input_base_typeids[i];
(gdb) 
1307            for (i = 0; i < nargs; i++)
(gdb) p known_type
$53 = 23
(gdb) n
1309                if (input_base_typeids[i] == UNKNOWNOID)
(gdb) 
1310                    continue;
(gdb) 
1307            for (i = 0; i < nargs; i++)
(gdb) 
1321            if (known_type != UNKNOWNOID)
(gdb) 
1324                for (i = 0; i < nargs; i++)
(gdb) 
1325                    input_base_typeids[i] = known_type;
(gdb) 
1324                for (i = 0; i < nargs; i++)
(gdb) p known_type
$54 = 23
(gdb) n
1325                    input_base_typeids[i] = known_type;
(gdb) 
1324                for (i = 0; i < nargs; i++)
(gdb) 
1326                ncandidates = 0;
(gdb) 
1327                last_candidate = NULL;
(gdb) 
1328                for (current_candidate = candidates;
(gdb) 
1332                    current_typeids = current_candidate->args;
(gdb) 
1333                    if (can_coerce_type(nargs, input_base_typeids, current_typeids,
(gdb) 
1336                        if (++ncandidates > 1)
(gdb) n
1338                        last_candidate = current_candidate;
(gdb) 
1330                     current_candidate = current_candidate->next)
(gdb) 
1328                for (current_candidate = candidates;
(gdb) 
1332                    current_typeids = current_candidate->args;
(gdb) 
1333                    if (can_coerce_type(nargs, input_base_typeids, current_typeids,
(gdb) 
1336                        if (++ncandidates > 1)
(gdb) 
1337                            break;  
(gdb) 
1341                if (ncandidates == 1)
(gdb) 
1350        return NULL;                
(gdb)

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

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-数据库
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯