目前,Inception已经支持大部分MySQL语句了,但是有一点不足之处是,规则都是固定的,虽然可以通过设置参数来修改是不是可以跳过这些检查,但除了检查语法错误之外,其它可配置的检查始终是一个固定在一个范围内的,如果想要新增一些检查项,过程可能比较慢长,所以想到在Inception内部,再集成一个格式化、结构化SQL语句的功能,这样的好处是,上层根据Inception返回的结构化的SQL语句,定义一些自己的规则,这样就可以满足更多人的需求了。

如果这是你的需求,请继续往下看。

结果集信息

前面在介绍<>中已经讲过了,可以通过设置选项--enable-query-print来启用打印语法树的功能,同样的,它与其它enable开头的选项是互斥的,不能同时设置,开启之后,再连接Inception,执行返回的结果集是一个与拆分、审核及执行都不同的结果集,所包括的列如下:

ID:这个用来表示当前语句的一个序列值。

STATEMENT:这个列用来存储当前被分析的SQL语句。

ERRLEVEL:这个列用来存储当打印遇到问题时,错误的级别,与审核结果集中的ERRLEVEL意义相同。

QUERY_TREE:这个列就是对当前语句的分析结果,格式为JSON字符串。

ERRMSG:这个列与上面的ERRLEVEL对应,当出错时,这里存储分析过程中所有的错误信息,与审核结果集中的同名列意义相同。

举例说明

举例说明才是最有说服力的: 针对SQL语句:

insert into t (sno,name)

select sno, name from t alias_t

where sno=(

select sno+1 from my

where

name like "%zhufeng%" and

sno > '10010' and

name=alias_t.name

)

order by name

limit 100, 10;

1

2

3

4

5

6

7

8

9

10

11

insertintot(sno,name)

selectsno,namefromtalias_t

wheresno=(

selectsno+1frommy

where

namelike"%zhufeng%"and

sno>'10010'and

name=alias_t.name

)

orderbyname

limit100,10;

执行时提交给Inception的语句如下:

执行结果如下:

注:使用到的print.py其实和之前<>中介绍的脚本没什么两样,只是显示的结果集不同而已。

对应的Json可视化的query_tree如下:

