前面的几个部分,基本实现了数据的读写。对于数据库使用者来说,SQL(Structured Query Language)是访问数据库的窗口,这一节就来看下simpledb对SQL语句的解析。

首先要说的是,simpledb实现了一个SQL-92的子集,具体支持的语法如下所示:

   1:  
   2: <Query>      := SELECT <SelectList> FROM <TableList> [ WHERE <Predicate> ]
   3: <SelectList> := <Field> [ , <SelectList> ]
   4: <TableList>  := TableName [ , <TableList> ]
   5: <Predicate>  := <Term> [ AND <Predicate> ]
   6: <Term>       := <Expression> = <Expression>
   7: <Expression> := <Field> | <Constant>
   8: <Field>      := FieldName
   9: <Constant>   := String | Integer
  10:  
  11: <Modify>     := <Insert> | <Delete> | <Update> 
  12: <Insert>     := INSERT INTO TableName ( <FieldList> ) VALUES ( <ConstList> )
  13: <FieldList>  := <Field> [ , <FieldList> ]
  14: <ConstList>  := <Constant> [ , <Constant> ]
  15: <Delete>     := DELETE FROM TableName [ WHERE <Predicate> ]
  16: <Update>     := UPDATE TableName SET <Field> = <Expression> [ WHERE <Predicate> ]
  17:  
  18: <Create>     := <CreateTable> | <CreateView> | <CreateIndex>
  19: <CreateTable>:= CREATE TABLE TableName ( <FieldDefs> )
  20: <FieldDefs>  := <FieldDef> [ , <FieldDefs> ]
  21: <FieldDef>   := FieldName <TypeDef>
  22: <TypeDef>    := INT | VARCHAR ( Integer )
  23: <CreateView> := CREATE VIEW ViewName AS <Query>
  24: <CreateIndex>:= CREATE INDEX IndexName ON TableName ( <Field> )

simpledb中的parse模块完成了解析的功能,类图如下:

图1 parse类图

在开始之间,先想一下SQL语句的解析,主要的工作是:

通过对输入SQL语句字符串的分割等工作,

首先,对输入SQL语句字符串的分割等工作;

然后,识别出语句执行的是CRUD中的哪个动作,识别出数据库操作关联的表和相关的数据;

最后,把识别出的表和数据传递给系统的相关接口,完成查询。

结合上面的类图,可以分三类:lexer、parser工具类,完成了SQL的解析;*Data,SQL解析成果的载体;BadSyntaxException,语法错误异常类。

下面,先从工具类说起:

> lexer

用编译原理的知识说来,这是个词法分析器,主要负责把输入的SQL字符串切割开,

第一步,将SQL字符串使用指定的分割符进行分割,将结果保存在一个叫tokens的string数组中

图2 lexer分割SQL示意图

分割过程如图2所示,利用正则表达式,将SQL字符串分割。

\s{1}|(,){1}|(=){1}|(\(){1}|(\)){1}|('[^']*'){1}

图3 SQL to tokens分割过程用到的RE

图4 实际运行时tokens结果

图5 恶意输入的结果

