当前位置:首页 » 编程语言 » sql语法树

sql语法树

发布时间: 2022-02-25 15:57:43

java解析sql语句是实现不了的

这个需要用到编译原理的知识,理论上,既然dbms可以解析,那我们当然可以实现。
不过比较、很、太难实现而已。
并且不同数据库、不同版本的语法结构还不一样,又进一步增加了难度

Ⅱ 急求设计SQL语言的语法树

select * from 表名 for xml

以下是详细介绍:

FOR 子句

FOR 子句用于指定 BROWSE 或 XML 选项(BROWSE 和 XML 是不相关的选项)。
语法

[ FOR { BROWSE | XML { RAW | AUTO | EXPLICIT }
[ , XMLDATA ]
[ , ELEMENTS ]
[ , BINARY BASE64 ]
}
]
参数

BROWSE

指定当查看 DB-Library 浏览模式游标中的数据时允许更新。如果表包含时间戳列(用 timestamp 数据类型定义的列),表有唯一索引且 FOR BROWSE 选项在 SELECT 语句的最后发送到 SQL Server,则可以在应用程序中浏览该表。

说明 在含有 FOR BROWSE 选项的 SELECT 语句中无法使用 <lock_hint> HOLDLOCK。

FOR BROWSE 选项不能出现在用 UNION 运算符联接的 SELECT 语句中。

XML

指定查询结果将作为 XML 文档返回。必须指定下列 XML 模式之一:RAW、AUTO、EXPLICIT。

RAW

获得查询结果并将结果集内的各行转换为 XML 元素,用一般标识符 <row /> 作为元素标记。

测试:
select top 2 图书编号=BookNo,图书名称=BookName from sys_books as图书信息 FOR XML raw

结果:
<row 图书编号="B001" 图书名称="1"/><row 图书编号="B002" 图书名称="体育报(上海)"/>

AUTO

以简单的嵌套 XML 树返回查询结果。在 FROM 子句内,每个在 SELECT 子句中至少有一列被列出的表都表示为一个 XML 元素。SELECT 子句中列出的列映射到适当的元素特性。
测试:
select top 2 图书编号=BookNo,图书名称=BookName from sys_books as 图书信息 FOR XML auto

结果:
<图书信息 图书编号="B001" 图书名称="1"/><图书信息 图书编号="B002" 图书名称="体育报(上海)"/>

EXPLICIT

指定显式定义所得到的 XML 树的形状。使用此种模式,要求以一种特定的方式编写查询,以便显式指定有关期望的嵌套的附加信息。

XMLDATA

返回架构,但不将根元素添加到结果中。如果指定了 XMLDATA,它将被追加到文档上。

ELEMENTS

指定列作为子元素返回。否则,列将映射到 XML 特性。

测试:
select top 2 图书编号=BookNo,图书名称=BookName from sys_books as 图书信息 FOR XML AUTO,ELEMENTS

结果:
<图书信息><图书编号>B001</图书编号><图书名称>1</图书名称></图书信息><图书信息><图书编号>B002</图书编号><图书名称>体育报(上海)</图书名称></图书信息>

NARY BASE64

指定查询返回二进制 base64 编码格式的二进制数据。使用 RAW 和 EXPLICIT 模式检索二进制数据时,必须指定该选项。这是 AUTO 模式中的默认值。

Ⅲ impala怎么解析sql语句

Impala的SQL解析与执行计划生成部分是由impala-frontend(Java)实现的,监听端口是21000。用户通过Beeswax接口BeeswaxService.query()提交一个请求,在impalad端的处理逻辑是由void ImpalaServer::query(QueryHandle& query_handle, const Query& query)这个函数(在impala-beeswax-server.cc中实现)完成的。
在impala中一条SQL语句先后经历BeeswaxService.Query->TClientRequest->TExecRequest,最后把TExecRequest交由impala-coordinator分发给多个backend处理。本文主要讲一条SQL语句是怎么一步一步变成TExecRequest的。
本文以下内容都以这样的一个SQL为例说明:
select jobinfo.dt,user,
max(taskinfo.finish_time-taskinfo.start_time),
max(jobinfo.finish_time-jobinfo.submit_time)
from taskinfo join jobinfo on jobinfo.jobid=taskinfo.jobid
where jobinfo.job_status='SUCCESS' and taskinfo.task_status='SUCCESS'
group by jobinfo.dt,user

