SQL血缘解析

Druid 作为使用率特别高的的数据库连接池工具,在具备完善的连接池管理功能外,同时Druid 的 SQL解析功能可以用来防止 SQL注入等安全风险。通过对 SQL 语句进行解析和检查,Druid 可以识别并阻止潜在的恶意 SQL 语句执行,黑名单(阻止特定的 SQL 语句执行)、白名单(仅允许特定的 SQL 语句执行)等功能,从而提升数据库的安全性。

可以利用 Druid 的 SQL 解析结果,进行进一步的二次解析和组合,从而形成脚本的血缘关系和影响关系
在这里插入图片描述

测试访问地址:http://43.139.19.48:8888/#/
Gitee:https://gitee.com/javalxy/sql-lineage-show

前置知识

AST抽象语法树

官方文档链接:Druid_SQL_AST · alibaba/druid Wiki · GitHub

抽象语法树(AST, Abstract Syntax Tree) 是编程语言解析和编译过程中产生的一种树状数据结构,它表示源代码的语法结构。AST 抽象出代码的语法特征,同时剔除不必要的语法细节,提供了程序结构的抽象表示。

SQLTableSource

常见的SQLTableSource包括SQLExprTableSource、SQLJoinTableSource、SQLSubqueryTableSource、SQLUnionQuery

主要为表的关联类型,针对与不同的SQL,分支处理。

if (tableSource instanceof SQLExprTableSource) {SQLExpr sqlExpr = ((SQLExprTableSource) tableSource).getExpr();processTableExpression(tableName, sqlExpr);
} else if (tableSource instanceof SQLSubqueryTableSource) {List<SQLSelectItem> selectList = queryBlock.getSelectList();selectList.forEach(item -> processTableExpression(tableName, item.getExpr()));
} else if (tableSource instanceof SQLUnionQuery) {SQLUnionQuery sqlUnionQuery = (SQLUnionQuery) tableSource;List<SQLSelectQuery> relations = sqlUnionQuery.getRelations();for (SQLSelectQuery relation : relations) {if (relation instanceof SQLSelectQueryBlock) {SQLTableSource nestedTableSource = ((SQLSelectQueryBlock) relation).getFrom();if (nestedTableSource instanceof SQLExprTableSource) {SQLExpr sqlExpr = ((SQLExprTableSource) nestedTableSource).getExpr();processTableExpression(tableName, sqlExpr);}}}
}

SQLSelect & SQLSelectQuery

SQLSelectStatement包含一个SQLSelect,SQLSelect包含一个SQLSelectQuery,都是组成的关系。SQLSelectQuery有主要的两个派生类,分别是SQLSelectQueryBlockSQLUnionQuery

此对象是一个查询主体,其主要的关联关系就是查询的关系。这种关系由查询字段衍生出来,涵盖了查询字段、关系字段、函数、组成等(也就是可解析的字段类型,后文会详细说明,即:SQLExpr)。除此之外,还有表关系(如上文提到的 SQLTableSource)、分组关系等。这些关系共同构成了 SQL 语句的结构和逻辑。此对象也可看做是解析的中流砥柱,很多向下的衍生关系也都通过此封装。

if (sqlSelectQuery instanceof SQLSelectQueryBlock) {disposeSelectQuery((SQLSelectQueryBlock) sqlSelectQuery, sqlItems, fieldModels);
} else if (sqlSelectQuery instanceof SQLUnionQuery) {disposeSQLUnionQuery((SQLUnionQuery) sqlSelectQuery, sqlItems, fieldModels);
}

SQLExpr

解析代码中大约 80% 的内容可能都围绕着 SQLExpr 进行。在所有的 SQLExpr 子对象中,通常存在多层次的继承关系。因此,无论表达式多么复杂,都可以通过递归层层向下,找到基本类型进行处理。这种处理方式相当繁琐,因为需要针对每种类型进行细致的拆解和处理。对于几种基本类型,可以直接进行处理;但对于聚合函数或二元操作这样的复杂类型,则需要逐层拆解,获取其下层类型后再判断并处理,如此反复,直至解析到基本类型为止,形成一个完整的闭环。

目前已处理类型如下:

SQLAggregateExpr、SQLBinaryOpExpr、SQLPropertyExpr、SQLMethodInvokeExpr、SQLAllColumnExpr、SQLIdentifierExpr、SQLCaseExpr、SQLInListExpr、SQLCastExpr、SQLBetweenExpr、SQLQueryExpr、SQLCharExpr、SQLNullExpr、SQLIntegerExpr、SQLNumberExpr

其中也存在无法处理的情况,如常量类型,All类型(*),需要其他逻辑支持。

