SQL 解析在 CloudQuery 中的应用

2023-11-05

hi 好久不见!今天将为大家带来一期干货满满的技术分享。

作为一款数据库管控平台,大家通常认为 CloudQuery 的核心能力是对平台的管控,包括统一入口管理、权限体系、审计分析等,但实际上 CloudQuery 的核心技术点之一在于其独特的 SQL 解析能力。

01

SQL 解析功能界定

SQL 解析是指将结构化查询语言( SQL 语句)转换成可以被数据库系统理解和执行的内部表示形式的过程。在执行 SQL 查询之前,数据库系统需要对查询语句进行解析,以确定查询语句的语法是否正确,是否存在语义错误,并生成执行计划。

目前 SQL 解析工具有 Druid、JSqlParser、Apache Calcite、Presto 等,它们都提供了一些 API 用于分析 SQL 语句中的信息,比如获取表名、列名等字段。但是上述工具提供的 SQL 解析功能通常封装性比较强,扩展性不足,支持的数据源有限,在许多特殊场景下它们无法准确的给出 SQL 解析结果。

因此, CloudQuery 技术团队选择使用 ANTLR 作为 SQL 解析的引擎。ANTLR 作为 SQL 解析引擎具有很多优势,它帮助我们构建高效、可扩展和易于维护的 SQL 解析器。

02

SQL 解析原理介绍

SQL 解析是将用户输入的 SQL 语句转换为数据库能够理解的结构化查询语言的过程,与普通编程语言的解析无本质区别。主要分为词法分析、语法分析、语义分析、优化、代码生成这些步骤。SQL 解析的原理可以分为两个主要阶段:词法分析和语法分析。

词法分析

词法分析是将 SQL 语句分解为一个个单独的 Token,标识每一个关键字、符号或者其他语法元素的过程。词法分析器会逐个读取 SQL 语句中的字符,根据预定义好的规则组成不同的 Token,并将 Token 序列传递给下一个步骤。

比如,下面是一个简单的 SELECT 语句:

SELECT FirstName FROM Employee WHERE Department = ‘Sales’

在进行词法分析后,将生成的 Token 序列如下:

在这里插入图片描述

语法分析

语法分析是将 Token 序列转换成语法分析树,并进行语义分析、类型检查等处理的过程。语法分析器会根据事先定义好的 SQL 语法规则,将 Token 序列转换为语法分析树,并对其进行分析,以确定 SQL 语句是否符合语法规范。

比如,针对上述 SELECT 语句,语法分析器会将其转换为以下语法分析树:

SELECT_STATEMENT
/ | \
SELECT COLUMN_LIST FROM WHERE
| | |
FirstName Employee Department = ‘Sales’

SQL 语句数据收集

在经过词法分析和语法分析的步骤后,我们就得到了一棵语法分析树。我们要收集 SQL 语句中的表名、列名、表达式等信息,其实就是遍历这个语法树的各个节点,将想要获取的信息保存下来。

在上面的语法树中,我们通过访问 COLUMN_LIST 节点可以获取到语句中查询的列名,通过 FROM 节点可以获取到语句中查询的表名,通过WHERE 节点可以获取到语句中的查询条件。

有了这些信息,我们就可以基于这些信息做许多数据库方面的功能,比如 SQL 语句权限管控、SQL 合法性检查、SQL 高危操作检查等。

03

SQL 解析在 CloudQuery 中的应用

CloudQuery 很多功能的实现都离不开强大的 SQL 解析能力,SQL 解析是 CQ 稳步前行的一大基石。

SQL 高亮

在编辑框中输入一条 SQL 语句,可以看到语句中的关键字部分 SELECT、FROM、WHERE 会被渲染成蓝色,这其实就是上面讲到的词法分析的应用。

在这里插入图片描述

在语句经过词法分析后,语句会变成一系列 Token,Token 代表了语句中不同类型的字符。Token 大致上可以分为关键字、标识符、数字、字符串、注释这几种,然后编辑器就可以根据这几种类别,将用户输入的 SQL 语句进行着色。

语法提示

我们在输入 SQL 的过程中,比如输入下面的文本:

