成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

擴(kuò)展 Spark SQL 解析,你知道嗎?

運(yùn)維 數(shù)據(jù)庫運(yùn)維 Spark
大家好久不見了,最近生活發(fā)生了很多變故,同時我也大病了一場,希望一切都盡快好起來吧。今天跟大家分享下Spark吧,談?wù)勅绾涡薷腟park SQL解析,讓其更符合你的業(yè)務(wù)邏輯。好,我們開始吧...

 [[394525]]

大家好久不見了,最近生活發(fā)生了很多變故,同時我也大病了一場,希望一切都盡快好起來吧。今天跟大家分享下Spark吧,談?wù)勅绾涡薷腟park SQL解析,讓其更符合你的業(yè)務(wù)邏輯。好,我們開始吧...

理論基礎(chǔ)

ANTLR

Antlr4是一款開源的語法分析器生成工具,能夠根據(jù)語法規(guī)則文件生成對應(yīng)的語法分析器。現(xiàn)在很多流行的應(yīng)用和開源項目里都有使用,比如Hadoop、Hive以及Spark等都在使用ANTLR來做語法分析。

ANTLR 語法識別一般分為二個階段:

1.詞法分析階段 (lexical analysis)

對應(yīng)的分析程序叫做 lexer ,負(fù)責(zé)將符號(token)分組成符號類(token class or token type)

2.解析階段

根據(jù)詞法,構(gòu)建出一棵分析樹(parse tree)或叫語法樹(syntax tree)

 

ANTLR的語法文件,非常像電路圖,從入口到出口,每個Token就像電阻,連接線就是短路點(diǎn)。

 

語法文件(*.g4)

上面截圖對應(yīng)的語法文件片段,定義了兩部分語法,一部分是顯示表達(dá)式和賦值,另外一部分是運(yùn)算和表達(dá)式定義。

  1. stat:   expr NEWLINE               # printExpr 
  2.   |   ID '=' expr NEWLINE         # assign 
  3.   |   NEWLINE                     # blank 
  4.   ; 
  5.  
  6. expr:   expr op=('*'|'/') expr     # MulDiv 
  7.   |   expr op=('+'|'-') expr     # AddSub 
  8.   |   INT                         # int 
  9.   |   ID                         # id 
  10.   |   '(' expr ')'               # parens 
  11.   ; 

接下來,加上定義詞法部分,就能形成完整的語法文件。

完整語法文件:

  1. grammar LabeledExpr; // rename to distinguish from Expr.g4 
  2.  
  3. prog:   stat+ ; 
  4.  
  5. stat:   expr NEWLINE               # printExpr 
  6.   |   ID '=' expr NEWLINE         # assign 
  7.   |   NEWLINE                     # blank 
  8.   ; 
  9.  
  10. expr:   expr op=('*'|'/') expr     # MulDiv 
  11.   |   expr op=('+'|'-') expr     # AddSub 
  12.   |   INT                         # int 
  13.   |   ID                         # id 
  14.   |   '(' expr ')'               # parens 
  15.   ; 
  16.  
  17. MUL :   '*' ; // assigns token name to '*' used above in grammar 
  18. DIV :   '/' ; 
  19. ADD :   '+' ; 
  20. SUB :   '-' ; 
  21. ID :   [a-zA-Z]+ ;     // match identifiers 
  22. INT :   [0-9]+ ;         // match integers 
  23. NEWLINE:'\r''\n' ;     // return newlines to parser (is end-statement signal) 
  24. WS :   [ \t]+ -> skip ; // toss out whitespace 

SqlBase.g4

Spark的語法文件,在sql下的catalyst模塊里,如下圖:

 

擴(kuò)展語法定義

一條正常SQL,例如 Select t.id,t.name from t , 現(xiàn)在我們?yōu)槠涮砑右粋€ JACKY表達(dá)式,令其出現(xiàn)在 Select 后面 ,形成一條語句

  1. Select t.id,t.name JACKY(2) from t 

我們先看一下正常的語法規(guī)則:

 

現(xiàn)在我們添加一個 jackyExpression

 

jackExpression 本身的規(guī)則就是 JACKY加上括號包裹的一個數(shù)字

 

將 JACKY 添加為token

 

修改語法文件 如下:

  1. jackyExpression 
  2.   : JACKY'(' number ')' 
  3.   //expression 
  4.   ; 
  5.  
  6. namedExpression 
  7.   : expression (AS? (identifier | identifierList))? 
  8.   ; 
  9.  
  10. namedExpressionSeq 
  11.   : namedExpression (',' namedExpression | jackyExpression )* 
  12.   ; 

擴(kuò)展邏輯計劃

經(jīng)過上面的修改,就可以測試語法規(guī)則,是不是符合預(yù)期了,下面是一顆解析樹,我們可以看到j(luò)ackyExpression已經(jīng)可以正常解析了。

 