{

"command": "insert",

"table_object": {

"db": "ver",

"table": "t"

},

"fields": [

{

"type": "FIELD_ITEM",

"db": "ver",

"table": "t",

"field": "sno"

},

{

"type": "FIELD_ITEM",

"db": "ver",

"table": "t",

"field": "name"

}

],

"select_insert_values": {

"select_list": [

{

"type": "FIELD_ITEM",

"db": "ver",

"table": "t",

"field": "sno"

},

{

"type": "FIELD_ITEM",

"db": "ver",

"table": "t",

"field": "name"

}

],

"table_ref": [

{

"db": "ver",

"table": "t"

}

],

"where": [

{

"type": "FUNC_ITEM",

"func": "=",

"args": [

{

"type": "FIELD_ITEM",

"db": "ver",

"table": "t",

"field": "sno"

},

{

"type": "SUBSELECT_ITEM",

"engine": "single_select",

"subselect": {

"select_list": [

{

"type": "FUNC_ITEM",

"func": "OTHERS",

"name": "+",

"args": [

{

"type": "FIELD_ITEM",

"db": "ver",

"table": "my",

"field": "sno"

},

{

"type": "INT_ITEM",

"value": "1"

}

]

}

],

"table_ref": [

{

"db": "ver",

"table": "my"

}

],

"where": [

{

"type": "COND_ITEM",

"func": "AND",

"args": [

{

"type": "FUNC_ITEM",

"func": "LIKE",

"args": [

{

"type": "FIELD_ITEM",

"db": "ver",

"table": "my",

"field": "name"

},

{

"type": "STRING_ITEM",

"value": "%zhufeng%"

}

]

},

{

"type": "FUNC_ITEM",

"func": ">",

"args": [

{

"type": "FIELD_ITEM",

"db": "ver",

"table": "my",

"field": "sno"

},

{

"type": "STRING_ITEM",

"value": "10010"

}

]

},

{

"type": "FUNC_ITEM",

"func": "=",

"args": [

{

"type": "FIELD_ITEM",

"db": "ver",

"table": "my",

"field": "name"

},

{

"type": "FIELD_ITEM",

"db": "ver",

"table": "t",

"field": "name"

}

]

}

]

}

]

}

}

]

}

],

"OrderBy": [

{

"type": "FIELD_ITEM",

"db": "ver",

"table": "t",

"field": "name"

}

],

"limit": {

"limit": [

{

"type": "INT_ITEM",

"value": "10"

}

],

"limit_offset": [

{

"type": "INT_ITEM",

"value": "100"

}

]

}

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

{

"command":"insert",

"table_object":{

"db":"ver",

"table":"t"

},

"fields":[

{

"type":"FIELD_ITEM",

"db":"ver",

"table":"t",

"field":"sno"

},

{

"type":"FIELD_ITEM",

"db":"ver",

"table":"t",

"field":"name"

}

],

"select_insert_values":{

"select_list":[

{

"type":"FIELD_ITEM",

"db":"ver",

"table":"t",

"field":"sno"

},

{

"type":"FIELD_ITEM",

"db":"ver",

"table":"t",

"field":"name"

}

],

"table_ref":[

{

"db":"ver",

"table":"t"

}

],

"where":[

{

"type":"FUNC_ITEM",

"func":"=",

"args":[

{

"type":"FIELD_ITEM",

"db":"ver",

"table":"t",

"field":"sno"

},

{

"type":"SUBSELECT_ITEM",

"engine":"single_select",

"subselect":{

"select_list":[

{

"type":"FUNC_ITEM",

"func":"OTHERS",

"name":"+",

"args":[

{

"type":"FIELD_ITEM",

"db":"ver",

"table":"my",

"field":"sno"

},

{

"type":"INT_ITEM",

"value":"1"

}

]

}

],

"table_ref":[

{

"db":"ver",

"table":"my"

}

],

"where":[

{

"type":"COND_ITEM",

"func":"AND",

"args":[

{

"type":"FUNC_ITEM",

"func":"LIKE",

"args":[

{

"type":"FIELD_ITEM",

"db":"ver",

"table":"my",

"field":"name"

},

{

"type":"STRING_ITEM",

"value":"%zhufeng%"

}

]

},

{

"type":"FUNC_ITEM",

"func":">",

"args":[

{

"type":"FIELD_ITEM",

"db":"ver",

"table":"my",

"field":"sno"

},

{

"type":"STRING_ITEM",

"value":"10010"

}

]

},

{

"type":"FUNC_ITEM",

"func":"=",

"args":[

{

"type":"FIELD_ITEM",

"db":"ver",

"table":"my",

"field":"name"

},

{

"type":"FIELD_ITEM",

"db":"ver",

"table":"t",

"field":"name"

}

]

}

]

}

]

}

}

]

}

],

"OrderBy":[

{

"type":"FIELD_ITEM",

"db":"ver",

"table":"t",

"field":"name"

}

],

"limit":{

"limit":[

{

"type":"INT_ITEM",

"value":"10"

}

],

"limit_offset":[

{

"type":"INT_ITEM",

"value":"100"

}

]

}

}

}

上面的SQL语句实际上没有任何意义,这里只是为了尽可能好的将每一类型的表达式打印出来而胡乱构造的。

可以看到,这个Json串很长,不过结构化之后,整个语句就非常清楚了,是什么语句类型,用到什么表,什么列,有没有ORDER BY等,都非常明确,分析语句再也不是难事儿了,使用程序对这个结构化的语句做分析,应该是很容易了,并且是非常准确的。

标签定义

不过这里还是要简单讲一下语法树Json串中的一些标签:

command: 每个语句都是以command开头的,这个表示是什么语句类型,现在支持的有insert, update, delete, select这四种类型。

table_object: 表示当前语句对哪个表做的操作,这个只针对插入、删除操作的,比如是插入哪个表,删除哪个表。而更新操作在语法树中不太好确认哪些表被改了,所以这里没有明确拿出来,而是可以通过从更新列的信息中取到表信息,这也就是被更新的表。这是一个字典,里面包括的是一个,或者多个表信息,并且已经对应到其对应的数据库。

fields: 表示插入时语句中指定的要插入的列列表,如果没有指定,则没有这个信息。它是一个数组,包括了语句中所指定的所有列信息,每一个列是一个对列表达式的表示,包括数据库、表及列名,因为这是一个表达式,所以其表达式类型为FIELD_ITEM,后面会专门列出所有支持的表达式信息。

select_insert_values: 这个表示的是查询插入的查询部分,它是一个字典,里面包括了这个查询语句的所有元素,包括查询列、查询涉及的表、WHERE及ORDER BY等信息。

select_list: 表示当前查询语句(或者子查询)要查询的表达式信息,这里可以是列,也可以是其它计算出来的值,例子中就有select sno+1...这样的查询。

table_ref: 表示当前语句上下文中使用到的表信息,是一个数组,包括了所有的表,这里所谓的上下文,可以简单理解为,在一个子查询的可见范围内的所有表达式,都是属于同一个层次的,而如果比如一个列在当前上下文中找不到,可能就需要去父亲的上下文中找,那如果找到了,这种就算做是相关子查询,那么这种一个语句中有不同层级的查询存在时,就存在不同的上下文。在例子中也有相关反映。

where: 表示的就是查询表达式(包括查询、删除、更新及查询等)的语法树,因为WHERE语句其实就是一个表达式,只是有可能是多个表达式的逻辑运算而已。

OrderBy: 表示查询时使用到的排序列,是一个数组。

limit: 表示在查询时使用到的LIMIT信息,因为LIMIT是一个复合信息,包括了限制行数及开始位置等,所以会有limit及limit_offset,而limit_offset有可能没有,只有限制行数。

GroupBy: 表示查询时使用到的分组列,是一个数组。

Having: 表示查询时,使用到的Having表达式。

subselect: 如果使用到子查询时,则这个就用来表示这个子查询。它是一个字典。

many_values: 在查询语句中,如果插入的是值,而不是查询结果,则用这个来表示它的值列表,因为在MySQL中可以同时插入多个值,则这里有可能是多个。

values: 如果插入的是值时,这个用来表示一行的插入内容,这是一个数组,每个元素是一个列的表达式。这是many_values数组的一个元素。而如果是一个更新语句时,这表示的是被更新的值表达式列表。

set_fields: 用于表示更新语句的更新列的信息的,这是一个数组,里面每个元素对应被更新的一个列表达式。

上面就是目前支持的语句中出现的标签说明,但是还有很大一部分是表达式的处理,在打印表达式时,每一个对象都有一个公共的KEY,名为type,而针对不同的type,其它的KEY就不一定相同了,而具体的不同,这里就不多叙述了,这里只给出支持哪些表达式,除type之外的其它信息,可以在使用过程中一试便知。

支持表达式类型

下面是目前支持的所有表达式的列表,下面仅列出type的不同的值:

STRING_ITEM: 字符串,有其它KEY用来存储其具体值信息。

FIELD_ITEM: 列信息,有其它KEY用来存储具体对应的库、表及列名等。

FUNC_ITEM,COND_ITEM: 逻辑运算信息,包括比较运算符、AND、OR、ISNULL、ISNOTNULL、LIKE、BETWEEN、IN、NOT、NOW及其它自定义或者内置函数等运算操作。

INT_ITEM: 整数值表达式。

REAL_ITEM: 符点数值表达式。

NULL_ITEM: NULL值表达式。

SUBSELECT_ITEM: 子查询表达式。

SUM_FUNC_ITEM: 集函数表达式。

ROW_ITEM: 行表达式,比如select * from t where (sno,name) = (select sno,name from t1),这里where条件的左值就是这个表达式类型。

DECIMAL_ITEM: DECIMAL表达式类型。

上面就是目前所支持的表达式类型,已经基本覆盖所有的常用的表达式。

最后要说明的是,这里打印出来的信息,已经不完全只是语法分析结束之后的信息,而是经过Inception加工过的,比如在查询语句中用到了子查询,存在不同的上下文时,同时还使用了别名,或者在使用列时,没有指定其表名,这几种情况,Inception都打印了每一个列对应的库名表名,这样打印出来的信息中,已经不存在没有定位(找到其库名表名)的列名了,使用中更加友好,准确。比如上面例子中,就有这样的情况(名为alisa_t的t表的别名)。

后记

这个功能是新开发实现的,没有经过太多的验证(但也不存在太大问题),所以还需要后期的不断完善及更新,请各位有兴趣的同学,有任何意见、建议,都可以加群或者联系本人QQ讨论解决

mysql 语法树_Inception 语法树打印(15)相关推荐

  1. Scala的抽象语法树打印小工具-小拉达

    为什么80%的码农都做不了架构师?>>>    最近做的两个项目,一个是VeriScala,另一个是Lickitung,都涉及到了Scala的抽象语法树(AST),前者是写macro ...

  2. 2022-09-15 mysql列存储引擎-语法树转换

    摘要: 列存储引擎有一套自己的执行处理规则, 在进行处理前,是将mysql经过词法分析和语法分析后的语法树,经过了一些符合自己逻辑的处理. 本文记录mysql的语法树在列存储引擎中的转换过程. 逻辑建 ...

  3. 基于AST抽象语法树的SQL注入检测 (2) -- 每周小结(01-02~01-08) - .Little Hann

    本周继续学习AST的SQL语法检测原理的学习,文章的接下来部分准备分为2部分进行学习: 1. SQL注入语法防御规则 2. druid中SQL注入防御模块sql-wall 1. 相关学习资料 http ...

  4. 淘宝数据库OceanBase SQL编译器部分 源码阅读--解析SQL语法树

    http://blog.csdn.net/qq910894904/article/details/28658421 OceanBase是阿里巴巴集团自主研发的可扩展的关系型数据库,实现了跨行跨表的事务 ...

  5. 编译原理:短语,简单短语,句柄,语法树

    在文法和语言概念这里,比较难理解的是短语.简单短语,所以好好梳理一下. 先给出短语.简单短语的概念: (备注:Vn代表非终结符号集,V+代表字汇表的正闭包,V*代表字汇表的闭包) 所以,短语.简单短语 ...

  6. 2.5.1 推导和语法树

    2.5.1 推导和语法树 1. 语法树的生成 对句型的推导过程给出一种图形表示,这种表示称为语法树,也称推导树.设文法G = ( V N , V T , P , S ),对 G 的任何句型都能构造与之 ...

  7. 抽象语法树 Abstract syntax tree

    什么是抽象语法树? 在计算机科学中,抽象语法和抽象语法树其实是源代码的抽象语法结构的树状表现形式 在线编辑器 我们常用的浏览器就是通过将js代码转化为抽象语法树来进行下一步的分析等其他操作.所以将js ...

  8. html转换成抽象语法树,五分钟了解抽象语法树(AST)babel是如何转换的?

    抽象语法树 什么是抽象语法树? It is a hierarchical program representation that presents source code structure acco ...

  9. ast抽象语法树_新抽象语法树(AST)给 PHP7 带来的变化

    本文大部分内容参照 AST 的 RFC 文档而成:https://wiki.php.net/rfc/abstract_syntax_tree,为了易于理解从源文档中节选部分进行介绍. 我的官方群点击此 ...

最新文章

  1. 华人小哥控诉机器学习四大 Boring!CS 博士:深有同感,正打算退学
  2. 控制器描述者(ControllerDescriptor),行为方法描述者(ActionDescriptor),参数描述者(ParameterDescriptor)的小结...
  3. Mybatis ResolverUtil的设计概念
  4. 视频回顾丨带你逛腾讯全球数字生态大会「腾讯技术工程」展区
  5. 进程环境之环境表【转】
  6. P2756,ssl2601-飞行员配对问题【网络流24题,最大匹配,dinic】
  7. brew卸载jenv_使用brew,cask和jenv在MacOSX上设置多个Java JRE / JDK
  8. 怎么在html页面和js里判断是否是IE浏览器
  9. spring 通配符的匹配很全面, 但无法找到元素 'context:component-scan' 的声明
  10. [SNMP超详解]:简介、抓包分析与编程实战
  11. poi-tl——Word模板生成器
  12. 阿里巴巴 Java开发手册 最新官网下载
  13. 统计推断——假设检验——t 检验(总体的标准差未知)
  14. qpython3电脑版下载_qpython3官方版下载
  15. 当当当~他来喽CCRC-PIP个人信息保护专业人员
  16. jmeterhttp代理服务器_Jmeter使用HTTP代理服务器录制脚本
  17. 线性代数 06 克莱默法则
  18. 职场人士,如何打造“自品牌”?
  19. 什么是AVIF?如何在您的网站上使用AV1图像格式
  20. NewTek LightWave 3D 2018 破解版

热门文章

  1. 我的世界服务器自定义怪物怎么用,我的世界怪物属性自定义教程 怪物属性代码一览...
  2. 用python怎么读_python怎么读sql数据?
  3. VUE3搞一下数据录入
  4. linux php ldap_linux php ldap安装配置的方法
  5. 电子助力方向机控制模块_17款路虎揽胜:偶发性电子助力失效
  6. Win10安装GPU版tensorflow和keras
  7. 已有项目要不要迁移到Addressable系统?
  8. memcached简单的使用教程
  9. OpenCV基本函数使用--Python
  10. 6远程桌面连接不上_windows server2008 远程桌面 创建新用户和多用户登录