0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

OSC开源社区 来源:KaiwuDB 2023-06-18 10:46 次阅读

一、概述

SQL 引擎主要由三大部分构成:解析器、优化器和执行器。

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

e903d308-0c36-11ee-962d-dac502259ad0.png  

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

KaiwuDB 中的语义解析主要包括:

检查数据库或表是否存在

检查语句所需的特定权限

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

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

二、语义解析

e917fe78-0c36-11ee-962d-dac502259ad0.png  

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

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

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

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

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

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

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

Source and target analysis (目标解析)

Permission check (权限校验)

Semanticdecomposition & validation (表达式拆分及其语义解析)

e92e5fa6-0c36-11ee-962d-dac502259ad0.png  

1. 目标解析及权限校验

1)接口路径:

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

2)核心接口为:

e94b4d14-0c36-11ee-962d-dac502259ad0.png  

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

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

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

1)接口路径:

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

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

e961648c-0c36-11ee-962d-dac502259ad0.png  

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

e96a5a7e-0c36-11ee-962d-dac502259ad0.png   e9881712-0c36-11ee-962d-dac502259ad0.png  

参数 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

e9a95ba2-0c36-11ee-962d-dac502259ad0.png  

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





审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 比较器
    +关注

    关注

    14

    文章

    1650

    浏览量

    107185
  • SQL
    SQL
    +关注

    关注

    1

    文章

    762

    浏览量

    44117
  • DDL
    DDL
    +关注

    关注

    0

    文章

    12

    浏览量

    6326
  • AST
    AST
    +关注

    关注

    0

    文章

    7

    浏览量

    2327

原文标题:一文走进SQL编译-语义解析

文章出处:【微信号:OSC开源社区,微信公众号:OSC开源社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    数据库SQL的优化

    数据库执行SQL都会先进行语义解析,然后将SQL分成步可执行的计划,然后逐步执行。通过分析
    的头像 发表于 10-09 15:43 1041次阅读
    数据库<b class='flag-5'>SQL</b>的优化

    手写SQL编译器词法分析

    精读《手写 SQL 编译器 - 词法分析》
    发表于 05-26 16:27

    手写SQL编译器——文法介绍

    精读《手写 SQL 编译器 - 文法介绍》
    发表于 05-29 13:35

    读懂SQL Server和MySQL的区别

    SQL Server和MySQL的区别主要体现在下面这些方面: 、本质区别是它们所遵循的基本原则 二、发行费用上:MySQL不全是免费,但很便宜 三、性能方面:先进的MySQL 四、安全功能 五、恢复性:先进的SQL
    发表于 09-28 11:29 8.3w次阅读

    SQL相关知识解析SQL完全手册的免费分享

    本文介绍了SQL的基础知识、SQL快速入门及SQL编程手册的分享。
    发表于 11-22 11:31 0次下载
    <b class='flag-5'>SQL</b>相关知识<b class='flag-5'>解析</b>及<b class='flag-5'>SQL</b>完全手册的免费分享

    解析编译原理

    学过编译原理课程的同学应该有体会,各种文法、各种词法语法分析算法,非常消磨人的耐心和兴致;中间代码生成和优化,其实在很多应用场景下并不重要(当然这块对于“编译原理”很重要);语义分析
    发表于 11-24 09:28 3.4w次阅读
    <b class='flag-5'>解析</b><b class='flag-5'>编译</b>原理

    详解SQL解析与应用

    为了避免这种损失,般会在管理上下功夫,比如为研发人员制定数据库开发规范;新上线的SQL,需要DBA进行审核;维护操作需要经过领导审批等等。而且如果希望能够有效地管理这些措施,需要有效的数据库培训
    发表于 06-21 09:28 1.2w次阅读
    <b class='flag-5'>一</b><b class='flag-5'>文</b>详解<b class='flag-5'>SQL</b><b class='flag-5'>解析</b>与应用

    解析PLC的应用

    解析PLC的应用,具体的跟随小编起来了解下。
    的头像 发表于 07-19 11:21 5259次阅读
    <b class='flag-5'>一</b><b class='flag-5'>文</b><b class='flag-5'>解析</b>PLC的应用

    带你了解安全测试基础之SQL注入

    传说,SQL注入是黑客对数据库进行攻击的常用手段,今天就来介绍SQL注入。
    的头像 发表于 06-28 11:15 2241次阅读

    嵌入式SQL语句

    编译程序编译处理目标语言程序主语言访问数据库基本步骤:第步:打开数据库第二步:定义必要的主变量和数据通信去第三步:用SQL访问数据库,并对返回结果进行处理第四步:关闭数据库...
    发表于 10-21 11:51 4次下载
    嵌入式<b class='flag-5'>SQL</b>语句

    掌握MyBatis的动态SQL使用与原理

    摘要:使用动态 SQL 并非件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这特性的
    的头像 发表于 01-06 11:27 983次阅读

    Java中如何解析、格式化、生成SQL语句?

    昨天在群里看到有小伙伴问,Java里如何解析SQL语句然后格式化SQL,是否有现成类库可以使用?
    的头像 发表于 04-10 11:59 972次阅读

    动态Sql介绍

    动态Sql介绍 动态 SQL 是 MyBatis 的强大特性之。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记
    的头像 发表于 05-31 09:34 1379次阅读
    动态<b class='flag-5'>Sql</b>介绍

    sql where条件的执行顺序

    。 在深入讨论WHERE条件的执行顺序之前,先回顾一下一SQL语句的执行顺序。SQL语句的执行通常可以分为以下几个步骤:解析器分析语法
    的头像 发表于 11-23 11:31 2194次阅读

    oracle执行sql查询语句的步骤是什么

    Oracle数据库是种常用的关系型数据库管理系统,具有强大的SQL查询功能。Oracle执行SQL查询语句的步骤包括编写SQL语句、解析
    的头像 发表于 12-06 10:49 957次阅读