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
失败学数据库
数据库密码的文本格式
软件开发中心面试结果
集成电路软件开发免税
电脑蓝牙服务器
西安学习网络安全
建立网络安全监测预警
公司服务器文件不能复制
苹果云服务器如何关闭
电子商务网站服务器
台州中宏网络技术有限公司电话
南邮网络安全期末试卷
深圳大楼震动 服务器
南北软件开发合同样本
宜章学电脑软件开发工资多少
江苏省计算机网络技术专转本
服务器可以建多个web站吗
数据库中的关键字和索引
哈尔滨魔豆网络技术有限公司
360网络技术版
教务系统数据库目的
云服务器上网
服务器 处理速度
教育软件开发怎么选择
明朝网络安全企业50强
四川广电网络安全设置
数据库的安全保护测试题
开启数据库root远程访问权限