if (sqlExpr instanceof SQLAggregateExpr) {// 处理聚合函数表达式dispose((SQLAggregateExpr) sqlExpr, itemFieldModels);
} else if (sqlExpr instanceof SQLBinaryOpExpr) {// 处理二元操作表达式dispose((SQLBinaryOpExpr) sqlExpr, itemFieldModels);
} else if (sqlExpr instanceof SQLPropertyExpr) {// 处理属性表达式dispose((SQLPropertyExpr) sqlExpr, itemFieldModels);
} else if (sqlExpr instanceof SQLMethodInvokeExpr) {// 处理方法调用表达式dispose((SQLMethodInvokeExpr) sqlExpr, itemFieldModels);
} else if (sqlExpr instanceof SQLAllColumnExpr) {// 处理所有列(*)表达式dispose((SQLAllColumnExpr) sqlExpr, itemFieldModels);
} else if (sqlExpr instanceof SQLIdentifierExpr) {// 处理标识符表达式dispose((SQLIdentifierExpr) sqlExpr, itemFieldModels);
}
// 略...

示例

此示例和druid解析无关系。

SELECT name, age FROM users WHERE age > 18;

对应的 AST

这个 SQL 查询的 AST(抽象语法树)可以表示如下:

SelectStatement├── SelectClause│   ├── Column (name)│   └── Column (age)├── FromClause│   └── Table (users)└── WhereClause└── BinaryExpression (>)├── Column (age)└── Literal (18)

一条正确的 SQL 语句可以通过抽象语法树(AST)进行概括(通常使用 ANTLR 作为底层支持,排除 g4 模板解析失败的情况)。对于较复杂的语句,如关联查询、子查询和函数处理等,这些语句基本上是层层嵌套的。理论上,通过支持各种类型的解析后,可以使用递归方式遍历整个抽象语法树,从而完整地获取字段结构并进行二次处理。

二次处理Druid AST抽象语法树

使用Druid解析SQL

List

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

★ 算法OJ题 ★ 力扣11 - 盛水最多的容器

Ciallo&#xff5e;(∠・ω< )⌒☆ ~ 今天&#xff0c;我将和大家一起做一道双指针算法题--盛水最多的容器~ 目录 一 题目 二 算法解析 三 编写算法 一 题目 11. 盛最多水的容器 - 力扣&#xff08;LeetCode&#xff09; 二 算法解析 解法1&#xff1a;暴力枚举 …

文本数据分析-(TF-IDF)(1)

文章目录 一、TF-IDF简介1.意义2.TF与IDF1).TF&#xff08;Term Frequency&#xff09;2).IDF&#xff08;Inverse Document Frequency&#xff09;3).TF-IDF 二、应用三、代码实现1.文件读取2.数据预处理3.排序和输出4.全部代码 一、TF-IDF简介 1.意义 TF-IDF&#xff08;Te…

28 TreeView组件

Tkinter ttk.Treeview 组件使用指南 ttk.Treeview 是 Tkinter 的一个高级控件&#xff0c;用于显示和管理层次化数据。它类似于电子表格或列表视图&#xff0c;但提供了更丰富的功能&#xff0c;如可展开的节点、多列显示等。ttk 模块是 Tkinter 的一个扩展&#xff0c;提供了…

Golang | Leetcode Golang题解之第382题链表随机节点

题目&#xff1a; 题解&#xff1a; type Solution struct {head *ListNode }func Constructor(head *ListNode) Solution {return Solution{head} }func (s *Solution) GetRandom() (ans int) {for node, i : s.head, 1; node ! nil; node node.Next {if rand.Intn(i) 0 { …

《机器学习》数据分析之关键词提取、TF-IDF、项目实现 <下>

目录 一、内容回顾 1、核心算法 2、算法公式 3、拆分文本 二、再次操作 1、取出每一卷的地址和内容 得到下列结果&#xff1a;&#xff08;此为DF类型&#xff09; 2、对每一篇文章进行分词 3、计算TF-IDF值 得到以下数据&#xff1a; 三、总结 1、关键词提取 1&a…

数据挖掘之分类算法

分类算法是数据挖掘中常用的一类算法&#xff0c;其主要任务是根据已知的训练数据&#xff08;即带有标签的数据&#xff09;构建模型&#xff0c;然后利用该模型对新的数据进行分类。分类算法广泛应用于金融、医疗、市场营销等领域&#xff0c;用于预测、决策支持等任务。以下…

STM32G474采用“多个单通道ADC转换”读取3个ADC引脚的电压

STM32G474采用“多个单通道ADC转换”读取3个ADC引脚的电压&#xff1a;PC0、PA1和PA2。本测试将ADC1_IN6映射到PC0引脚&#xff0c;ADC12_IN2映射到PA1引脚&#xff0c;ADC1_IN3映射到PA2引脚。 1、ADC输入 ADC输入电压范围&#xff1a;Vref– ≤ VIN ≤ Vref ADC支持“单端输入…

Java 集合Collection(List、Set)Map

集合的理解和优点 1)可以动态保存任意多个对象&#xff0c;使用比较方便!2)提供了一系列方便的操作对象的方法: add、remove、 set、 get等3)使用集合添加,删除新元素的示意代码- Java集合的分类 Java的集合类很多&#xff0c;主要分为两大类&#xff0c;如图&#xff1a; 1…