SELECT * FROM SYS.

通常输入到这里的时候,我们希望提示出 SYS 下面的一些信息来帮助我们快速写完 SQL,比如提示出表名、视图名、函数名等。目前 CloudQuery 在用户书写 SQL 语句的过程中有完善的智能提示功能, 包括提示出关键字、表名、列名、函数名、子查询别名等。

这里 SQL 的智能提示技术就是上面讲到的语法分析的应用,当我们输入 SELECT FROM SYS. 的时候,其实已经经过语法分析构成了一棵语法树,只是这棵语法树不完整,CloudQuery 在用户输入 SQL 语句时会实时遍历语法树,找出当前语法树中缺失的节点,在例子中缺失的节点就是表名节点,由此可以得到我们当前提示信息应该是 SYS 下的表名或视图名。

在这里插入图片描述

SQL 语句权限控制

CloudQuery 使用基于角色的权限访问控制体系,权限控制粒度可以详细到每一种 SQL 语句、每一个数据库对象。比如常用的 SELECT、UPDATE、DELETE、CREATE TABLE、CREATE FUNCTION、函数调用等语句。

这里语句权限的控制就是 SQL 解析的重要应用场景,CloudQuery 在接收到用户输入的 SQL 语句后,会经过上述的词法分析和语法分析步骤,再遍历语法树收集 SQL 语句中的信息。在信息收集过程中,会提取出 SQL 语句中涉及到的所有表名、列名、别名、函数、查询条件等信息,接下来会对这些信息做进一步加工处理,比如消除 TABLE 的别名、绑定列的来源表、对象的真实类型查询等。

无权限的用户输入下面的SQL语句,将会受到权限管控:

SELECT * FROM “SYS”.“ACCESS " L E F T J O I N " S Y S " . " A C L M V " LEFT JOIN "SYS"."ACLMV "LEFTJOIN"SYS"."ACLMV”;
DELETE FROM “CQ”.“USER” WHERE ID = 1;
CREATE OR REPLACE FUNCTION GET_UUID RETURN VARCHAR2 IS
uuid VARCHAR2(32);
BEGIN
uuid := REPLACE(SYS_GUID(),‘-’,‘’);
RETURN uuid;
END;
BEGIN
“CQ”.“GET_UUID”();
END;

在这里插入图片描述

动态过滤数据行

CloudQuery 支持数据行安全控制,行安全控制是 CloudQuery 的一项安全特性,它允许管理员定义基于行的安全规则,以限制用户在表中的访问权限。

使用行安全控制,可以根据用户的角色、组织、部门等信息来动态控制数据的可见性,从而增强数据库的安全性。CloudQuery 的行安全控制条件支持任意的 SQL 表达式、支持引用用户的任何参数值、支持引用系统级别的参数值、支持引用环境变量等。

下面用一个例子说明行安全控制的使用场景: 存在一张业务数据表,其中有一个部门字段( dept ),管理员希望普通用户在查询这张表里的数据时,只能查询到自己部门的数据。在 CloudQuery 可以通过给表配置行安全控制实现上面的需求,配置方式类似下面这样:

DEPT = ‘${USER.DEPT}’

上面配置中 DEPT 是表中的列名, ${USER.DEPT} 是引用用户的部门参数,在真正执行 SQL 时这里会被替换成用户的真实部门值。用户在执行下面的 SQL 语句时:

SELECT * FROM DEPT;

最终执行的 SQL 会被修改成:

SELECT * FROM DEPT WHERE DEPT = ‘dept1’;

行安全控制的实现方式也依赖于 SQL 解析,在经过前面所说的词法分析、语法分析、SQL 语句信息收集这几步后,我们可以收集到语句中的需要行过滤的表名,当然还要知道这个表名所在的 SELECT 语句的位置信息, 以及所在 SELECT 语句中 FROM 的位置和WHERE条件的位置。通过这些信息,我们就可以对原始语句进行改写。

