栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 其他 > Spark

扩展 Spark SQL 解析,你知道吗?

Spark 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

 

大家好久不见了,最近生活发生了很多变故,同时我也大病了一场,希望一切都尽快好起来吧。今天跟大家分享下Spark吧,谈谈如何修改Spark SQL解析,让其更符合你的业务逻辑。好,我们开始吧...

理论基础

ANTLR

Antlr4是一款开源的语法分析器生成工具,能够根据语法规则文件生成对应的语法分析器。现在很多流行的应用和开源项目里都有使用,比如Hadoop、Hive以及Spark等都在使用ANTLR来做语法分析。

ANTLR 语法识别一般分为二个阶段:

1.词法分析阶段 (lexical analysis)

对应的分析程序叫做 lexer ,负责将符号(token)分组成符号类(token class or token type)

2.解析阶段

根据词法,构建出一棵分析树(parse tree)或叫语法树(syntax tree)



 

ANTLR的语法文件,非常像电路图,从入口到出口,每个Token就像电阻,连接线就是短路点。



 

语法文件(*.g4)

上面截图对应的语法文件片段,定义了两部分语法,一部分是显示表达式和赋值,另外一部分是运算和表达式定义。

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

接下来,加上定义词法部分,就能形成完整的语法文件。

完整语法文件:

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

Spark的语法文件,在sql下的catalyst模块里,如下图:



 

扩展语法定义

一条正常SQL,例如 Select t.id,t.name from t , 现在我们为其添加一个 JACKY表达式,令其出现在 Select 后面 ,形成一条语句

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

我们先看一下正常的语法规则:



 

现在我们添加一个 jackyexpression



 

jackexpression 本身的规则就是 JACKY加上括号包裹的一个数字



 

将 JACKY 添加为token



 

修改语法文件 如下:

  1. jackyexpression   : JACKY'(' number ')' 
  2.   //expression   ; 
  3.  namedexpression 
  4.   : expression (AS? (identifier | identifierList))?   ; 
  5.  namedexpressionSeq 
  6.   : namedexpression (',' namedexpression | jackyexpression )*   ; 
扩展逻辑计划

经过上面的修改,就可以测试语法规则,是不是符合预期了,下面是一颗解析树,我们可以看到jackyexpression已经可以正常解析了。



 

Spark 执行流程

这里引用一张经典的Spark SQL架构图



 

我们输入的 SQL语句 首先被解析成 Unresolved Logical Pan ,对应的是



 

给逻辑计划添加遍历方法:

  1.  override def visitJackyexpression(ctx: JackyexpressionContext): String = withOrigin(ctx) {    println("this is astbuilder jacky = "+ctx.number().getText) 
  2.     this.jacky = ctx.number().getText.toInt 
  3.     ctx.number().getText 

再处理namedexpression的时候,添加jackyexpression处理

  1. // expressions.    val expressions = Option(namedexpressionSeq).toSeq 
  2.     .flatMap(_.namedexpression.asScala)     .map(typedVisit[expression]) 
  3.   
  4. //jackyexpression 处理    if(namedexpressionSeq().jackyexpression()!=null && namedexpressionSeq().jackyexpression().size() > 0){ 
  5.      visitJackyexpression(namedexpressionSeq().jackyexpression().get(0))   } 

好了,到这里从逻辑计划处理就完成了,有了逻辑计划,就可以在后续物理计划中添加相应的处理逻辑就可以了(还没研究明白... Orz)。

测试

测试用例

  1. public class Case4 {    public static void main(String[] args) { 
  2.        CharStream ca = CharStreams.fromString("SELECt `b`.`id`,`b`.`class` JACKY(2) FROM `b` LIMIT 10");        SqlbaseLexer lexer = new SqlbaseLexer(ca); 
  3.        SqlbaseParser sqlbaseParser = new SqlbaseParser(new CommonTokenStream(lexer));        ParseTree parseTree = sqlbaseParser.singleStatement(); 
  4.         AstBuilder astBuilder = new AstBuilder(); 
  5.        astBuilder.visit(parseTree);        System.out.println(parseTree.toStringTree(sqlbaseParser)); 
  6.        System.out.println(astBuilder.jacky());   } 

执行结果



本文转载自微信公众号「麒思妙想」,可以通过以下二维码关注。转载本文请联系麒思妙想公众号。



 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/796565.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号