Spark 執(zhí)行流程

這里引用一張經(jīng)典的Spark SQL架構(gòu)圖

 

我們輸入的 SQL語句 首先被解析成 Unresolved Logical Pan ,對應(yīng)的是

 

給邏輯計劃添加遍歷方法:

  1.  override def visitJackyExpression(ctx: JackyExpressionContext): String = withOrigin(ctx) { 
  2.    println("this is astbuilder jacky = "+ctx.number().getText) 
  3.  
  4.    this.jacky = ctx.number().getText.toInt 
  5.  
  6.    ctx.number().getText 

再處理namedExpression的時候,添加jackyExpression處理

  1. // Expressions. 
  2.    val expressions = Option(namedExpressionSeq).toSeq 
  3.     .flatMap(_.namedExpression.asScala) 
  4.     .map(typedVisit[Expression]) 
  5.  
  6.  
  7. //jackyExpression 處理 
  8.    if(namedExpressionSeq().jackyExpression()!=null && namedExpressionSeq().jackyExpression().size() > 0){ 
  9.      visitJackyExpression(namedExpressionSeq().jackyExpression().get(0)) 
  10.   } 

好了,到這里從邏輯計劃處理就完成了,有了邏輯計劃,就可以在后續(xù)物理計劃中添加相應(yīng)的處理邏輯就可以了(還沒研究明白... Orz)。

測試

測試用例

  1. public class Case4 { 
  2.    public static void main(String[] args) { 
  3.        CharStream ca = CharStreams.fromString("SELECT `b`.`id`,`b`.`class` JACKY(2) FROM `b` LIMIT 10"); 
  4.        SqlBaseLexer lexer = new SqlBaseLexer(ca); 
  5.        SqlBaseParser sqlBaseParser = new SqlBaseParser(new CommonTokenStream(lexer)); 
  6.        ParseTree parseTree = sqlBaseParser.singleStatement(); 
  7.  
  8.        AstBuilder astBuilder = new AstBuilder(); 
  9.        astBuilder.visit(parseTree); 
  10.        System.out.println(parseTree.toStringTree(sqlBaseParser)); 
  11.        System.out.println(astBuilder.jacky()); 
  12.   } 

執(zhí)行結(jié)果

本文轉(zhuǎn)載自微信公眾號「麒思妙想」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系麒思妙想公眾號。

 

責(zé)任編輯:武曉燕 來源: 麒思妙想
相關(guān)推薦

2023-03-06 16:38:30

SQL數(shù)據(jù)庫

2023-12-20 08:23:53

NIO組件非阻塞

2024-04-30 09:02:48

2023-12-12 08:41:01

2023-04-26 10:21:04

2022-12-01 08:09:05

SQLOracleSPM

2024-05-28 09:12:10

2024-04-07 00:00:00

ESlint命令變量

2024-01-09 07:29:05

Argo代碼庫應(yīng)用程序

2020-10-28 11:20:55

vue項目技

2019-12-12 09:23:29

Hello World操作系統(tǒng)函數(shù)庫

2017-10-16 13:45:04

2024-07-30 08:22:47

API前端網(wǎng)關(guān)

2022-05-27 08:55:15

工具自動化軟件

2022-03-10 08:25:27

JavaScrip變量作用域

2024-08-20 08:29:55

2022-06-24 08:20:04

CAP網(wǎng)絡(luò)通信

2021-02-02 08:21:28

網(wǎng)絡(luò)面試通信

2024-04-07 00:00:03

2021-02-20 08:21:18

Hive動態(tài)分區(qū)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 中文字幕精品一区二区三区精品 | 久久精品小视频 | 国产三级| 岛国av免费观看 | 福利二区 | 久久久久久综合 | 日韩成人专区 | 国产一级电影在线 | 久久久精品一区 | 日本不卡免费新一二三区 | 国产精品99久久久久久人 | 国产精品久久久久久久久久软件 | 欧美日韩亚洲一区 | 欧美视频在线观看 | 亚洲一区二区三区免费在线观看 | 日本高清视频在线播放 | 一区二视频| 91视频精选 | 亚洲精品一区二区三区蜜桃久 | 国产精品69毛片高清亚洲 | 成人免费观看男女羞羞视频 | 亚洲欧美精品在线 | 成人黄色a| 精品久久久久国产免费第一页 | 国产视频2021 | 成人看片在线观看 | 色999视频| 91.xxx.高清在线 | 久久这里只有精品首页 | 亚洲欧美激情精品一区二区 | 国产精品久久久久久久久免费相片 | 欧美精品一区二区三区四区五区 | 91在线视频一区 | 国产资源一区二区三区 | 高清视频一区二区三区 | 亚洲欧美中文日韩在线 | 99国产视频 | 在线观看中文字幕一区二区 | 亚洲精品成人av | 欧美一区二区三区日韩 | 一区二区三区精品视频 |