通过调用Status ImpalaServer::GetExecRequest(const TClientRequest& request, TExecRequest* result) 函数把TClientRequest转化成TExecRequest
在这个函数里通过JNI接口调用frontend.createExecRequest()生成TExecRequest。首先调用AnalysisContext.analyze(String stmt)分析提交的SQL语句。
注释:Analyzer对象是个存放这个SQL所涉及到的所有信息(包含Table, conjunct, slot,slotRefMap, eqJoinConjuncts等)的知识库,所有跟这个SQL有关的东西都会存到Analyzer对象里面。
1,SQL的词法分析,语法分析
AnalysisContext.analyze(String stmt)会调用SelectStmt.analyze()函数,这个函数就是对SQL的analyze和向中央知识库Analyzer register各种信息。
(1)处理这个SQL所涉及到的Table(即TableRefs),这些Table是在from从句中提取出来的(包含关键字from, join, on/using)。注意JOIN操作以及on/using条件是存储在参与JOIN操作的右边的表的TableRef中并分析的。依次analyze()每个TableRef,向Analyzer注册registerBaseTableRef(填充TupleDescriptor)。如果对应的TableRef涉及到JOIN操作,还要analyzeJoin()。在analyzeJoin()时会向Analyzer registerConjunct()填充Analyzer的一些成员变量:conjuncts,tuplePredicates(TupleId与conjunct的映射),slotPredicates(SlotId与conjunct的映射),eqJoinConjuncts。本例中on从句是一种BinaryPredicate,然后onClause.analyze(analyzer)会递归analyze这个on从句里的各种组件。
(2)处理select从句(包含关键字select, MAX(), AVG()等聚集函数):分析这个SQL都select了哪几项,每一项都是个Expr类型的子类对象,把这几项填入resultExprs数组和colLabels。然后把resultExprs里面的Expr都递归analyze一下,要分析到树的最底层,向Analyzer注册SlotRef等。
(3)分析where从句(关键字where),首先递归Analyze从句中Expr组成的树,然后向Analyzer registerConjunct()填充Analyzer的一些成员变量(同1,此外还要填充whereClauseConjuncts) 。
(4)处理sort相关信息(关键字order by)。先是解析aliases和ordinals,然后从order by后面的从句中提取Expr填入orderingExprs,接着递归Analyze从句中Expr组成的树,最后创建SortInfo对象。
(5)处理aggregation相关信息(关键字group by, having, avg, max等)。首先递归分析group by从句里的Expr,然后如果有having从句就像where从句一样,先是analyze having从句中Expr组成的树,然后向Analyzer registerConjunct()等。
(6)处理InlineView。
关于SQL解析中所涉及到的各种数据结构表示如下:

