一文走进 SQL 编译-语义解析

news2025/2/9 12:06:52

一、概述

SQL 引擎主要由三大部分构成:解析器、优化器和执行器。解析器的主要作用是将客户端传来的命令解析编译成数据库能识别运行的命令,其主要由词法解析、语法解析和语义解析三部分构成,如下图所示。

本文将重点介绍 KaiwuDB 语义解析部分,其输入为 AST 语法树,输出为可供优化器使用的 Expr 表达式。KaiwuDB 中的语义解析主要包括:

  • 检查数据库或表是否存在

  • 检查语句所需的特定权限

  • 对语句中的表达式进行语义解析

  • 检查 DDL 语句所请求的 schema change 的有效性

二、语义解析

KaiwuDB 中的语义解析主要包括以下流程:

  • 检查查询是否为 SQL 语言中的有效语句

  • 解析名称,例如表名或变量名的值

  • 消除不必要的中间计算,例如用 1.0 替换 0.6 + 0.4,这也被称为常数折叠

  • 确定用于中间结果的数据类型

其代码流程介于 parser 和 memo 构建之间,将 parser 输出的 AST 中的对象进行语义解析,语义解析的输出作为 memo 构建的输入。

接下来,将重点介绍查询语句的语义解析流程:

  • Source and target analysis (目标解析)   

  • Permission check (权限校验)

  • Semantic decomposition & validation (表达式拆分及其语义解析)

1. 目标解析及权限校验

1)接口路径:

buildStmt() -> buildSelectStmtWithoutParent() ->  buildSelectClause() -> builtFrom() -> buildDataSource()

2)核心接口为:

ResolveDataSource 通过 object name 解析出对象描述符(元数据),Privilege check 使用 current username 来校验当前用户对该对象是否有相应权限。

在完成目标解析和权限校验后,会为 select stmt 中的 from clause 构建 memo 表达式。这个行为看似不是语义解析应该做的,出现在这里的原因是 KaiwuDB 的语义解析和部分逻辑计划优化是相互融合的。

2. 表达式拆分及其语义解析

1)接口路径:

buildStmt() -> buildSelectStmtWithoutParent() -> buildSelectClause()

KaiwuDB 将 select stmt 中的各个部分拆分为表达式,并对其进行标量表达式的语义解析,从而完成 scalarExpr 的构建。例如:

2)标量表达式语义解析:

ROLE:检查表达式是否合法,为其做一些初步的优化,为其赋予类型。

INTERFACE

       in : Expr

       out : TypedExpr

       实质上是检查并赋予类型 + 简化表达式

       AnalyzeExpr()

HOW

       i. Name Resolution

       ii. TypeCheck

       iii. Normalize Expr

这些子任务实现几乎是纯粹的函数,唯一的缺陷是, TypeCheck 将 SQL 占位符($1、$2 等)的类型以一种对顺序敏感的方式,输出到通过递归传递的语义环境对象上。

注意:可以使用 EXPLAIN(EXPRS, TYPES) 来检查表达式,而不进行解构和简化。

i. Name Resolution

参数 sources 和 IndexedVars,如果都不是 nil,则表示 resolveNames 应该被执行。IndexedVars map 将被填充并且作为结果返回。

  • 用 parser.IndexedVar 实例替换列名

  • 用 parser.FuncDef 引用替换函数名

ii. TypeCheck

parser.TypeCheck() / parser.TypeCheckAndRequire():

  • 常数折叠

  • 类型推断

  • 类型检查

  • 在 ComparisonExpr 节点上记忆比较器函数

  • 用其类型来注释表达式和占位符

实现 Expr 接口的表达式有很多:AndExpr, OrExpr, CastExpr, CaseExpr 等。

每个表达式都实现了 TypeCheck 接口,在被调用时返回结果表达式的类型,包括 bool, string, int 等。

iii. Normalize

parser.NormalizeExpr():

注意:此处的 normalize 有点不太准确,因为他并没有进行标准的 normalize,这里只是将除变量名以外的东西都放到比较符号的右侧,从而达到简化的目的。

Normalize Example:

  • (a+1) < 3 is transformed to a < 2

  • -(a - b) is transformed to (b - a)

  • a between c and d is transformed to a >= c and a <= d