以上就是 SQL 解析在 CloudQuery 中的基本应用,正是凭借强大的 SQL 解析能力,CloudQuery 持续不断地为用户提供稳定高效的操作体验。

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SQL 解析在 CloudQuery 中的应用 的相关文章

  • MySQL MIN/MAX 所有行

    我有桌子Races与行ID Name and TotalCP 我选择分钟 TotalCP FROM Races 但是我想选择具有最小值的整行 我如何在单个查询中做到这一点 从聚合值获取整行的一般形式是 SELECT FROM Races W
  • 在sqlite SQL语句中与order by子句结合使用limit

    下面的两条 SQL 语句总是会产生相同的结果集吗 1 SELECT FROM MyTable where Status 0 order by StartTime asc limit 10 2 SELECT FROM SELECT FROM
  • 列中差异的数量

    我想检索一列每行中有多少个字母的差异 例如 如果您有一个值 test 而另一行有一个值 testing 则 test 和 testing 之间的差异为 4 个字母 该列的数据值为 4 I have reflected about it an
  • 如何从 PostgreSQL 中的时间戳列值提取一天中的时间(或小时)?

    我正在尝试从 PostgreSQL 中的 时间戳 列中提取一天中的时间 这是我的做法 但是 太糟糕了 知道如何做得更好吗 SELECT date part hour date demande text hours date part min
  • Laravel leftJoin 仅右表的最后一条记录

    我是 Laravel 的新手 我有两张桌子 1 产品 2 价格 products id product int p key name varchar prices id price int p key id product int
  • 当所有维度值都具有 100% 重要性时处理多对多维度

    我至少会尽力保持简洁 假设我们正在跟踪一段时间内的账户余额 所以我们的事实表将包含诸如 账户余额情况表 FK 账户ID FK 日期ID Balance 显然你有一个账户维度表 and a 日期维度表 所以现在我们可以轻松地过滤帐户或日期 或
  • MySQL Connector C/C API - 使用特殊字符进行查询

    我是一个 C 程序 我有一个接受域名参数的函数 void db domains query char name 使用 mysql query 我测试数据库中是否存在域名 如果不是这种情况 我插入新域名 char query 400 spri
  • 即使使用“autoReconnect=true”,MySql JDBC 也会超时[重复]

    这个问题在这里已经有答案了 有时 我的 Java Tomcat6 Debian Squeeze 应用程序无法与 MySql 服务器通信 Tomcat 应用程序位于前端服务器上 而 MySql 位于单独的 仅限 MySql 的机器上 一个典型
  • gem install mysql:无法构建 gem 本机扩展 (Mac Lion)

    我为 Mac OS X Lion 安装了 MySQL 5 5 27 来自 dmg 现在我尝试安装 mysql gem gem install mysql Building native extensions This could take
  • 用更轻的解决方案替换完整的 ORM(JPA/Hibernate):推荐的加载/保存模式?

    我正在开发一个新的 Java Web 应用程序 并且正在探索保存数据的新方法 对我来说是新方法 我主要有 JPA 和 Hibernate 的经验 但是 除了简单的情况之外 我认为这种完整的 ORM 可能会变得相当复杂 另外 我不太喜欢和他们
  • 如何将ElasticSearch与MySQL集成?

    在我的一个项目中 我计划将 ElasticSearch 与 MySQL 结合使用 我已经成功安装ElasticSearch 我可以单独管理ES中的索引 但我不知道如何用 MySQL 实现同样的功能 我读过一些文件 但我有点困惑 没有明确的想
  • 初级SQL部分:避免重复表达式

    我对 SQL 完全陌生 但我们可以说StackExchange 数据浏览器 https data stackexchange com 我只想按信誉列出前 15 位用户 我写了这样的内容 SELECT TOP 15 DisplayName I
  • MySQL 查询到 CSV [重复]

    这个问题在这里已经有答案了 有没有一种简单的方法来运行MySQL查询来自linux命令行并以csv格式输出结果 这就是我现在正在做的事情 mysql u uid ppwd D dbname lt lt EOQ sed e s g tee l
  • 如何使用 Perl 更改 mysql 密码

    我需要使用 Perl 脚本更改一些 mysql 密码 以下内容在更改数据库条目时有效 但是当我针对 mysql 用户更改修改它时 它将它们重置为空白密码 最后 刷新权限 也很好 但我还没有找到方法 usr bin perl use DBI
  • 计算运行总计时出错(之前期间的累计)

    我有一张桌子 我们称之为My Table有一个Created日期时间列 在 SQL Server 中 我试图提取一个报告 该报告显示历史上有多少行My Table按月在特定时间 现在我知道我可以显示有多少added每个月 SELECT YE
  • Google BQ:运行参数化查询,其中参数变量是 BQ 表目标

    我正在尝试从 Linux 命令行为 BQ 表目标运行 SQL 此 SQL 脚本将用于多个日期 客户端和 BQ 表目标 因此这需要在我的 BQ API 命令行调用中使用参数 标志 parameter 现在 我已经点击此链接来了解参数化查询 h
  • 使用间隔阈值对不同的连续时间戳记录进行分组

    我有一系列间歇性间隔的带有时间戳的 GPS 坐标 我正在使用 PostGIS 将它们渲染到地图画布上 为了渲染它们 需要使用 PostGIS 中的 ST MakeLine 聚合函数将点聚合成线 从而在地图上留下 GPS 数据丢失的间隙 数据
  • 在 postgres 查询中使用列表

    我有一个动态列表 list a b c d 所以长度可能会改变 我想在查询中比较这些列表值 select from student where name in all the list values 我想将列表值传递到此查询中 我怎样才能做
  • 如何在NiFi中映射流文件中的列数据?

    我有 csv 文件 其结构如下 Alfreds Centro Ernst Island Bacchus Germany Mexico Austria UK Canada 01 02 03 04 05 现在我必须将这些数据移入数据库 如下所示
  • MS ACCESS 计数/求和行数,不重复

    我有下表 我需要计算总行数而不包括任何重复记录 CustomerID test1 test1 test2 test3 test4 test4 如您所见 总行数为 6 但有两个 test1 和两个 test4 我希望查询返回 4 IOW 我想