至此词法分析,语法分析结束,有点像一个小的编译器。我们现在回到frontend.createExecRequest()函数中。调用完AnalysisContext.analyze()之后,就开始填充TExecRequest内的成员变量。
(1)如果是DDL命令(use, show tables, show databases, describe),那么调用createDdlExecRequest();
(2)另外一种情况就是Query或者DML命令,那么就得创建和填充TQueryExecRequest了。
2,根据SQL语法树生成执行计划(PlanNode和PlanFragment的生成)
下面就是用Planner把SQL解析出的语法树转换成Plan fragments,后者能在各个backend被执行。
Planner planner = new Planner();
ArrayListfragments =
planner.createPlanFragments(analysisResult, request.queryOptions);
这个createPlanFragments()函数是frontend最重要的函数:根据SQL解析的结果和client传入的query options,生成执行计划。执行计划是用PlanFragment的数组表示的,最后会序列化到TQueryExecRequest.fragments然后传给backend的coordinator去调度执行。
下面进入Planner.createPlanFragments()函数看看执行计划是怎么生成的:
首先要搞清楚两个概念:PlanNode和PlanFragment。
PlanNode是SQL解析出来的逻辑功能节点;PlanFragment是真正的执行计划节点。
2.1,创建PlanNode
PlanNode singleNodePlan =
createQueryPlan(queryStmt, analyzer, queryOptions.getDefault_order_by_limit());
(1)这个函数首先根据from从句中的第一个TableRef创建一个PlanNode,一般为ScanNode(HdfsScanNode或者HBaseScanNode)。这个ScanNode关联一个ValueRange的数组(由多个cluster column取值区间组成)表示要读取的Table的范围,还关联一个conjunct(where从句)。
(2)这个SQL语句中TableRef中剩下的其他Table就需要建立HashJoinNode了。进入Planner.createHashJoinNode()函数:首先为这个Table建立ScanNode(同上),然后调用getHashLookupJoinConjuncts()获取两表或者多表JOIN的eqJoinConjuncts和eqJoinPredicates,利用这两个条件创建HashJoinNode。每个HashJoinNode也是树状的,会有孩子节点,对于我们举例的两表JOIN,孩子节点分别是两个表对应的ScanNode。(注意目前impala只支持一大一小两个表的JOIN,默认是左大右小,是通过把右边的小表分发到每个节点的内存中分别于左边大表的一个区间进行JOIN过滤实现的。)
(3)如果有group by从句,创建AggregationNode,并把刚才的HashJoinNode设为它的孩子。这里暂时不考虑DISTINCT aggregation function。
(4)如果有order by… limit从句,创建SortNode。
这样createQueryPlan()函数执行完毕,PlanNode组成的execution tree形成如下:

2.2,创建PlanFragment
接下来就看impala backend节点数目有多少,如果只有一个节点,那么整棵执行树都在同一个impalad上执行;否则调用createPlanFragments(singleNodePlan, isPartitioned, false, fragments)把PlanNode组成的执行树转换成PlanFragment组成的执行计划。
下面进入createPlanFragments()这个函数:
这是一个递归函数,沿着PlanNode组成的执行树递归下去,分别创建对应的Fragment。
(1)如果是ScanNode,创建一个PlanFragment(这个PlanFragment的root node是这个ScanNode,而且这个PlanFragment只包含一个PlanNode)。
(2)如果是HashJoinNode,并不是创建一个新的PlanFragment,而是修改leftChildFragment(是一个ScanNode)为以HashJoinNode作为root node的PlanFragment。因为对于HashJoinNode一般有两个ScanNode孩子,在处理HashJoinNode之前已经把这两个ScanNode变成了对应的PlanFragment。那么此时要得到HashJoinNode作为root node的PlanFragment是通过Planner.createHashJoinFragment()函数完成的:首先把当前HashJoinNode作为HashJoinFragment的root node;然后把leftChildFragment中的root PlanNode(也就是参与JOIN的两个表中左边的那个表对应的ScanNode)作为HashJoinNode的左孩子;通过调用Planner.connectChildFragment()函数把HashJoinNode的右孩子设置为一个ExchangeNode(这个ExchangeNode表示一个1:n的数据流的receiver);同时把rightChildFragment(ScanNode作为root node)的destination设置为这个ExchangeNode。
(3)如果是AggregationNode,聚集操作很复杂了。以我们的例子来说明:如果这个AggregationNode不是DISTINCT aggregation的2nd phase(因为本例中的AggregationNode的孩子是HashJoinNode而不是另外一个AggregationNode),首先把刚才生成的HashJoinNode作为root node对应的PlanFragment的root node设置为该AggregationNode,并把原来的root node(即HashJoinNode)设为新root node的孩子。然后通过Planner.createParentFragment()创建一个包含ExchangeNode作为root node的新的PlanFragment。并把孩子PlanFragment的destination设置为这个ExchangeNode。然后在这个新的PlanFragment中创建一个新的AggregationNode作为新的root node并把刚才的ExchangeNode作为其孩子节点。
至此,createPlanFragments()调用完成,生成的三个PlanFragment如下:

