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