PostgreSQL查询引擎——General Expressions Grammar之restricted expression
General expressions语法规则定义在src/backend/parser/gram.y文件中,其是表达式语法的核心。有两种表达式类型:a_expr是不受限制的类型,b_expr是必须在某些地方使用的子集,以避免移位/减少冲突。例如,我们不能将BETWEEN作为BETWEEN a_expr AND a_exp,因为AND的使用与AND作为布尔运算符冲突。因此,b_expr在BETWEEN中使用,我们从b_expr中删除布尔关键字。请注意,( a_expr )是b_expr,因此始终可以使用无限制表达式,方法是用括号将其括起来。c_expr是a_expr和b_expr共同的所有乘积;它被分解出来只是为了消除冗余编码。注意涉及多个terminal token的产出productions。默认情况下,bison将为此类productions分配其最后一个terminal的优先级,但在几乎所有情况下,您都希望它是第一个terminal的优先权;否则你不会得到你期望的行为!因此,我们可以自由使用%prec注释来设置优先级。

b_expr代表Restricted expressions,它是复杂表达式a_expr的子集,AND, NOT, IS, and IN是a_expr的关键字,这些关键字在b_expr使用会存在歧义。b_expr is a subset of the complete expression syntax defined by a_expr. Presently, AND, NOT, IS, and IN are the a_expr keywords that would cause trouble in the places where b_expr is used. For simplicity, we just eliminate all the boolean-keyword-operator productions from b_expr.
b_expr: c_expr{ $$ = $1; }| b_expr TYPECAST Typename{ $$ = makeTypeCast($1, $3, @2); }| '+' b_expr %prec UMINUS{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", NULL, $2, @1); }| '-' b_expr %prec UMINUS{ $$ = doNegate($2, @1); }| b_expr '+' b_expr{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", $1, $3, @2); }| b_expr '-' b_expr{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "-", $1, $3, @2); }| b_expr '*' b_expr{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "*", $1, $3, @2); }| b_expr '/' b_expr{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "/", $1, $3, @2); }| b_expr '%' b_expr{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "%", $1, $3, @2); }| b_expr '^' b_expr{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "^", $1, $3, @2); }| b_expr '<' b_expr{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<", $1, $3, @2); }| b_expr '>' b_expr{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, ">", $1, $3, @2); }| b_expr '=' b_expr{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "=", $1, $3, @2); }| b_expr LESS_EQUALS b_expr{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<=", $1, $3, @2); }| b_expr GREATER_EQUALS b_expr{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, ">=", $1, $3, @2); }| b_expr NOT_EQUALS b_expr{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<>", $1, $3, @2); }| b_expr qual_Op b_expr %prec Op{ $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3, @2); }| qual_Op b_expr %prec Op{ $$ = (Node *) makeA_Expr(AEXPR_OP, $1, NULL, $2, @1); }| b_expr qual_Op %prec POSTFIXOP{ $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, NULL, @2); }| b_expr IS DISTINCT FROM b_expr %prec IS{ $$ = (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", $1, $5, @2); }| b_expr IS NOT DISTINCT FROM b_expr %prec IS{ $$ = (Node *) makeSimpleA_Expr(AEXPR_NOT_DISTINCT, "=", $1, $6, @2); }| b_expr IS OF '(' type_list ')' %prec IS{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "=", $1, (Node *) $5, @2); }| b_expr IS NOT OF '(' type_list ')' %prec IS{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "<>", $1, (Node *) $6, @2); }| b_expr IS DOCUMENT_P %prec IS{ $$ = makeXmlExpr(IS_DOCUMENT, NULL, NIL, list_make1($1), @2); }| b_expr IS NOT DOCUMENT_P %prec IS{ $$ = makeNotExpr(makeXmlExpr(IS_DOCUMENT, NULL, NIL, list_make1($1), @2), @2); }
表达式强转