( 在面试的时候,问过我一个问题,如果有用户而已输入,输入了N多个空格,隔断了select语句的field-list,该怎么办?

select sid,            sname from     students where sid='10001'

实际上,在上面这个步骤,把所有的单元都独立分出来,如图5所示,每个空格都占一个tokens的位置。但是,lexer有一个nextToken方法,能有效地过滤掉这些干扰:

private void nextToken()
{
    position++;
    while (position < tokens.Length && tokens[position].Length == 0)
        position++;
}

之后,lexer通过以下的算法,实现对各种字符串片段的处理

(注意:lexer下有tokens数组的指针position,指向了lexer当前处理的tokens数组中的元素)

1、定位到下一个处理元素token,使用nextToken()方法
2、匹配token,使用match*()方法

3、处理token,使用eat*()方法

在match阶段,用到了如下的RE来对字符串片段进行匹配:

private const string intPattern = @"^[-+]?(0|[1-9]\d*)$";
private const string stringPattern = @"^'[^']*'$";
private const string idPattern = @"^[a-zA-Z_]\w*$"
private const string keywordPattern = @"^[a-zA-Z]*$";

simpledb支持的SQL关键字如下:

string[] keywords = {"select","from","where","and","insert","into","values",
"delete","update","set","create","table","varchar","view","as","index","on"};

在eat阶段,

总共有5个eat方法:eatDelim(char) eatId() eatIntConstant() eatKeyword(string) eatStringConstant,其中eatDelim和eatKeyword,有参数输入,根据参数的不懂,吃掉相应的分隔符或关键字,其他的,只是利用position,将position指向的token解析对指定的int或string。

可以说,lexer为SQL的解析完成了第一步的工作。

明天得早起,先到这里,待续。

转载于:https://www.cnblogs.com/YFYkuner/archive/2012/09/11/2679584.html

再读simpledb 之 SQL语句解析(1)相关推荐

  1. sql java 解析_Java 实现对Sql语句解析

    最近要实现一个简易的数据库系统,除了要考虑如何高效的存储和访问数据,建立表关系外,对基本的sql查询语句要做一个解析,这样我们才能知道用户的查询要求:因为时间关系,参考了已有的一篇文章,并对其实现中出 ...

  2. java sql语句逗号_Java 实现对Sql语句解析

    最近要实现一个简易的数据库系统,除了要考虑如何高效的存储和访问数据,建立表关系外,对基本的sql查询语句要做一个解析,这样我们才能知道用户的查询要求:因为时间关系,参考了已有的一篇文章,并对其实现中出 ...

  3. oracle12测试骤,Oracle中SQL语句解析的步骤

    我们都知道在Oracle中每条SQL语句在执行之前都需要经过解析,这里面又分为软解析和硬解析.那么这两种解析有何不同之处呢?它们又分别是如何进行解析呢?Oracle内部解析的步骤又是如何进行的呢?下面 ...

  4. 再读simpledb 之 元数据管理(3)

    接着前面的,本节介绍剩下的索引信息管理和视图信息管理. 3.(IndexMgr)索引信息管理 IndexMgr随着系统启动而创建,如果系统已经有idxcat.tbl,说明事先已经创建过索引信息表,直接 ...

  5. 数据库SQL语句解析

    SQL语言 在DBMS中以交互式执行SQL命令 针对数据的操作,核心功能只用9个动词完成. 一.SQL语言概述 SQL语言-三级模式支持 1.外模式 基本表:本身独立存在的表,一个关系对应一个表. 一 ...

  6. Oracle进阶学习3:SQL语句解析类型——硬解析和软解析

    文章目录 硬解析和软解析 shared pool功能 shared pool组成 SQL语句 硬解析和软解析 Oracle数据信息全部存储在数据字典中, Oracle的解析有两种,软解析以及硬解析 硬 ...

  7. Mysql三、数据库面试题+sql语句解析

    面试题1 (建表数据也有) 以下为某外卖公司的用户订单表.商户DB表.请写出一下问题的sql语句. 1.1月每笔消费均大于20元的用户的总消费金额 2.1月只吃了麻辣烫和汉堡的人数 3.计算每个人bd ...

  8. java sql语法解析_Java中的SQL语句解析

    String sql = "SELECT userId,password FROM Table_1 where userId ='" + userId +"' and p ...

  9. 编程能力强化(4)——模拟SQL语句解析

    这是2010年软件大赛的样题,用到的知识点比较多,也比较实用. 题目: 数据库中有"表"的概念."表"由若干"行"组成,每"行&q ...

  10. 再读目标检测--ssd深度解析

    [目标检测 – R-CNN,Fast R-CNN,Faster R-CNN] https://www.cnblogs.com/yanghailin/p/14767995.html [目标检测-SSD] ...

最新文章

  1. vibe前景提取改进算法
  2. js 的try catch应用
  3. KVM嵌套虚拟化 -- 在虚拟机中创建虚拟机
  4. SHOP++ JTM使用帮助
  5. jvm垃圾收集器的发展史及回收算法
  6. vue-cli3 本地代理配置
  7. Linux和Windows下部署BeetleX服务网关
  8. junit 预期错误_谨慎使用JUnit的预期异常
  9. 神经网络 卷积神经网络_如何愚弄神经网络?
  10. 【华为云技术分享】小白学YOLO:一文带你学YOLOv1 Testing
  11. 漫画丨让你专心干技术,没让你干到35岁啊…
  12. 修改样式_Word小技巧:如何设置样式 快速修改文本格式
  13. 微信小程序底部突起半圆设计
  14. Flex游戏篇——游戏开发概述
  15. php unset函数 赋值 null来销毁变量
  16. Android 9.0 蓝牙电话BluetoothHeadsetClient
  17. SQL SERVER 查看所有存储过程或视图里包含某个关键字的查询语句
  18. mac最强项目管理工具OmniPlan极速入门
  19. Nginx:搭建简单的文件下载服务器
  20. 名画134 方从义《云山图卷》

热门文章

  1. 申请以及集成 Stripe 的 Alipay 支付方案
  2. Javascript对象的方法赋值
  3. C#中可以使用正则表达式来过滤html字符
  4. svn checkout的时候报E000022错误
  5. Matlab多惯量仿真,两连杆机器鱼的简单建模以及MATLAB仿真
  6. 对象用[]来获取属性的注意点
  7. git和github的基本使用
  8. nginx访问502,日志报错:connect() to 127.0.0.1:180 failed (13: Permission denied)解决
  9. ERROR 1820: You must reset your password using ALTER USER statement before executing this statement
  10. jQuery操作元素内容的相关方法