通过createPlanFragments(singleNodePlan, isPartitioned, false, fragments)获取了所以执行计划PlanFragment组成的数组fragments,这个数组的最后一个元素就是根节点PlanFragment。然后就是调用PlanFragment.finalize()把这个执行计划finalize(递归finalize每个PlanNode)同时为每个PlanFragment指定 DataStreamSink。
然后回到frontend.createExecRequest()函数中。执行完Planner.createPlanFragments()返回的ArrayList就是完整的执行计划了。然后就是一次调用PlanFragment.toThrift()把它序列化到TQueryExecRequest。填充TQueryExecRequest的相关变量:dest_fragment_idx,per_node_scan_ranges,query_globals,result_set_metadata等。最后返回TExecRequest型的对象给backend执行。

Ⅳ 怎样将一个sql语句转化为相应的语法树

token就是把程序的语句进行类似分词得到的单词。
它是下步语法分析的输入。
typedef struct Token
{
int label;
char name[buf];
int code;
}Token;
是一个结构体。
C语言中单词可以分为
保留字,就是int,while等。
标识符,例如int m;m就是标识符。
数字,有整数和小数
字符,+,-,.,*,;等字符,其中也包括++,--,!=等。
label应该标识token的类型。
name表示的就是程序中对应的字符序列。例如:int等。
最后code的意思,看不出来。。。,不过个人认为,上面的两项就可以表示
token的信息。

Ⅳ spark SQL和hive到底什么关系

第一,Spark SQL在Hive兼容层面仅依赖HQL parser、Hive Metastore和Hive SerDe。也就是说,从HQL被解析成抽象语法树(AST)起,就全部由Spark SQL接管了。执行计划生成和优化都由Catalyst负责。借助Scala的模式匹配等函数式语言特性,利用Catalyst开发执行计划优化策略比Hive要简洁得多。去年Spark summit上Catalyst的作者Michael Armbrust对Catalyst做了一个简要介绍:2013 | Spark Summit。
第二,相对于Shark,由于进一步削减了对Hive的依赖,Spark SQL不再需要自行维护打了patch的Hive分支。Shark后续将全面采用Spark SQL作为引擎,不仅仅是查询优化方面。

Ⅵ mysql中视图功能会节省SQL解析时间吗

如果没有变化(比如插入,删除操作),就会直接调用视图的缓存数据,有变化就会重新查询并刷新缓存。

Ⅶ entity framework中怎么通过lambda表达式生成sql语句的

Set返回的是IQuerable。然后你Where的时候,lambda表达式不是一个函数,而是一个Expression<函数>,C#编译器会把这段代码的语法树在运行时直接交给IQuerable。所以IQuerable自然就知道你Where了,也知道你Where了什么。但是ToList是要给结果的,IQuerable的ToList就会把之前的Where翻译成SQL,然后提交上去,等结果回来了,搞成列表给你。

Ⅷ sql,关系代数~~

