有没有办法验证原始spark sql查询的语法?

时间:2018-02-19 11:27:22

标签: scala apache-spark

有没有办法验证raw spark SQL查询的语法?

例如,我想知道是否有任何isValid API调用spark提供?

val query = "select * from table"
if(isValid(query)) {
    sparkSession.sql(query) 
} else {
    log.error("Invalid Syntax")
}

我尝试了以下

val query = "select * morf table" // Invalid query
val parser = spark.sessionState.sqlParser
try{
    parser.parseExpression(query)
} catch (ParseException ex) {
    throw new Exception(ex); //Exception not getting thrown
}
Dataset<>Row df = sparkSession.sql(query) // Exception gets thrown here
df.writeStream.format("console").start()

问题:parser.parseExpression在点击sparkSession.sql之前没有捕获无效语法。换句话说,它在上面的代码中没有帮助。任何原因?我的目标是在将语法错误传递给sparkSession.sql

之前捕获语法错误

3 个答案:

答案 0 :(得分:4)

使用Spark SQL Parser:

val parser = spark.sessionState.sqlParser
parser.parseExpression("select * from table")

答案 1 :(得分:2)

经过无数次研究之后,我找到了一种方法,可以通过阅读一些Spark sql代码来实现。这些代码行可以完成这项工作:

.catch(error => 'send error response to user

请注意,在分析阶段,我们需要进行表解析,列名解析等操作。因此,这基本上是在进行语法和上下文分析

答案 2 :(得分:1)

虽然已经晚了,但可能对其他人有帮助。使用

spark.sessionState.sqlParser

似乎没有什么用,因为即使对于查询字符串为“ Hello World”也没有抱怨

最好使用,

sparkSession.sql(query)

实际验证查询语法。由于spark主要懒惰地工作,因此理想情况下,不应对实际数据集执行任何操作。

  def validateSql(query: String, session: SparkSession): Boolean = {
    try {
      val result1 = session.sql(query)
      println(s"No Syntax Error [$result1] Query [$query]")
      return true;
    } catch {
      case e: Throwable => {
        println(s"Query has syntax error. Error [${e.getMessage}] Query [$query]")
        return false
      }
    }
  }

如果您在Spark日志中查找上述代码,则该内容类似于

19/08/07 11:17:09 INFO SparkSqlParser: Parsing command: select * from XYZ limit 5
19/08/07 11:17:10 INFO CatalystSqlParser: Parsing command: bigint
19/08/07 11:17:10 INFO CatalystSqlParser: Parsing command: bigint
19/08/07 11:17:10 INFO CatalystSqlParser: Parsing command: bigint
19/08/07 11:17:10 INFO CatalystSqlParser: Parsing command: bigint
No Syntax Error [[A: bigint, BC: bigint ... 2 more fields]] Query [select * from XYZ limit 5]

相同的细节可以在SO的另一个问题中找到。 How to validate SQL expression (in user frontend) without executing it?

但是,由于sparkSession.sql(query)需要表元数据来验证表列,所以最好直接指向配置单元存储。以下是通过编程进行相同操作的参考。

How to connect to a Hive metastore programmatically in SparkSQL?

How to create pom.xml for maven using SparkSql and Hive?