Normalize 的实现主要依靠 WalkExpr 函数。WalkExpr 会横穿 Expr,其通过传入对应的 visitor 来定义 WalkExpr 的具体行为,前面讲到的 name resolution 也是通过传入 name resolution visitor 实现的。

上述就是 KaiwuDB 关于语义解析的介绍,欢迎大家关注我们的公众号,后续将陆续为大家介绍更多关于 SQL 编译的相关内容。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/640391.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

机器学习-11 BP神经网络

BP神经网络 神经网络介绍前馈神经网络BP神经网络BP神经网络的核心思想误差反向传播算法BP网络结构 反馈神经网络自组织神经网络 神经网络相关概念激活函数Sigmoid函数tanh双曲正切函数ReLU函数Leaky RuLU函数Maxout函数激活函数的选择 损失函数Softmax交叉熵均方差损失函数自定…

chatgpt赋能python:Python文件处理入门指南-如何将Python程序转化为文件

Python文件处理入门指南 - 如何将Python程序转化为文件 Python是一门广泛应用于机器学习、数据分析、网络编程等领域的高级编程语言。Python代码简洁易懂&#xff0c;具有良好的可移植性和跨平台性&#xff0c;因此备受程序员们的喜欢。然而&#xff0c;要想让代码得到更广泛的…

kotlin协程flow retry功能函数返回失败后重试(4)

kotlin协程flow retry功能函数返回失败后重试&#xff08;4&#xff09; import kotlinx.coroutines.delay import kotlinx.coroutines.flow.* import kotlinx.coroutines.runBlockingfun main(args: Array<String>) {var count 0 //重试计数runBlocking {load().onEach…

chatgpt赋能python:Python怎么往表格里写数据

Python怎么往表格里写数据 在Python中&#xff0c;我们经常需要往表格里写入数据。表格是一种最基本的数据储存结构&#xff0c;而Python在处理表格数据方面非常出色。在这篇文章中&#xff0c;我们将介绍Python中常用的几种写入表格的方法。 方法一&#xff1a;使用CSV模块 …

MySQL-索引详解(二)

♥️作者&#xff1a;小刘在C站 ♥️个人主页&#xff1a;小刘主页 ♥️每天分享云计算网络运维课堂笔记&#xff0c;努力不一定有回报&#xff0c;但一定会有收获加油&#xff01;一起努力&#xff0c;共赴美好人生&#xff01; ♥️树高千尺&#xff0c;落叶归根人生不易&…

哨兵架构redisCluster-Redis(五)

上篇文章介绍了主从架构以及lua脚本。 主从架构&lua脚本-Redis&#xff08;四&#xff09;https://blog.csdn.net/ke1ying/article/details/131159229 Sentinel集群 主从的搭建我们已经完成&#xff0c;但如果主节点宕机&#xff0c;这时候导致整个redis服务不可用怎么办…

Cesium入门之十:Cesium加载3DTiles数据

目录 3DTiles介绍3DTiles数据结构Cesium中与3DTiles相关的类1.Cesium3DTileset类常用属性&#xff1a;常用方法&#xff1a; 2.Cesium3DTileStyle类常用属性&#xff1a; 3.Cesium3DTileContent类常用属性常用方法 4. Cesium3DTileFeature类常用属性常用方法 5.Cesium3DTile类常…

chatgpt赋能python:Python怎么循环

Python怎么循环 循环是编程中最重要的控制结构之一&#xff0c;它允许我们重复执行一组语句&#xff0c;直到满足某个条件为止。在Python中&#xff0c;我们有多种循环结构可供使用&#xff0c;本文将介绍它们及其用法。 for循环 for循环通常用于迭代&#xff08;遍历&#…

chatgpt赋能python:在Python中用何种方式来建立SEO友好网站?

在Python中用何种方式来建立SEO友好网站&#xff1f; 在当今数字时代&#xff0c;一个强大且易于维护的网站是任何企业或组织成功的关键。但是&#xff0c;一个网站的外观和功能不代表它的成功。如果语义不清、标记不恰当或结构不正确&#xff0c;网络爬虫可能会忽略您的网站&…

51单片机“密码锁”代码详解

