千家信息网

PostgreSQL隐式类型转换中使用哪些操作符实现函数

发表于:2025-01-23 作者:千家信息网编辑
千家信息网最后更新 2025年01月23日,这篇文章主要讲解了"PostgreSQL隐式类型转换中使用哪些操作符实现函数",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"PostgreSQL隐式类型
千家信息网最后更新 2025年01月23日PostgreSQL隐式类型转换中使用哪些操作符实现函数

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

一、数据结构

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

/* *  This structure holds a list of possible functions or operators *  found by namespace lookup.  Each function/operator is identified *  by OID and by argument types; the list must be pruned by type *  resolution rules that are embodied in the parser, not here. *  See FuncnameGetCandidates's comments for more info. *  该结构体存储检索得到的所有可能选中的函数或操作符链表. *  每一个函数/操作符通过OID和参数类型唯一确定, *  通过集成到分析器中的type resolution rules来确定裁剪该链表(但不是在这里实现) *  详细可参考FuncnameGetCandidates函数. */typedef struct _FuncCandidateList{    struct _FuncCandidateList *next;    //用于namespace检索内部使用    int         pathpos;        /* for internal use of namespace lookup */    //OID    Oid         oid;            /* the function or operator's OID */    //参数个数     int         nargs;          /* number of arg types returned */    //variadic array的参数个数    int         nvargs;         /* number of args to become variadic array */    //默认参数个数    int         ndargs;         /* number of defaulted args */    //参数位置索引    int        *argnumbers;     /* args' positional indexes, if named call */    //参数类型    Oid         args[FLEXIBLE_ARRAY_MEMBER];    /* arg types */}          *FuncCandidateList;

二、源码解读

func_match_argtypes
给定候选函数列表(正确的函数名称/参数个数匹配)和输入数据类型OIDs数组,生成实际可匹配输入数据类型(完全匹配或可转换)的候选函数链表,然后符合条件的候选函数个数.

/* func_match_argtypes() * * Given a list of candidate functions (having the right name and number * of arguments) and an array of input datatype OIDs, produce a shortlist of * those candidates that actually accept the input datatypes (either exactly * or by coercion), and return the number of such candidates. * 给定候选函数列表(正确的函数名称/参数个数匹配)和输入数据类型OIDs数组, * 生成实际可匹配输入数据类型(完全匹配或可转换)的候选函数链表,然后符合条件的候选函数个数 * * Note that can_coerce_type will assume that UNKNOWN inputs are coercible to * anything, so candidates will not be eliminated on that basis. * can_coerce_type函数假定UNKNOWN输入可转换为任意类型. * * NB: okay to modify input list structure, as long as we find at least * one match.  If no match at all, the list must remain unmodified. * 注意:如果只是找到一个匹配的候选函数,修改输入链表结构是OK的.如无匹配,则链表保持不变. */intfunc_match_argtypes(int nargs,                    Oid *input_typeids,                    FuncCandidateList raw_candidates,                    FuncCandidateList *candidates)  /* return value */{    FuncCandidateList current_candidate;//当前候选    FuncCandidateList next_candidate;//下一候选    int         ncandidates = 0;    *candidates = NULL;    for (current_candidate = raw_candidates;         current_candidate != NULL;         current_candidate = next_candidate)//遍历候选函数    {        next_candidate = current_candidate->next;        if (can_coerce_type(nargs, input_typeids, current_candidate->args,                            COERCION_IMPLICIT))//可匹配输入数据类型(完全匹配或可转换)        {            current_candidate->next = *candidates;            *candidates = current_candidate;            ncandidates++;        }    }    return ncandidates;}                               /* func_match_argtypes() */

在pg_operator中,输入参数类型与operator的参数类型匹配或可转换,可进入候选函数链表.

三、跟踪分析

测试脚本

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

跟踪分析

(gdb) cContinuing.Breakpoint 2, oper_select_candidate (nargs=2, input_typeids=0x7ffeb9cca190, candidates=0x13db8a0, operOid=0x7ffeb9cca22c)    at parse_oper.c:330330     ncandidates = func_match_argtypes(nargs, input_typeids,(gdb) p *candidates$1 = {next = 0x13db870, pathpos = 0, oid = 3284, nargs = 2, nvargs = 0, ndargs = 0, argnumbers = 0x0, args = 0x13db8c8}(gdb) p *candidates->next$2 = {next = 0x13db840, pathpos = 0, oid = 3681, nargs = 2, nvargs = 0, ndargs = 0, argnumbers = 0x0, args = 0x13db898}(gdb) p *candidates->next->next$3 = {next = 0x13db810, pathpos = 0, oid = 3633, nargs = 2, nvargs = 0, ndargs = 0, argnumbers = 0x0, args = 0x13db868}(gdb) p *candidates->next->next->next$4 = {next = 0x13db7e0, pathpos = 0, oid = 2780, nargs = 2, nvargs = 0, ndargs = 0, argnumbers = 0x0, args = 0x13db838}(gdb) p *candidates->next->next->next->next$5 = {next = 0x13db7b0, pathpos = 0, oid = 374, nargs = 2, nvargs = 0, ndargs = 0, argnumbers = 0x0, args = 0x13db808}(gdb) p *candidates->next->next->next->next->next$6 = {next = 0x13db780, pathpos = 0, oid = 349, nargs = 2, nvargs = 0, ndargs = 0, argnumbers = 0x0, args = 0x13db7d8}(gdb) p *candidates->next->next->next->next->next->next$7 = {next = 0x13db750, pathpos = 0, oid = 375, nargs = 2, nvargs = 0, ndargs = 0, argnumbers = 0x0, args = 0x13db7a8}(gdb) p *candidates->next->next->next->next->next->next->next$8 = {next = 0x13db720, pathpos = 0, oid = 1797, nargs = 2, nvargs = 0, ndargs = 0, argnumbers = 0x0, args = 0x13db778}(gdb) p *candidates->next->next->next->next->next->next->next->next$9 = {next = 0x13db6f0, pathpos = 0, oid = 2779, nargs = 2, nvargs = 0, ndargs = 0, argnumbers = 0x0, args = 0x13db748}(gdb) p *candidates->next->next->next->next->next->next->next->next->next$10 = {next = 0x13db6c0, pathpos = 0, oid = 654, nargs = 2, nvargs = 0, ndargs = 0, argnumbers = 0x0, args = 0x13db718}(gdb) p *candidates->next->next->next->next->next->next->next->next->next->next$11 = {next = 0x0, pathpos = 0, oid = 2018, nargs = 2, nvargs = 0, ndargs = 0, argnumbers = 0x0, args = 0x13db6e8}(gdb) p *candidates->next->next->next->next->next->next->next->next->next->next->nextCannot access memory at address 0x0(gdb) n334     if (ncandidates == 0)(gdb) 339     if (ncandidates == 1)(gdb) 349     candidates = func_select_candidate(nargs, input_typeids, candidates);(gdb) p ncandidates$12 = 2(gdb) p *candidates$13 = {next = 0x13db810, pathpos = 0, oid = 374, nargs = 2, nvargs = 0, ndargs = 0, argnumbers = 0x0, args = 0x13db808}(gdb) p *candidates->next$14 = {next = 0x0, pathpos = 0, oid = 2780, nargs = 2, nvargs = 0, ndargs = 0, argnumbers = 0x0, args = 0x13db838}(gdb) p *candidates->next->nextCannot access memory at address 0x0(gdb)

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

函数 类型 参数 输入 操作符 个数 数据 可转换 结构 分析 学习 检索 内容 名称 实际 数组 条件 存储 生成 跟踪 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 c语言 开发数据库 陕西定制化服务器厂家推荐 数据库事务的四个基本性质 linux数据库加外网用户 计算机网络技术工程系统 室内实时定位导航软件开发 湖北银行微服务架构数据库 微信艾特谁属于网络技术么 大兴区智能网络技术诚信服务 网络安全除了前端还有啥 mvc 上传保存到数据库 条码打印软件数据库设定 中地数码招聘数据库开发 金蝶去数据库删凭证 戴尔服务器清理垃圾 数据库如何计算关键字个数 和工作站有哪些品牌服务器 金融科技和互联网 服务器关机先关管理还是先关储存 数据库中一个字段同表名相同 石家庄招聘的软件开发 同城网络技术公司 计算机三级考试题网络技术 水管所网络安全排查情况汇报 挖矿软件开发公司 网络安全提示信息泄露 服务器总是自动修改密码 朝阳区威力软件开发经历 神经元网络技术常用于物联网 蔚来软件开发中国副总裁
0