Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
*/
package org.apache.gluten.extension

import org.apache.gluten.config.GlutenConfig

import org.apache.spark.sql.catalyst.rules.{Rule, RuleExecutor}
import org.apache.spark.sql.execution.{GenerateExec, ProjectExec, SparkPlan}
import org.apache.spark.sql.internal.SQLConf
Expand All @@ -37,8 +39,9 @@ case class PartialFallbackRules() extends Rule[SparkPlan] {
}

object PartialFallback {
def supportPartialFallback(plan: SparkPlan): Boolean = {
plan.isInstanceOf[ProjectExec] ||
plan.isInstanceOf[GenerateExec]
def supportPartialFallback(plan: SparkPlan): Boolean = plan match {
case _: ProjectExec => GlutenConfig.get.enableColumnarPartialProject

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed the following code already performs this check before PartialFallback.supportPartialFallback is called. Is this a duplicate?

if (!GlutenConfig.get.enableColumnarPartialProject) {

@zml1206 zml1206 Apr 27, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is to handle situations where the parent and child are different; one is ProjectExec, and the other is GenerateExec.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant the check for config. Am I missing something?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rule-level check only controls whether that specific rule runs. supportPartialFallback is used when checking whether a parent SparkPlan can be used as a partial-fallback boundary by another rule.

In nested cases, PartialGenerateRule may inspect a ProjectExec parent, and PartialProjectRule may inspect a GenerateExec parent. Without checking the corresponding config in supportPartialFallback, a disabled partial fallback type can still be considered a supported boundary indirectly.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. It's cross referenced. Thanks.

case _: GenerateExec => GlutenConfig.get.enableColumnarPartialGenerate

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

case _ => false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -162,14 +162,28 @@ class GlutenHiveUDFSuite extends GlutenQueryComparisonTest with SQLTestUtils {
val plusOne = udf((x: Long) => x + 1)
spark.udf.register("plus_one", plusOne)
sql(s"CREATE TEMPORARY FUNCTION noInputUDTF AS '${classOf[NoInputUDTF].getName}'")
runQueryAndCompare("""
|select plus_one(col1) as col2, l_partkey from (
| select col1, l_partkey from lineitem lateral view noInputUDTF() as col1
|)""".stripMargin) {
df =>
{
checkOperatorMatch[ColumnarPartialProjectExec](df)
checkOperatorMatch[ColumnarPartialGenerateExec](df)

Seq(true, false).foreach {
enablePartialProject =>
withSQLConf(
SQLConf.ANSI_ENABLED.key -> "false",
GlutenConfig.ENABLE_COLUMNAR_PARTIAL_PROJECT.key -> enablePartialProject.toString) {
runQueryAndCompare(
"""
|select plus_one(col1) as col2, l_partkey from (
| select col1, l_partkey from lineitem lateral view noInputUDTF() as col1
|)""".stripMargin,
noFallBack = enablePartialProject
) {
df =>
val executedPlan = getExecutedPlan(df)
assert(
executedPlan.exists(_.isInstanceOf[ColumnarPartialProjectExec]) ==
enablePartialProject)
assert(
executedPlan.exists(_.isInstanceOf[ColumnarPartialGenerateExec]) ==

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we also test the case that ENABLE_COLUMNAR_PARTIAL_GENERATE is disabled?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

enablePartialProject)
}
}
}
}
Expand Down
Loading