當前位置:首頁 » 編程語言 » 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了。

熱點內容
電腦怎麼看網路密碼 發布:2025-01-10 14:56:40 瀏覽:107
java調用shell腳本參數 發布:2025-01-10 14:43:51 瀏覽:52
php數組計數 發布:2025-01-10 14:23:03 瀏覽:474
s盒演算法 發布:2025-01-10 14:16:42 瀏覽:643
c語言用二分法求方程 發布:2025-01-10 14:15:45 瀏覽:219
廣場舞加密 發布:2025-01-10 14:13:21 瀏覽:520
網路密碼顯示低安全性是什麼意思 發布:2025-01-10 14:11:49 瀏覽:782
恥辱2博士保險箱密碼是多少 發布:2025-01-10 14:11:41 瀏覽:101
如何把伺服器搭在自己電腦 發布:2025-01-10 14:10:57 瀏覽:585
水晶可以存儲 發布:2025-01-10 14:09:35 瀏覽:391