calcite查询mysql_使⽤Calcite做Sql语法解析
Flink SQL中使⽤Calcite作为sql语法解析、校验、优化⼯具,本篇是实操篇,介绍⼀下calcite做sql语法解析使⽤⽅式。
sql经过calcite解析之后,得到⼀棵抽象语法树,也就是我们说的AST,这棵语法树是由不同的节点组成,节点称之为SqlNode,根据不同类型的dml、ddl得到不同的类型的SqlNode,例如select语句转换为SqlSelect,delete语句转换为SqlDelete,join语句转换为SqlJoin。
使⽤⽅式:
SqlParser.Config config = figBuilder()
.setLex(Lex.MYSQL) //使⽤mysql 语法
.build();
//SqlParser 语法解析器
SqlParser sqlParser = SqlParser
.
create("select id,name,age FROM stu where age<20", config);
SqlNode sqlNode = null;
try {
sqlNode = sqlParser.parseStmt();
} catch (SqlParseException e) {
throw new RuntimeException("", e);
}
这⾥解析了⼀个select的语句,那么得到的sqlNode就是⼀个SqlSelect。
if(SqlKind.SELECT.Kind())){
SqlSelect sqlSelect = (SqlSelect) sqlNode;
SqlNode From();
SqlNode Where();
SqlNodeList SelectList();
//标识符
if(SqlKind.IDENTIFIER.Kind())){
System.out.String());
}
if(SqlKind.LESS_THAN.Kind())){
SqlBasicCall sqlBasicCall=(SqlBasicCall)where;
for(SqlNode sqlNode1: sqlBasicCall.operands){
if(SqlKind.LITERAL.Kind())){
System.out.String());
}
}
}
if(SqlKind.IDENTIFIER.Kind())){
System.out.String());
}
});
}
⼀个select语句包含from部分、where部分、select部分等,每⼀部分都表⽰⼀个SqlNode。SqlKind是⼀个枚举类型,包含了各种SqlNode类型:SqlSelect、SqlIdentifier、SqlLiteral等。SqlIdentifier表⽰标识符,例如表名称、字段名;SqlLiteral表⽰字⾯常量,⼀些具体的数字、字符。
SqlBasicCall对⽐SqlSelect/SqlDelete⽽⾔,可以理解为表⽰的是⼀些基本的、简单的调⽤,例如聚合函数、⽐较函数等,接下来看⼀下其如何解析sum操作:
select sum(amount) FROM orders //解析的sql
//解析select部分
if(SqlKind.SUM.Kind())){
SqlBasicCall sqlBasicCall=(SqlBasicCall)x;
System.out.println(sqlBasicCall.operands[0]);
}
});
其内部主要就是operands,也是SqlNode节点,但是都是⼀些基本的SqlNode,例如SqlIdentifier、SqlLiteral。
SqlSelect/SqlDelete/SqlBasicCall 都称之为SqlCall,差别是SqlSelect是复杂的SqlCall,内部可以包含其他节点,⽽SqlBasicCall表⽰简单的SqlCall。另外两种SqlNode:SqlDataTypeSpec与SqlNodeList,SqlDataTypeSpec代表数据类型节点,例如
CHAR/VARCHAR/DOUBLE, SqlNodeList表⽰包含多个同级别的SqlNode,在上⾯select中已经展⽰过,看下SqlDataTypeSpec使⽤实例:
select cast(amount as CHAR) FROM orders//解析的sql
//解析select部分
if(SqlKind.CAST.Kind())){
SqlBasicCall sqlBasicCall=(SqlBasicCall)x;
System.out.println(sqlBasicCall.operands[0]); //amount
SqlDataTypeSpec charType=(SqlDataTypeSpec)sqlBasicCall.operands[1];
System.out.TypeName()); //CHAR
}
});
另外⼀种节点SqlOperator,可以代表函数、运算符、语法(select)结构,例如sum解析为SqlAggFunction、select解析为SqlSelectOperator,as 作为SqlAsOperator。SqlOperator是被嵌⼊在SqlNode中,作为其属性,通过SqlOperator的createCall⽅法可以创建对应的SqlNode,使⽤⽅式:
SqlOperator operator = new SqlAsOperator();
SqlParserPos sqlParserPos = new SqlParserPos(1, 1);
SqlIdentifier name = new SqlIdentifier("orders", null, sqlParserPos);
SqlIdentifier alias = new SqlIdentifier("o", null, sqlParserPos);
SqlNode[] sqlNodes = new SqlNode[2];
sqlNodes[0] = name;
sqlNodes[1] = alias;
SqlBasicCall sqlBasicCall = (ateCall(sqlParserPos,sqlNodes);
System.out.println(sqlBasicCall); //得到的就是 Order as o
SqlParsePos表⽰对应解析的节点在sql位置,起⽌⾏与起⽌列。
mysql中delete语句
以上介绍了⼀下calcite解析sql的简单使⽤⽅式,我们可以使⽤Calcite来做⾎缘分析、flink sql维表关联等。
关注回复Flink获取更多信息.jpg

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。