b_expr TYPECAST Typename是表达式强转的规则,其中主要关注SimpleTypename所代表的规则。除了GenericType之外的规则和PostgreSQL查询引擎——General Expressions Grammar之AexprConst中介绍的常量类型强转类似,这里仅仅关注GenericType。
SimpleTypename:GenericType { $$ = $1; }| Numeric { $$ = $1; }| Bit { $$ = $1; }| Character { $$ = $1; }| ConstDatetime { $$ = $1; }| ConstInterval opt_interval{ $$ = $1; $$->typmods = $2; }| ConstInterval '(' Iconst ')'{ $$ = $1; $$->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1), makeIntConst($3, @3)); };
GenericType涵盖所有没有标准规定的特殊语法的类型名称,包括限定名称。我们还允许类型修饰符。为了避免对函数调用的解析冲突,这里必须将修饰符显示为expr_list,但解析分析只接受它们的常量。GenericType covers all type names that don’t have special syntax mandated by the standard, including qualified names. We also allow type modifiers. To avoid parsing conflicts against function invocations, the modifiers have to be shown as expr_list here, but parse analysis will only accept constants for them.
GenericType:type_function_name opt_type_modifiers{ $$ = makeTypeName($1); $$->typmods = $2; $$->location = @1; }| type_function_name attrs opt_type_modifiers{ $$ = makeTypeNameFromNameList(lcons(makeString($1), $2)); $$->typmods = $3; $$->location = @1; }
opt_type_modifiers: '(' expr_list ')' { $$ = $2; }| /* EMPTY */ { $$ = NIL; }
表达式强转的规则不同之处在于opt_array_bounds和ARRAY对于arrayBounds成员取值的影响,以及使用SETOF需要将setof成员设置为true。
Typename: SimpleTypename opt_array_bounds{ $$ = $1; $$->arrayBounds = $2; }| SETOF SimpleTypename opt_array_bounds{ $$ = $2; $$->arrayBounds = $3; $$->setof = true; }/* SQL standard syntax, currently only one-dimensional */| SimpleTypename ARRAY '[' Iconst ']'{ $$ = $1; $$->arrayBounds = list_make1(makeInteger($4)); }| SETOF SimpleTypename ARRAY '[' Iconst ']'{ $$ = $2; $$->arrayBounds = list_make1(makeInteger($5)); $$->setof = true; }| SimpleTypename ARRAY{ $$ = $1; $$->arrayBounds = list_make1(makeInteger(-1)); }| SETOF SimpleTypename ARRAY{ $$ = $2; $$->arrayBounds = list_make1(makeInteger(-1)); $$->setof = true; }
opt_array_bounds:opt_array_bounds '[' ']'{ $$ = lappend($1, makeInteger(-1)); }| opt_array_bounds '[' Iconst ']'{ $$ = lappend($1, makeInteger($3)); }| /*EMPTY*/{ $$ = NIL; }
运算符

