PostgreSQL如何解析表达式.
发表于:2024-11-19 作者:千家信息网编辑
千家信息网最后更新 2024年11月19日,本篇内容介绍了"PostgreSQL如何解析表达式."的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!S
千家信息网最后更新 2024年11月19日PostgreSQL如何解析表达式.
本篇内容介绍了"PostgreSQL如何解析表达式."的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
SQL样例脚本.
testdb=# select 1+id,c2 from t_expr where id < 3;
一、数据结构
FmgrInfo
在函数通过fmgr调用前,该结构体持有系统目录(字典)信息,用于检索相关信息.
如果相同的函数将被调用多次,检索只需要完成一次即可,该结构体会缓存多次使用.
/* * This struct holds the system-catalog information that must be looked up * before a function can be called through fmgr. If the same function is * to be called multiple times, the lookup need be done only once and the * info struct saved for re-use. * 在函数通过fmgr调用前,该结构体持有系统目录(字典)信息,用于检索相关信息. * 如果相同的函数将被调用多次,检索只需要完成一次即可,该结构体会缓存多次使用. * * Note that fn_expr really is parse-time-determined information about the * arguments, rather than about the function itself. But it's convenient * to store it here rather than in FunctionCallInfoData, where it might more * logically belong. * 注意,fn_expr实际上是关于参数的解析时确定的信息,而不是函数自身. * 但fn_expr在这里存储而不是FunctionCallInfoData中存储,因为从逻辑上来说,它就应该属于那. * * fn_extra is available for use by the called function; all other fields * should be treated as read-only after the struct is created. * fn_extra可用于被调用函数的使用;所有其他字段应该在结构体创建后被处理为只读. */typedef struct FmgrInfo{ //指向函数或者将被调用的处理器 PGFunction fn_addr; /* pointer to function or handler to be called */ //函数的oid Oid fn_oid; /* OID of function (NOT of handler, if any) */ //输入参数的个数,0..FUNC_MAX_ARGS short fn_nargs; /* number of input args (0..FUNC_MAX_ARGS) */ //函数是否严格(strict),输入NULL,输出NULL bool fn_strict; /* function is "strict" (NULL in => NULL out) */ //函数是否返回集合 bool fn_retset; /* function returns a set */ //如track_functions > this,则收集统计信息 unsigned char fn_stats; /* collect stats if track_functions > this */ //handler使用的额外空间 void *fn_extra; /* extra space for use by handler */ //存储fn_extra的内存上下文 MemoryContext fn_mcxt; /* memory context to store fn_extra in */ //表达式解析树,或者为NULL fmNodePtr fn_expr; /* expression parse tree for call, or NULL */} FmgrInfo;typedef struct Node *fmNodePtr;
FunctionCallInfoData
该结构体存储了实际传递给fmgr-called函数的参数
/* * This struct is the data actually passed to an fmgr-called function. * 该结构体存储了实际传递给fmgr-called函数的参数 * * The called function is expected to set isnull, and possibly resultinfo or * fields in whatever resultinfo points to. It should not change any other * fields. (In particular, scribbling on the argument arrays is a bad idea, * since some callers assume they can re-call with the same arguments.) * 被调用的函数期望设置isnull以及可能的resultinfo或者resultinfo指向的域字段. * 不应该改变其他字段. * (特别的,在参数数组上乱写是个坏主意,因为某些调用者假定它们可以使用相同的参数重复调用) */typedef struct FunctionCallInfoData{ //指向该调用的检索信息 FmgrInfo *flinfo; /* ptr to lookup info used for this call */ //调用上下文 fmNodePtr context; /* pass info about context of call */ //传递或返回关于结果的特别信息 fmNodePtr resultinfo; /* pass or return extra info about result */ //函数的collation Oid fncollation; /* collation for function to use */#define FIELDNO_FUNCTIONCALLINFODATA_ISNULL 4 //如结果为NULL,则必须设置为T bool isnull; /* function must set true if result is NULL */ //实际传递的参数个数 short nargs; /* # arguments actually passed */#define FIELDNO_FUNCTIONCALLINFODATA_ARG 6 //传递给函数的参数 Datum arg[FUNC_MAX_ARGS]; /* Arguments passed to function */#define FIELDNO_FUNCTIONCALLINFODATA_ARGNULL 7 //如arg[i]为NULL,则对应的值为T bool argnull[FUNC_MAX_ARGS]; /* T if arg[i] is actually NULL */} FunctionCallInfoData;/* * All functions that can be called directly by fmgr must have this signature. * (Other functions can be called by using a handler that does have this * signature.) * 所有函数可以通过fmgr直接调用,但必须持有签名. * (其他函数可通过使用handler的方式调用,也有此签名) */typedef struct FunctionCallInfoData *FunctionCallInfo;
二、源码解读
ExecInterpExpr
ExecInterpExpr中与表达式求值相关的代码片段如下:
EEO_CASE(EEOP_FUNCEXPR) { FunctionCallInfo fcinfo = op->d.func.fcinfo_data; Datum d; fcinfo->isnull = false; d = op->d.func.fn_addr(fcinfo); *op->resvalue = d; *op->resnull = fcinfo->isnull; EEO_NEXT(); }
如为函数表达式,则从ExecInitFunc初始化的步骤信息中获取统一的调用参数fcinfo,然后通过函数指针(用于封装)调用实际的函数进行表达式求值.通过统一的参数,统一的返回值,做到了实现的统一,体现了面向对象OO中多态的思想,这再次说明了OO是思想,用过程性语言一样可以实现.
int4pl
SQL样例脚本相应的实现函数是int4pl,其实现代码如下:
Datumint4pl(PG_FUNCTION_ARGS){ int32 arg1 = PG_GETARG_INT32(0); int32 arg2 = PG_GETARG_INT32(1); int32 result; if (unlikely(pg_add_s32_overflow(arg1, arg2, &result))) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); PG_RETURN_INT32(result);}/* * If a + b overflows, return true, otherwise store the result of a + b into * *result. The content of *result is implementation defined in case of * overflow. */static inline boolpg_add_s32_overflow(int32 a, int32 b, int32 *result){#if defined(HAVE__BUILTIN_OP_OVERFLOW) return __builtin_add_overflow(a, b, result);#else int64 res = (int64) a + (int64) b; if (res > PG_INT32_MAX || res < PG_INT32_MIN) { *result = 0x5EED; /* to avoid spurious warnings */ return true; } *result = (int32) res; return false;#endif}
函数实现相对比较简单,两个数简单相加,如溢出则返回T,否则返回F.
"PostgreSQL如何解析表达式."的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!
函数
参数
信息
结构
表达式
实际
存储
检索
统一
相同
字段
指向
上下
上下文
个数
代码
内容
字典
思想
更多
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
深圳市偶地网络技术有限公司
河南笑吧网络技术有限公司
腾讯云服务器内网ip访问
数据库文件多久备份一次好
为什么要软件定义网络技术
数据库可以不使用终端吗
数据库ctid
赣州市网络安全知识线上竞答
报考北警网络安全与执法专业
软件开发简介ppt
电商页面商品数据库
多层次数据库是什么
怎么设置共享流量数据库
取表1中相同单位的数据库
数据库基础与实践技术第八章
多选题网络安全
app软件开发课题报告书
深度防护服务器
免费ssl服务器证书
现在网络安全工程师证考什么
北京上市软件开发公司
大庆市网络安全方面
武汉网络安全监察举报电话
ros vpn服务器
数据库打印时文字无法显示
盖世汽车网络技术有限公司
淮安智能仓库管理软件开发
北仑ios软件开发项目
苏州机械软件开发哪家好
曹忠平 网络安全