使用 extraOptimizations 改造 Spark SQL AST

2024-02-22

我想将 SQL 字符串作为用户输入,然后在执行之前对其进行转换。特别是,我想修改顶级投影(select 子句),注入要由查询检索的附加列。

我希望通过使用 Catalyst 来实现这一点sparkSession.experimental.extraOptimizations。我知道我正在尝试的严格来说并不是优化(转换改变了 SQL 语句的语义),但 API 似乎仍然合适。但是,查询执行器似乎忽略了我的转换。

这是一个最小的例子来说明我遇到的问题。首先定义一个行案例类:

case class TestRow(a: Int, b: Int, c: Int)

然后定义一个优化规则,简单地丢弃任何投影:

object RemoveProjectOptimisationRule extends Rule[LogicalPlan] {
    def apply(plan: LogicalPlan): LogicalPlan = plan transformDown {
        case x: Project => x.child
    }
}

现在创建一个数据集,注册优化,并运行 SQL 查询:

// Create a dataset and register table.
val dataset = List(TestRow(1, 2, 3)).toDS()
val tableName: String = "testtable"
dataset.createOrReplaceTempView(tableName)

// Register "optimisation".
sparkSession.experimental.extraOptimizations =  
    Seq(RemoveProjectOptimisationRule)

// Run query.
val projected = sqlContext.sql("SELECT a FROM " + tableName + " WHERE a = 1")

// Print query result and the queryExecution object.
println("Query result:")
projected.collect.foreach(println)
println(projected.queryExecution)

这是输出:

Query result: 
[1]

== Parsed Logical Plan ==
'Project ['a]
+- 'Filter ('a = 1)
   +- 'UnresolvedRelation `testtable`

== Analyzed Logical Plan ==
a: int
Project [a#3]
+- Filter (a#3 = 1)
   +- SubqueryAlias testtable
      +- LocalRelation [a#3, b#4, c#5]

== Optimized Logical Plan ==
Filter (a#3 = 1)
+- LocalRelation [a#3, b#4, c#5]

== Physical Plan ==
*Filter (a#3 = 1)
+- LocalTableScan [a#3, b#4, c#5]

我们看到结果与原始 SQL 语句的结果相同,但未应用转换。然而,在打印逻辑和物理平面图时,投影确实被删除了。我还确认(通过调试日志输出)确实正在调用转换。

关于这里发生的事情有什么建议吗?也许优化器只是忽略了改变语义的“优化”?

如果使用优化不是可行的方法,有人可以建议替代方案吗?我真正想做的就是解析输入的 SQL 语句,对其进行转换,然后将转换后的 AST 传递给 Spark 执行。但据我所知,执行此操作的 API 是 Spark 私有的sql包裹。可能可以使用反射,但我想避免这种情况。

任何指示将不胜感激。


正如您所猜测的,这不起作用,因为我们假设优化器不会更改查询的结果。

具体来说,我们缓存来自分析器的模式(并假设优化器不会更改它)。将行转换为外部格式时,我们使用此模式,因此会截断结果中的列。如果您所做的不仅仅是截断(即更改数据类型),这甚至可能会崩溃。

正如你所看到的这个笔记本 https://databricks-prod-cloudfront.cloud.databricks.com/public/4027ec902e239c93eaaa8714f173bcfc/1023043053387187/3743056197112949/2840265927289860/latest.html,它实际上正在产生您所期望的结果。我们计划在不久的将来的某个时候开放更多挂钩,让您可以在查询执行的其他阶段修改计划。看SPARK-18127 https://issues.apache.org/jira/browse/SPARK-18127更多细节。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 extraOptimizations 改造 Spark SQL AST 的相关文章

随机推荐