注&#xff1a;此代码一经过验证&#xff0c;读者不必怀疑其正确性&#xff0c;如果烧录进去没有反应&#xff0c;请自行检查引脚端口配置&#xff0c;以及仔细分析代码实现原理。倘若能静下心来分析代码&#xff0c;一定能受益匪浅。 废话不多说&#xff0c;&#xff0c;直接…

深入理解 SpringBoot 日志框架:从入门到高级应用——(一)日志框架原理

文章目录 了解日志框架常见日志框架面向 SLF4J 编程SLF4J 接口规范其他框架统一转换为 SLF4J 框架 了解日志框架 日志框架的历史可以追溯到计算机编程的早期。在早期的编程语言中&#xff0c;如 C 和 Pascal&#xff0c;程序员通常使用 printf 或 fprintf 函数将程序的状态信息…

总结898

今天在B站上看英文短视频&#xff0c;认识了一位著名的心理学家乔丹彼得森&#xff08;号称“龙虾教授”&#xff09;。他的思想对我 产生了一定的影响。 曾在《写作:自我精进的武器》中看到过写作的5大好处&#xff0c;但他没有乔丹彼得森所讲的那么令我震撼&#xff0c;他对写…

Django框架-1

框架介绍 框架是整个或部分系统的可重用设计&#xff0c;表现为一组抽象构件及构件实例间交互的方法&#xff1b; 框架是可被应用开发者定制的应用骨架&#xff0c;是某种半成品&#xff1b; 使用框架开发的好处 开发周期短维护成本低软件生产效率和质量得到提高 Django框…

面向对象、封装、就近原则及this关键字

面向:拿、找&#xff1b; 对象:能干活的东西&#xff1b; 面向对象编程:拿东西过来做对应的事&#xff1b; 即&#xff0c;分别找对应的“对象”完成对应的“事件”。因此学习内容包括&#xff1a; ①学习各种已存在的对象并使用&#xff1b; ②学习设计对象并使用。 面向对象…

DAY21:二叉树(十一)二叉搜索树中的搜索+验证二叉搜索树(坑比较多,复盘)

文章目录 700.二叉搜索树中的搜索二叉搜索树概念二叉搜索树的搜索方式补充总结 思路递归法迭代法注意这里写if-if和if-else if的区别为什么if-if会访问空的root&#xff1f;if-if结构和if-else if-else的区别 迭代法修改结果&#xff1a; 98.验证二叉搜索树&#xff08;坑比较多…

Java小知识

一、lambda ()->{} ()中为接口唯一方法中的参数&#xff0c;可以任意取 {}为接口唯一方法中的执行语句&#xff0c;返回的结果类型必须符合接口中方法返回值的定义 原理理解&#xff1a; Public interface Printable{ String print(String suffix);} 在函数式编程中有一个方…

【哈佛积极心理学笔记】第6讲 乐观主义

第6讲 乐观主义 How can we create consciously and subconsciously a positive environment, where we actually can take out the most moral, the most successful self to appreciate that self. Create a powerful positive situation to bring out the best in people.…

STM32——08-STM32感应开关盖垃圾桶

项目二&#xff1a;感应开关盖垃圾桶 项目需求 检测靠近时&#xff0c;垃圾桶自动开盖并伴随滴一声&#xff0c; 2 秒后关盖 发生震动时&#xff0c;垃圾桶自动开盖并伴随滴一声&#xff0c; 2 秒后关盖 按下按键时&#xff0c;垃圾桶自动开盖并伴随滴一声&#xff0c; 2 秒后…

DAY19:二叉树(九)路径总和+已知中后序构造二叉树

文章目录 112.路径总和思路伪代码完整版写法1写法1必须分开两个函数的原因注意点 完整版写法2写法2不涉及到回溯的原因 106.中序和后序遍历构造二叉树思路伪代码后序数组如何切割出左右区间写法注意区间切割注意中序和前序如何唯一构造二叉树后序和前序能否唯一构造二叉树&…

03-踏入程序诗意:Golang 流程控制的优雅律动

&#x1f4c3;个人主页&#xff1a;个人主页 &#x1f525;系列专栏&#xff1a;Golang基础 &#x1f4ac;Go&#xff08;又称Golang&#xff09;是由Google开发的开源编程语言。它结合了静态类型的安全性和动态语言的灵活性&#xff0c;拥有高效的并发编程能力和简洁的语法。G…