Postgresql函数解析规则
2016-10-25 17:41:22 0 举报
Postgresql函数解析规则
作者其他创作
大纲/内容
二重循环处理每一个函数候选集,规则:1. 一一对比函数候选集参数和输入参数类型的OID,相等或者候选集函数的参数是对应的输入参数类型的存储类别的首选类型,则匹配的权重nmatchs++,否则比较下一个参数类型,直到函数的所有参数类型都比较完毕,然后按此继续处理下一个函数候选集。2. 最后选择最匹配(nmatchs值最大)的函数候选集列表进行接下来处理。
对应特殊调用的标志变量置为true
选择最匹配的唯一候选集,否则返回NULL
func_match_argtypes()
标记需要搜索search_path
根据“函数名”和“参数个数匹配候选集”
Y
只按函数名搜索syscache,获取候选集
将原始候选集加入到新候选集列表
transformFuncCall()
resolved_unknowns == true即,说明经过上面步骤已为所有unknown参数位置确定了存储类别
N
候选集列表长度 = 1找到了唯一候选集函数?
返回新函数候选集长度
func_select_candidate()
“特殊调用”是否匹配候选集函数(略)1. 输入参数个数大于候选集参数个数,考虑可变数组参数2. 输入参数数量小于候选集参数个数,考虑有默认值的函数
移除不能隐式转换的候选集
位置调用方式:“特殊调用”判断和正常调用情况
结束
函数调用方式是否是参数名或混合表示法调用的(named- or mixed-notation call)
循环处理多个原始的候选集,判断函数候选集参数类型与输入参数类型是否可以进行隐式转换,如果可以隐式转换,则把原始候选集加入到新的候选集列表,否则丢弃,最终函数返回经过处理后的新候选集个数
比较函数候选集的模式是否位于search_path路径中?
获取模式OID
二重循环检查输入参数的每一个unknown参数位置与候选集参数对应位置比较,是否可以为unknown位置的参数确定一个类型的“存储列别”,规则如下:1. 如果任何一个候选集对应unknown参数位置的数据类型的存储类别是“S”,则此位置的unknown参数类型的存储类别为“S”。2. 如果对应位置参数没有存储类别是“S”的候选集,但所有候选集在此位置的参数的存储类别是相同的,则此位置的unknown参数类型的存储类别为这个相同的存储类别。3. 如果有任何一个候选集与其他候选集在此位置的参数的存储类别不相同并且不是“S”,我们就结束全部循环,并标记此步解决冲突的规则失败(resolved_unknowns == false),保留之前的候选集列表,尝试其他解决冲突的办法。注意:如果这步我们能成功的为所有unknown类型的位置决定一个类型的存储类别,也要记录候选集在此存储类别中是否有首选类型存在,记录在下面两个数组中:slot_category[i]slot_has_preferred_type[i]
Y(named- or mixed-notation call)
(3)
函数调用:(1) named- or mixed-notation call(2) positional notation call例子:
特殊调用
continue判断下一个候选集函数
continue进行下一次循环
原始候选集列表遍历结束
比较函数候选集的模式是否等于指定模式的OID?
则判断候选集函数的参数个数是否等于当前函数调用的参数个数?
非特殊调用
FuncnameGetCandidates()
二重循环处理每一个函数候选集,规则:1. 一一对比函数候选集参数和输入参数类型的OID,相等,则匹配的权重nmatchs++,否则比较下一个参数类型,直到函数的所有参数类型都比较完毕,然后按此继续处理下一个函数候选集。2. 最后选择最匹配(nmatchs值最大)的函数候选集列表进行接下来处理。
成功
nunknowns == 0
与之前的循环不同是判断了参数类别和首选类型
有模式修饰?
是否可以进行隐式转换?
失败:模式不存在或没有权限,返回NULL
(1)
返回这个唯一的候选集
进行下一次循环,直到所有候选集都匹配完毕,返回最终的函数候选集结果
(2)
函数名有模式修饰?
循环处理获取的函数候选集
ncandidates == 1
从候选集列表中移除不符合条件的候选集:1. 候选集与unknown位置的存储类别不同,即 current_category != slot_category[i] 。2. 如果存在首选类型的候选集,则移除所有此unknown位置上的非首选的候选集
func_get_detail()
ncandidates == 1最后剩下唯一候选集
把这个候选集函数插入到函数候选集结果列表中
ParseFuncOrColumn()
还没有找到一个唯一的候选集,则进行最后的尝试:1.如果除了unknown参数外,其他参数类型相同,则我们假设unknown也是这个类型的参数。然后循环判断所有参数是否能与候选集列表中函数的参数进行隐式转换,若能所有参数都可以隐式转换,则获取这个候选集,并记录获取的候选集数量ncandidates++
循环获取输入参数类型(包括unknown)的存储类别
特殊调用包括:(1)参数名或混合(参数名和位置)调用(2)含有参数默认值的函数调用(3)含有可变数组(variadic)参数的函数调用,可变函数
通过函数名和参数个数返回可能匹配的函数候选集列表(FuncnameGetCandidates)
N(positional notation call)
返回NULL
1.检查函数调用时指定的参数名是否与函数定义的参数名匹配。2.“特殊”调用处理,本身就是一种特殊调用
输入参数类型如果是域类型,获取其基本数据类型,并记录输入参数中unknown类型的数量(nunknowns)。
0 条评论
下一页