| '+' b_expr %prec UMINUS{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", NULL, $2, @1); }| '-' b_expr %prec UMINUS{ $$ = doNegate($2, @1); }| b_expr '+' b_expr{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", $1, $3, @2); }| b_expr '-' b_expr{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "-", $1, $3, @2); }| b_expr '*' b_expr{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "*", $1, $3, @2); }| b_expr '/' b_expr{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "/", $1, $3, @2); }| b_expr '%' b_expr{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "%", $1, $3, @2); }| b_expr '^' b_expr{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "^", $1, $3, @2); }| b_expr '<' b_expr{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<", $1, $3, @2); }| b_expr '>' b_expr{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, ">", $1, $3, @2); }| b_expr '=' b_expr{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "=", $1, $3, @2); }| b_expr LESS_EQUALS b_expr{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<=", $1, $3, @2); }| b_expr GREATER_EQUALS b_expr{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, ">=", $1, $3, @2); }| b_expr NOT_EQUALS b_expr{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<>", $1, $3, @2); }| b_expr qual_Op b_expr %prec Op{ $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3, @2); }| qual_Op b_expr %prec Op{ $$ = (Node *) makeA_Expr(AEXPR_OP, $1, NULL, $2, @1); }| b_expr qual_Op %prec POSTFIXOP{ $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, NULL, @2); }| b_expr IS DISTINCT FROM b_expr %prec IS{ $$ = (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", $1, $5, @2); }| b_expr IS NOT DISTINCT FROM b_expr %prec IS{ $$ = (Node *) makeSimpleA_Expr(AEXPR_NOT_DISTINCT, "=", $1, $6, @2); }| b_expr IS OF '(' type_list ')' %prec IS{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "=", $1, (Node *) $5, @2); }| b_expr IS NOT OF '(' type_list ')' %prec IS{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "<>", $1, (Node *) $6, @2); }| b_expr IS DOCUMENT_P %prec IS{ $$ = makeXmlExpr(IS_DOCUMENT, NULL, NIL, list_make1($1), @2); }| b_expr IS NOT DOCUMENT_P %prec IS{ $$ = makeNotExpr(makeXmlExpr(IS_DOCUMENT, NULL, NIL, list_make1($1), @2), @2); }
https://www.developerastrid.com/sql/sql-predicates/
相关文章:
PostgreSQL查询引擎——General Expressions Grammar之restricted expression
General expressions语法规则定义在src/backend/parser/gram.y文件中,其是表达式语法的核心。有两种表达式类型:a_expr是不受限制的类型,b_expr是必须在某些地方使用的子集,以避免移位/减少冲突。例如,我们不能将BETWE…...
从某种程度上来看,产业互联网是一次对于互联网的弥补和修正
如果对当下我们正在经历的这样一个时代进行一次定义的话,我更加愿意将其划归到产业互联网的范畴里。可能有人会说,这与产业互联网并无联系,因为从本质上来看,当下我们所经历的这样一个时代,其实是与互联网并没有太多联…...
【C#Unity题】1.委托和事件在使用上的区别是什么?2.C#中 == 和 Equals 的区别是什么?
1.委托和事件在使用上的区别是什么? 委托和事件是C#中的重要概念,通俗来讲,委托是一个可以指向特定方法的指针,可以将委托分配给不同的脚本,使它们能够完成不同的任务。而事件则是一种使用委托实现的通知机制ÿ…...
FFmpeg5.0源码阅读——内存池AVBufferPool
摘要:FFmpeg中大多数数据存储比如AVFrame,AVPacket都是通过AVBufferRef管理的,而承载数据的结构为AVBuffer。本文主要通过FFmpeg源码来分析下FFmpeg中AVBuffer相关的实现。 关键字:AVBuffer、AVBufferPool、AVBufferPool 1. AVBufferRef 1.…...
Python学习------起步7(字符串的连接、删除、修改、查询与统计、类型判断及字符串字母大小写转换)
目录 前言: 1.字符串的连接 join() 函数 2.字符串的删除&取代 replace()函数 3.字符串的修改&切割 (1)strip() 函数 (2)lstrip()函数 和 rstrip()函数 (3)split()函数-->…...
雪花算法snowflake
snowflake中文的意思是 雪花,雪片,所以翻译成雪花算法。它最早是twitter内部使用的分布式环境下的唯一ID生成算法。在2014年开源。雪花算法产生的背景当然是twitter高并发环境下对唯一ID生成的需求,得益于twitter内部高超的技术,雪…...
Part 4 描述性统计分析(占比 10%)——上
文章目录【后续会持续更新CDA Level I&II备考相关内容,敬请期待】【考试大纲】【考试内容】【备考资料】1、统计基本概念1.1、统计学的含义及应用1.1.1、统计学的含义1.2.1、统计学的应用1.2、统计学的基本概念1.2.1、数据及数据的分类1.2.2、总体和样本1.2.3、…...
Linux系统安全:安全技术和防火墙
目录 一、安全技术 1、安全技术 2、防火墙分类 二、防火墙 1、iptables五表五链 2、黑白名单 3、iptables基本语法 4、iptables选项 5、控制类型 6、隐藏扩展模块 7、显示扩展模块 8、iptables规则保存 9、自定义链使用 一、安全技术 1、安全技术 ①入侵检测系统…...
【干货】Python:turtle库的用法
【干货】Python:turtle库的用法1. turtle库概述2. turtle库与基本绘图2.1 导入库的三种方式2.1.12.1.22.1.32.2 窗体函数2.2 画笔状态函数2.2.1 seed(s)2.2.2 random()2.2.3 randint(a, b)2.2.4 getrandbits(k)2.2.5 randrange(start, stop[ , step])2.2.6 uniform(…...
信息安全与网络安全有什么区别?
生活中我们经常会听到要保障自己的或者企业的信息安全。那到底什么是信息安全呢?信息安全包含哪些内容?与网络安全又有什么区别呢?今天我们就一起来详细了解一下。什么叫做信息安全?信息安全定义如下:为数据处理系统建…...
花了5年时间,用过市面上95%的工具,终于找到这款万能报表工具
经常有粉丝问我有“哪个报表工具好用易上手?”或者是“有哪些适合绝大多数普通职场人的万能报表工具?” 从这里我大概总结出了大家选择报表工具最期望满足的3点: (1)简单易上手:也就是所谓的学习门槛要低…...
ESP32S3系列--SPI主机驱动详解(一)
一、目的SPI是一种串行同步接口,可用于与外围设备进行通信。ESP32S3自带4个SPI控制器外设,其中SPI0/SPI1内部专用,共用一组信号线,通过一个仲裁器访问外部Flash和PSRAM;SPI2/3各自使用一组信号线;开发者可以使用SPI2/3控制外部SPI…...
2023开工开学火热!远行的人们,把淘特箱包送上顶流
春暖花开,被疫情偷走的三年在今年开学季找补回来了。多个数据反馈,居民消费意愿大幅提升。在淘特上,开工开学节点就很是明显:1月30日以来,淘特箱包品类甚至远超2022年双11,成为开年“第一爆品”。与此同时&…...
Intel x86_64 PMU简介
文章目录前言一、性能监控概述二、CPUID information三、架构性能监控3.1 架构性能监控 Version 13.1.1 架构性能监控 Version 1 Facilities3.1.2 预定义的体系结构性能事件3.1.3 cmask demo测试参考资料前言 Intel 64 和 IA-32 架构提供了 PMU(Performance Monito…...
Vue (2)
文章目录1. 模板语法1.1 插值语法1.2 指令语法2. 数据绑定3. 穿插 el 和 data 的两种写法4. MVVM 模型1. 模板语法 root 容器中的代码称为 vue 模板 1.1 插值语法 1.2 指令语法 图一 : 简写 : v-bind: 是可以简写成 : 的 总结 : …...
ESP8266 + STC15基于AT指令通过TCP通讯协议获取时间
ESP8266 + STC15基于AT指令通过TCP通讯协议获取时间 如果纯粹拿32位的ESP8266模块给8位的单片机仅供授时工具使用,有点大材小用了。这里不讨论这个拿esp8266来单独开发使用。本案例只是通过学习esp8266 AT指令功能来验证方案的可行性。 🔖STC15 单片机采用的是:STC15F2K60S…...
谈谈Spring中Bean的生命周期?(让你瞬间通透~)
目录 1.Bean的生命周期 1.1、概括 1.2、图解 2、代码示例 2.1、初始化代码 2.2、初始化的前置方法和后置方法(重写) 2.3、Spring启动类 2.4、执行结果 2.5、经典面试问题 3.总结 1.Bean的生命周期 1.1、概括 Spring中Bean的生命周期就是Bean在…...
如何将VirtualBox虚拟机转换到VMware中
转换前的准备 首先需要你找到你的virtualbox以及VM安装到哪个文件夹里了,需要将这两个文件夹添加进环境变量Path中。 如果你记不清了,可以用everything全局搜索一下“VBoxManage.exe’以及“vmware-vdiskmanager.exe”,看一眼这个程序放到哪…...
洞庭龙梦(开发技巧和结构理论集)
1、经验来源,单一获取方式。进行形态等级展示。唯一游戏系统经验来源。无主线和支线剧情。2、玩家使用流通货币(充值货币),到玩家空间商城充值游戏,两人以上玩家进行游戏,掉落道具。交易系统游戏玩法&#…...
【23种设计模式】创建型模式详细介绍
前言 本文为 【23种设计模式】创建型模式详细介绍 相关内容介绍,下边具体将对单例模式,工厂方法模式,抽象工厂模式,建造者模式,原型模式,具体包括它们的特点与实现等进行详尽介绍~ 📌博主主页&…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...
全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