数据库关系代数表达式学习
关系代数是关系数据库系统查询语言的理论基础。很有必要学习一下,有些是用代数表达式很方便的东西,用SQL写出来还是挺麻烦的,并不是想象当中那么直接。
种操作:一、关系代数的9种操作:
关系代数中包括了:并、交、差、乘、选择、投影、联接、除、自然联接等操作。
五个基本操作:五个基本操作:并(∪)、差(-)、笛卡尔积(×)、投影(σ)、选择(π)
四个组合操作:四个组合操作:交(∩)、联接(等值联接)、自然联接(RS)、除法(÷)注2:等值连接表示先做笛卡尔积(×)之后,对相应列进行选择或等值关联后的结果(仅筛选行、不筛选列)注2:自然连接表示两个关系中若有相同名称的属性,则自动作为关联条件,且仅列出一列
二、关系代数表达式:关系代数表达式:
由关系代数运算经有限次复合而成的式子称为关系代数表达式。这种表达式的运算结果仍然是一个关系。可以用关系代数表达式表示对数据库的查询和更新操作。
三、举例说明:举例说明:
设教学数据库中有3个关系:
学生关系S(SNO,SNAME,AGE,SEX)学习关系SC(SNO,CNO,GRADE)课程关系C(CNO,CNAME,TEACHER)
(1)检索学习课程号为C2的学生与成绩-----------------------------------SELECTSNO,GRADEFROMSCWHERECNO='C2'------------------------------------
π
SNO,GRADE(σCNO='C2'(SC))
************************************
(2)检索学习课程号为C2的学生与-----------------------------------SELECTSC.SNO,S.SNAMEFROMSC,SWHERESC.SNO=S.SNOANDSC.CNO='C2'-----------------------------------π
SNO,SNAME(σCNO='C2'(S
SC))
此查询涉及S和SC,先进行自然连接,然后再执行选择投影操作。---π
SNO,SNAME(S)
(πSNO(σCNO='C2'(SC)))
自然连接的右分量为"学了C2课的学生的集合"。此表达式比前一个表达式优化,执行起来要省时间、省空间。************************************
(3)检索选修课程名为MATHS的学生与------------------------------------
SELECTSC.SNO,S.SNAMEFROMSC,S,CWHERESC.SNO=S.SNOANDSC.CNO=C.CNOANDC.CNAME='MATHS'-----------------------------------π
SNO,SANME(σCNAME='MATHS'(S
SCC))
************************************
(4)检索选修课程号为C2或C4的学生-----------------------------------SELECTSNOFROMSCWHERECNO='C2'ORCNO='C4'-----------------------------------π
SNO(σCNO='C2'∨CNO='C4'(SC))
************************************
(5)检索至少选修课程号为C2或C4的学生
-----------------------------------SELECTSA.SNOFROMSCASSA,SCASSBWHERESA.SNO=SB.SNOANDSA.CNO='C2'ANDSB.CNO='C4'-----------------------------------π1(σ1=4∧2='C2'∧5='C4'(SC×SC))************************************
(
6)检索不学C2课的学生与年龄-----------------------------------SELECTSNAME,AGEFROMSMINUSSELECTS.SNAME,S.AGEFROMSC,SWHERESC.SNO=S.SNOANDSC.CNO='C2'(Oracle)------------------------------------
π
SNAME,AGE(S)-πSNAME,AGE(σCNO='C2'(S
SC))
************************************
(7)检索学习全部课程的学生-----------------------------------这个定义用SQL表示比较麻烦,略过-----------------------------------π
SNO,CNO(SC)÷πCNO(C)
先用除法取出选取所有课程的SNO集(除法可以理解为一个Filter)π
SNAME(S
(πSNO,CNO(SC)÷πCNO(C)))
再关联S表取出SNAME************************************
(8)检索所学课程包含S3所学课程的学生-----------------------------------这个定义用SQL表示比较麻烦,略过-----------------------------------π
SNO,CNO(SC)÷
πCNO(σSNO='S3'(SC))
同样运用了除法的特性
************************************
(9)将新课程元组将新课程元组('C10','PHYSICS','YU')插入到关系C中插入到关系-----------------------------------INSERTINTOCVALUES('C10','PHYSICS','YU')-----------------------------------(C∪('C10','PHYSICS','YU'))∪记住该符号的用法************************************
(10)将S4选修课程号为C4的成绩改为85分-----------------------------------UPDATESCSETGRADE=85WHERESNO='S4'ANDCNO='C4'-----------------------------------(SC-('S4','C4',?)∪('S4','C4',85))-∪先用'-'实现DELETE功能,再用'∪'实现INSERT功能-注意使用?来表示检索时忽略该字段值************************************
四、关系代数表达式的优化:关系代数表达式的优化:
目的:为了系统在执行时既省时间又能提高效率。目的基本策略:先做选择,运用投影去除多余属性等等。基本策略优化算法:语法树(尽量提前做选择操作;在每个操作后,应做优化算法个投影操作,去掉不用的属性值)
例如:
ππ
SNO,SNAME(σGRADE>60(S
SC))进行优化后转换为:πSNO(σGRADE>60(SC)))
SNO,SNAME(πSNO,SNAME(S)
--即提前做选择操作;在每个操作后,应做个投影操作,去掉
不用的属性值
又如:
S(S#,SNAME,AGE,SEX)SC(S#,C#,GRADE)C(C#,CNAME,TEACHER)
π
CNAME,TEACHER(σSEX='女'(S
SCC))进行优化后转换为:
πCNAME,TEACHER(CπC#(πS#,C#(SC)πS#(σSEX='女'(S))))
优化前和优化后的语法树如下所示:

Ⅸ 如何获取SQL2005下的SQL语句的语义分析

我想获取一段sql语句在 mssql2005下解析成的语句,
主要是想获取这个sql所用到的所有的表的名字。(ps:复杂的sql语句的)
请高手帮忙 在线等~
我的意思是要从用户输入的sql语句中提取该语句中所用的表
或者是:
sql 执行的步骤

1. 解析器

第 1 阶段是解析器阶段,它将 SQL 文本转换成语法树。这个阶段不查找系统目录中的任何信息,不访问数据库。

2. 语义分析

第 2 阶段分析由解析器创建的语法树,并产生用于查询的查询控制块和表达式树。要构建这些内部数据结构,它执行以下操作:

验证对象
解析 UDR
如果可能的话,消除常量
验证对象

第 2 阶段访问数据库中不同的系统目录,以验证查询所引用的所有数据库对象(诸如表、列、视图、类型、UDR 等等)是否都存在。它在数据库中找到这些对象的标识,然后创建查询控制块和表达式树。

我要的就是验证对象步骤里的表的信息

Ⅹ spark sql怎么划分stage

其实sql就是关系操作。关系操作跟map,rece这些基础算子对应起来的(spark其实基础算子也是map,rece,只是在此基础上做了扩展)。比如projection,filter是窄依赖,join,semi join,outer join是宽依赖。
具体流程会比较复杂。首先spark会解析这条sql,生成语法树(spark2.0会通过antlr4解析),然后经过逻辑优化(dataframe中有logic plan),然后转换为map rece,生成对应的操作算子(projection,filter,join等)。有了宽依赖,窄依赖,也就能划分stage了。

热点内容
stm芯片用什么编译器 发布:2025-01-10 19:35:27 浏览:414
易语言qq登陆器源码 发布:2025-01-10 19:35:00 浏览:888
java生成文件 发布:2025-01-10 19:30:35 浏览:31
文件链接上传 发布:2025-01-10 19:30:32 浏览:907
linux安装sqlite 发布:2025-01-10 19:09:43 浏览:83
java工程师证 发布:2025-01-10 18:54:02 浏览:36
python如何判断密码强度 发布:2025-01-10 18:39:58 浏览:984
安卓怎么快捷关程序 发布:2025-01-10 18:35:48 浏览:927
仔细的算法 发布:2025-01-10 18:28:30 浏览:551
c语言判断是否为回文数 发布:2025-01-10 18:21:31 浏览:787