广告
返回顶部
首页 > 资讯 > 数据库 >PostgreSQL隐式类型转换中选择操作符的实现函数是什么
  • 499
分享到

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

2024-04-02 19:04:59 499人浏览 泡泡鱼
摘要

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

这篇文章主要讲解了“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隐式类型转换中选择操作符的实现函数是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

您可能感兴趣的文档:

--结束END--

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

本文链接: https://www.lsjlt.com/news/63801.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • PostgreSQL隐式类型转换中选择操作符的实现函数是什么
    这篇文章主要讲解了“PostgreSQL隐式类型转换中选择操作符的实现函数是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“PostgreSQL隐式类型转...
    99+
    2022-10-18
  • PostgreSQL隐式类型转换中使用哪些操作符实现函数
    这篇文章主要讲解了“PostgreSQL隐式类型转换中使用哪些操作符实现函数”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“PostgreSQL隐式类型转换中...
    99+
    2022-10-18
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作