改写SparkSql执行计划
SparkSql开发新的语法支持:
首先需要改动ANTLR4文件(在SqlBase.g4中添加文法),重新生成词法分析器(SqlBaseLexer)、语法分析器(SqlBaseParser)和访问者类(SqlBaseVisitor接口与SqlBaseBaseVisitor类),然后在AstBuilder一系列类中添加访问逻辑,最后添加执行逻辑。
修改ANTLR4文件
添加访问逻辑
扩展包dsql下:
DSQLAstBuilder继承了ANTLR4生成的默认SqlBaseBaseVisitor,用于生成SQL对应的抽象语法树AST(Unresolved LogicalPlan)
DSQLsqlAstBuilder继承了DSQLAstBuilder,并在其基础上添加了DDL的访问操作,主要在DSQLsqlParser中调用。
如:
DSQLSqlParser#visitCreateTableHeader中,调用了DSQLAstBuilder#visitTableIdentifier。
本篇以addDataSource为例:
class DSQLSqlParser(conf: SQLConf) extends AbstractDSQLParser {
/** Get the builder (visitor) which converts a ParseTree into an AST. */
override val astBuilder = new DSQLSqlAstBuilder(conf)
private val substitutor = new VariableSubstitution(conf)
protected override def parse[T](command: String)(toResult: SqlBaseParser => T): T = {
super.parse(substitutor.substitute(command))(toResult)
}
}
DSQLSqlAstBuilder#visitAddDatasource:得到Unresolved LogicalPlan
/**
* Create a [[DSQLAddDatasourceCommand]] logical plan
*/
override def visitAddDatasource(ctx: AddDatasourceContext): LogicalPlan = withOrigin(ctx) {
val properties = visitPropertyKeyValues(ctx.tablePropertyList)
DSQLAddDatasourceCommand(ctx.identifier().getText, properties.updated(TEMP_FLAG, "true"))
}
DSQLSqlAstBuilder#visitPropertyKeyValues;DSQLSqlAstBuilder#visitTablePropertyList等访问方法:
/**
* Parse a key-value map from a [[TablePropertyListContext]], assuming all values are specified.
*/
private def visitPropertyKeyValues(ctx: TablePropertyListContext): Map[String, String] = {
val props = visitTablePropertyList(ctx)
val badKeys = props.collect { case (key, null) => key }
if (badKeys.nonEmpty) {
operationNotAllowed(
s"Values must be specified for key(s): ${badKeys.mkString("[", ",", "]")}",
ctx)
}
props
}
/**
* Convert a table property list into a key-value map.
* This should be called through [[visitPropertyKeyValues]] or [[visitPropertyKeys]].
*/
override def visitTableProper