iPhone备忘录不小心删除了怎么办?

在日常使用iPhone的过程中&#xff0c;备忘录作为我们记录重要信息、灵感闪现和日常琐事的小帮手&#xff0c;其重要性不言而喻。然而&#xff0c;有时候因为操作失误或是不小心点击&#xff0c;我们可能会将珍贵的备忘录内容删除&#xff0c;这无疑会让人感到焦虑与不安。但请…

深入垃圾回收:理解GC的核心算法与实现

垃圾回收&#xff08;Garbage Collection&#xff0c;GC&#xff09;是现代编程语言中一项关键技术。它不仅解决了内存管理中的诸多问题&#xff0c;还为开发者提供了一个更高效、更安全的编程环境。本文将深入探讨GC的起源、主要算法以及这些算法在不同编程语言中的具体实现。…

考试:计算机网络(01)

网络功能和分类 计算机网络是计算机技术与通信技术相结合的产物&#xff0c;它实现了远程通信、远程信息处理和资源共享。 计算机网络的功能&#xff1a;数据通信、资源共享、管理集中化、实现分布式处理、负载均衡。 网络性能指标&#xff1a;速率、带宽(频带宽度或传送线路…

嵌入式数据库

概述 1.作用&#xff1a;存储大量数据&#xff0c;专业存储数据 存储在内存&#xff08;数组&#xff0c;变量&#xff0c;链表&#xff09;上的特点&#xff1a;程序运行结束&#xff0c;或者掉电&#xff0c;数据会丢失。 存储在硬盘&#xff08;文件&#xff09;上的特点…

vue3+ts+vite项目代码检查报错(vue-tsc)

报错原因&#xff1a;vue-tsc与typescrip版本不兼容 排查流程&#xff1a; 1、开始以为vue-tsc或者typescript版本太低&#xff0c;通过npm update更新&#xff0c;更新后还是报错 2、项目中package.json文件中typescript、vue-tsc版本并无兼容问题 3、控制台执行npm list发…

【HarmonyOS】模仿个人中心头像图片,调用系统相机拍照,从系统相册选择图片和圆形裁剪显示 (一)

【HarmonyOS】头像图片&#xff0c;调用系统相机拍照&#xff0c;从系统相册选择图片和圆形裁剪显示 &#xff08;一&#xff09; Demo效果展示&#xff1a; 方案思路&#xff1a; 使用photoAccessHelper实现系统相册选择图片的功能。此API可在无需用户授权的情况下&#xff…

万亿生成式AI市场,商汤迎来“长坡厚雪”

AI掀起了全球科技玩家的军备竞赛&#xff0c;然而声浪越强噪音越多&#xff0c;这个领域的混乱程度也变得远超以往。就连刚刚公布财报的英伟达&#xff0c;市场也没有买账&#xff0c;因为担心AI驱动的增长高峰已过&#xff0c;接下来&#xff0c;下游会更看重实际成果。 “囤…

javaee、ssm(maven)、springboot(maven)项目目录结构以及编译后文件目录存放路径

javaee项目目录结构&#xff1a; src下的文件或者是源码编译后都会放在WebRoot&#xff08;项目根目录&#xff09;文件夹\WebRoot\WEB-INF\classes目录中。 编译后的文件夹目录如下&#xff1a; 以上为普通的javaee项目目录结构&#xff0c;同maven工程目录结构是不一样的。…

07-图5 Saving James Bond - Hard Version(C)

哈哈&#xff0c;我是真的服了&#xff0c;写了好几天结果给我个这&#xff0c;气死我了&#xff0c;果然还有很大的进步空间。如果有c测试点4&#xff0c;就好了。 又写了一天&#xff0c;是真解决不了了&#xff0c;这个问题等我明白一定来解答 哈哈&#xff0c; 测试点提示内…

【SQL】餐馆营业额七日均线数据

目录 题目 分析 代码 题目 表: Customer ------------------------ | Column Name | Type | ------------------------ | customer_id | int | | name | varchar | | visited_on | date | | amount | int | -----------------------…

Docker 数据卷管理及优化

目录 1 数据卷实现的目的 2 为什么要用数据卷 3 docker的两种数据卷 3.1 bind mount 数据卷 实践实例&#xff1a; 3.2 docker managed 数据卷 实验实例&#xff1a; 3.3 bind mount 数据卷和docker managed 数据卷的对比 3.3.1 相同点&#xff1a; 3.3.2 不同点&#xff1a; …

【网络安全】服务基础第一阶段——第二节:Windows系统管理基础----虚拟化IP地址以及用户与组管理

目录 一、Windows网络测试工具 1.1.ping命令 1.2.tracert命令 二、IP实验内容 2.1 实验一 2.2 实验二 三、用户与组管理 3.1 用户与账户概述 3.2 用户管理 3.3 用户增删改查 3.4 增加用户 3.5 修改用户属性 3.6 删除用户 3.7 组账户概述 3.8 组账户增删改查 四、…