随机推荐

  • 【数据库】PostgreSQL增加密码复杂度校验

    前言 最近修改问题单 被分配了一个增加密码复杂度校验的单子 PG库也不是很懂 查了资料 PG有自带的密码复杂度校验插件 只需要使用这个插件就可以了 然后根据这几天的折腾 总结一下 怎么添加密码复杂度校验插件 PostgreSQL可以使用pa
  • 云计算与大数据第11章 大数据隐私保护习题带答案

    第11章 大数据隐私保护习题 11 1 选择题 1 以下 D 通常不是导致数据隐私泄露问题的来源 A 数据被肆意收集 B 数据集成融合 C 大数据分析 D DDOS攻击 2 以下 C 不是数据隐私保护的主要目标 A 机密性 B 完整性 C
  • 第38步 深度学习图像识别:VGG19建模(Tensorflow)

    基于WIN10的64位系统演示 一 写在前面 1 预训练模型和迁移学习 预训练模型就像是一个精心制作的省力工具 它是在大量的数据上进行训练 然后将学习到的模型参数保存下来 然后 我们可以直接使用这些参数 而不需要从头开始训练模型 这样可以节
  • PyTorch基础练习-task7(用PyTorch完成手写数字识别)

    PyTorch基础练习 task7 task7 import torch import numpy as np from torch autograd import Variable import torch nn as nn import
  • Vue全局注册组件的几种方式

    Vue全局注册组件的几种方式 1 extend vue js 代码 var com Vue extend template h1 这是第一种方式 h1 Vue component MyComponent com 此时的组件名为 MyComp
  • MySQL数据备份和恢复

    MySQL数据备份和恢复 数据备份 mysqldump是MySQL数据库备份工具 可以备份MySQL数据库中的数据和结构 生成 sql文件 方便数据的迁移和恢复 使用mysqldump工具前一定要配置环境变量 打开开始菜单 搜索 环境变量
  • 谷歌gn编译文件的使用简介

    Gn是什么 它是Google用来维护chromium项目的编译工具 现在相关的开源项目都基于gn来进行编译管理 目前一些大型系统的都会使用gn 例如谷歌 鸿蒙 Gn就是一个构建脚本生成器 是之前gyp的升级版本 并且gn是基于c 编写 效率
  • Python论文绘图利器seaborn.lineplot

    Python论文绘图利器seaborn lineplot 提示 前言 Python论文绘图利器seaborn lineplot 提示 写完文章后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 Python论文绘图利器seabor
  • Java中的equals()方法

    equals 在哪里 首先我们知道Java中Object类是所有类的父类 它里面定义了equals 方法 public boolean equals Object obj return this obj 可以看到是使用 来进行比较的 那么
  • 20 个常用的 CSS 技巧

    Sandy 推荐 高级工程师 游戏开发 下面这几个CSS技巧你可能不知道 1 彩色照片变黑白 2 所有元素垂直居中 3 禁用鼠标 4 模糊文字 小编学完能量满满的 觉得对CSS又充满了爱 你也来看看 原文链接 http caibaojian
  • sql 关联了2张表的 update 语句(转)

    转自 SQL Update 使用一个表的数据更新另一张表 update 关联两个表 基本上 select 能支持的关联和子查询操作 都能在 update 语句中使用 在 where 条件中使用子查询 update a set a age 1
  • Spark WARN cluster.ClusterScheduler: Initial job has not accepted any resources;check your cluster

    当我在Spark集群模式执行以下命令时 root debian master home hadoop spark 0 8 0 incubating bin hadoop1 run example org apache spark examp
  • DBA成长随笔---Oracle 11g,性能优化之等待事件

    目录 等待的定位方式 等待事件分类 观察等待事件的视图 常见等待事件 等待事件主要可以分为两类 即空闲 IDLE 等待事件和非空闲 NON IDLE 等待事件 空闲等待事件 是指Oracle正等待某种工作 比如用sqlplus登录之后 但没
  • 远程桌面连接出现了内部错误怎么解决?

    远程桌面连接是一种非常方便的工具 可以让用户从远程访问其他计算机的桌面界面 但是 有时候在连接远程桌面时会出现内部错误 导致无法连接或者连接后无法正常使用 在本文中 我们将会讨论远程桌面连接出现内部错误的原因和解决方法 1 确认网络连接 在
  • 2023牛客暑期多校第三场部分题解

    索引 A B D E G H I J A 直接输出两个数的差即可 再判一下无解的情况 B 其实思路还挺顺的 首先拿的牌肯定是一段增一段减一段增一段减 的序列 并且 gt n gt n gt n 的开头和 n
  • React中使用antd DatePicker限制日期选择

    场景 React中使用antd DatePicker限制日期选择 有下面一些场景 1 今天之前的日期不可选择 不包括今天 disabledDate current gt let current current format YYYY MM
  • 多标签学习之白话版

    简单的机器学习 就是把人类的学习方式教给机器 斯 cdot 沃索迪 1 任务的提出 单标签学习 假设你不知道河豚长什么样子 给你 1000 张照片 并标注哪些有河豚 再给你 100 张新的照片 你能判断哪些照片里面有河豚吗 本例中 从 10
  • charles介绍及代理设置

    一 介绍 你别说 这个真挺好看 有的叫花瓶 有的叫青花瓷 二 说明 安装charles后 如果不是正版 需要破解 破解码去百度查一个即可 否则试用期过后 使用半小时后就自动关闭了 需要重新打开呢 破解码输入路径 help register
  • ElasticSearch系列18:Mapping 设计指南

    点击上方 方才编程 即可关注我 本文导读 ElasticSearch 的 mapping 该如何设计 才能保证检索的高效 想要回答这个问题 就需要全面系统地掌握 mapping 各种参数的含义以及其适用的场景 ps 本文基于ElasticS
  • SQL 解析在 CloudQuery 中的应用

    hi 好久不见 今天将为大家带来一期干货满满的技术分享 作为一款数据库管控平台 大家通常认为 CloudQuery 的核心能力是对平台的管控 包括统一入口管理 权限体系 审计分析等 但实际上 CloudQuery 的核心技术点之一在于其独特