mixer: sql词法分析器设计
介绍
mixer希望在proxy这层就提供自定义路由,sql黑名单,防止sql注入攻击等功能,而这些的基石就在于将用户发上来的sql语句进行解析。也就是我最头大的词法分析和语法分析。
到现在为止,我只是实现了一个比较简单的词法分析器,用以将sql语句分解成多个token。而对于从token在进行语法分析,构建sql的AST,我现在还真没啥经验(编译原理太差了),急需牛人帮忙。
所以,这里只是简单介绍一下mixer的词法分析。
tokenize
在很多地方,我们都需要进行词法分析,通常会有几种方式:
- 使用一个强大的工具,譬如lex,mysql-proxy就用的这种方式
- 使用正则表达式
- state machine
对于使用工具,我觉得有一个不怎么好的地方在于学习成本,譬如我用lex的时候就需要学习它的语法,同时通过工具生成的代码可读性都不怎么好,代码量大,更严重的是可能会比较慢。所以mysql自身也是自己实现一个词法分析模块。
而对于正则表达式,性能问题可能是一个很需要考虑的,而且复杂度并不比使用类似lex这样的工具低。
状态机可能是我觉得自己动手实现词法解析一个很好的方式,对于sql的词法解析,我觉得使用state machine的方式来自己写一个难度并不大,所以mixer自己实现了一个。
state machine
通常,一个状态机的实现采用的是state + action + switch的做法,可能如下:
switch state {
case state1:
state = action1()
case state2:
state = action2()
case state3:
state = action3()
}
对于一个state,我们通过switch知道它将会由哪一个action进行处理,而对于每一个action,我们则知道执行完成之后下一个state是什么。
对于上面的实现,如果state过多,可能会导致太多的case语句,我们可以通过state function进行简化。
一个state function就是执行当前的state action,并且直接返回下一个state function。
我们可以这样做:
type stateFn func(*Lexer) stateFn
for state := startState; state != nil {
state = state(lexer)
}
所以我们需要实现的就是每一个state function以及对应的它的下一个需要执行的state function。
mixer lexer
mixer的词法分析实现主要参考这个。主要实现在parser模块。
对于一个lexer,需要提供的是NextToken的功能,供外部获取下一个token,从而进行后续的操作(譬如语法分析)。
lexer的next token如下:
func (l *Lexer) NextToken() (Token, error) {
for {
select {
case t := <-l.tokens:
return t, nil
default:
if l.state == nil {
return Token{TK_EOF, ""}, l.err
}
l.state = l.state(l)
if l.err != nil {
return Token{TK_UNKNOWN, ""}, l.err
}
}
}
}
tokens是一个channel,每次state解析的token都会emit到这个channel上面,供NextToken获取,如果channel为空了,则再次调用state function。
可以看到,用go实现一个词法解析是很容易的事情,剩下的就是写相应的state function用来解析sql。
todo
mixer的词法分析还有很多不完善的地方,譬如对于科学计数法数值的解析就不完善,后续准备参考mysql官方的词法分析模块在好好完善一下。
mixer的代码在这里https://github.com/siddontang/mixer,希望感兴趣的童鞋共同完善。
mixer: sql词法分析器设计的更多相关文章
- PowerDesigner之SQL表格设计
设计表格我觉得用PowerDesigner比起在SQL Server中设计表格简单快捷许多. 首先,我们新建一个Model(可以使用快捷键Ctrl + N) 在PowerDesigner中侧边栏有浮动 ...
- MySQL-03 SQL语句设计
学习要点 SQL语句分类 DML语句 DML 查询语句 SQL语句分类 数据操纵语言(DML):用来操纵数据库中数据的命令.包括:SELECT.INSERT.UPDATE.DELETE. 数据定义语言 ...
- PL/SQL EO 设计与开发
1.INSERT 调用PL/SQL 去insert的时候,没有使用super(),此时应当自己创建callable statement: 调用checkErrors()方法在执行 callable s ...
- SQL数据库设计三范式
关系型数据库将数据库设计需要遵循的一些规则叫做“范式”,最基本的三个范式(1NF.2NF.3NF)简称三范式.第一范式是满足第二范式的基础,而第一.二范式又是满足第三范式的基础. 第一范式 表中的字段 ...
- sql表设计
数据库实际上是系统逻辑在磁盘上的固化,是信息河流的蓄水池. 数据库的表应有如下类型 1)类表.配置表.作为业务逻辑基本的名字,状态的定义,作为构建逻辑世界的最基础框架,解释框架的框架. 特点,数据不会 ...
- sql数据库设计学习---数据库设计规范化的五个要求
http://blog.csdn.net/taijianyu/article/details/5945490 一:表中应该避免可为空的列: 二:表不应该有重复的值或者列: 三: 表中记录应该有一个唯一 ...
- 【SQL数据库设计】数据库设计【小型数据库】
数据库设计 需求 表结构 字段类型.是否允许为null.是否有默认值 索引设计 数据库引擎的选择 根据产品原型分析,词性分析法,名词创建表或字段,动词表示关系. 数据存储:长期存储的数据, 1.主键: ...
- SQL Server设计三范式
第一范式(1NF) (必须有主键,列不可分) 数据库表中的任何字段都是单一属性的,不可再分 create table aa(id int,NameAge varchar(100)) insert aa ...
- 【代码总结】SQL语句设计
1.根据空值(NULL)检索条件 select * from user where age is not null; //查询年龄为null的所有用户 2.使用IN进行范围对比查询 ,5的所有用户 , ...
随机推荐
- 搭建 RabbitMQ Server 高可用集群
阅读目录: 准备工作 搭建 RabbitMQ Server 单机版 RabbitMQ Server 高可用集群相关概念 搭建 RabbitMQ Server 高可用集群 搭建 HAProxy 负载均衡 ...
- redis的基本数据类型
一:redis是一个开源的,使用C语言编写,支持网络,可基于内存亦可持久化的日志型,key-value方式存储的nosql数据库.作为缓存服务器,速度效率都很快,和memcache相似 redis支持 ...
- IF判断条件说明
在Python中,任何非零整数都为true,0是false:判断条件也可以是任何序列(列表.元组.字符串):所有长度不为零的为true,否则为false,比如:空序列为false.简而言之:非0非空为 ...
- docker管理工具
Portainer是Docker的图形化管理工具,提供状态显示面板.应用模板快速部署.容器镜像网络数据卷的基本操作(包括上传下载镜像,创建容器等操作).事件日志显示.容器控制台操作.Swarm集群和服 ...
- Rx系列二 | Observer | Observable
Rx系列二 | Observer | Observable 上节课我们对RX的一些基本概念和使用JAVA代码实现了一个观察者,但是这只是对思路的一个讲解,在我们JAVA中,其实是已经封装好了观察者对象 ...
- 安卓高级4 第三方库SlidingMenu的使用
源码位于github上(本人fork地址):点击进入地址 效果图: 使用方法:下载源码后 解压其中的文件夹library 到任意地方 修改library中gragle 其方法参考另一个博客(建议先修改 ...
- 改善database schema
本文地址:http://blog.csdn.net/sushengmiyan/article/details/50422102 本文作者:苏生米沿 Hibernate 读取你java模型类的映射元数据 ...
- ArrayList中的modCount与ConcurrentModificationException
在看ArrayList源码时,看到了一个字段modCount.在add.remove.clear等方法中都有modCount++的操作.不明白什么意思.点进去看了看该字段的解释,总算明白了.modCo ...
- win2008r2 AD用户账户的批量导入方法
win2008r2 AD用户账户的批量导入方法 http://www.jb51.net/article/38423.htm
- windows curl命令详解
概述 Curl命令可以通过命令行的方式,执行Http请求.在Elasticsearch中有使用的场景,因此这里研究下如何在windows下执行curl命令. 软件下载 下载地址:https://cur ...