Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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 @@ -297,6 +297,22 @@ object ColumnarPartialProjectExec {
HiveUDFTransformer.isHiveUDF(h) && !VeloxHiveUDFTransformer.isSupportedHiveUDF(h)
}

/**
* Returns true for generic catalyst expressions that Velox cannot offload and should be pulled
* into ColumnarPartialProject, excluding ScalaUDF/HiveUDF and non-row-evaluable wrappers.
*/
private def isUnmappedGlutenExpr(expr: Expression): Boolean = expr match {
case _: ScalaUDF => false
case _ if HiveUDFTransformer.isHiveUDF(expr) => false
case _: Literal | _: AttributeReference | _: BoundReference => false
case _: NamedExpression => false
case _ =>
expr.deterministic &&
!expr.isInstanceOf[Unevaluable] &&
!expr.isInstanceOf[LambdaFunction] &&
!ExpressionMappings.expressionsMap.contains(expr.getClass)
}

private def isBlacklistExpression(e: Expression): Boolean = {
ExpressionMappings.blacklistExpressionMap.contains(e.getClass)
}
Expand All @@ -307,6 +323,7 @@ object ColumnarPartialProjectExec {
case _: ScalaUDF => true
case h if containsUnsupportedHiveUDF(h) => true
case e if isBlacklistExpression(e) => true
case e if isUnmappedGlutenExpr(e) => true
case p => p.children.exists(c => containsUDFOrBlacklistExpression(c))
}
}
Expand Down Expand Up @@ -339,6 +356,8 @@ object ColumnarPartialProjectExec {
replaceByAlias(h, replacedAlias)
case e if isBlacklistExpression(e) =>
replaceByAlias(e, replacedAlias)
case e if isUnmappedGlutenExpr(e) =>
replaceByAlias(e, replacedAlias)
case au @ Alias(_: ScalaUDF, _) =>
val replaceIndex = replacedAlias.indexWhere(r => r.exprId == au.exprId)
if (replaceIndex == -1) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,31 @@ import org.apache.gluten.config.GlutenConfig
import org.apache.gluten.execution.{ColumnarPartialProjectExec, WholeStageTransformerSuite}

import org.apache.spark.SparkConf
import org.apache.spark.sql.catalyst.FunctionIdentifier
import org.apache.spark.sql.catalyst.expressions.{Expression, ExpressionInfo, UnaryExpression}
import org.apache.spark.sql.catalyst.expressions.codegen.CodegenFallback
import org.apache.spark.sql.catalyst.optimizer.{ConstantFolding, NullPropagation}
import org.apache.spark.sql.execution.ProjectExec
import org.apache.spark.sql.functions.udf
import org.apache.spark.sql.types.{BooleanType, DataType}

import java.io.File

case class MyStruct(a: Long, b: Array[Long])

case class MyStructWithNullValue(a: Option[Long], b: Array[Long])

case class DummyUnmappedExpr(child: Expression) extends UnaryExpression with CodegenFallback {
override def dataType: DataType = BooleanType

override protected def nullSafeEval(input: Any): Any = {
input.asInstanceOf[Long] % 2 == 0
}

override protected def withNewChildInternal(newChild: Expression): DummyUnmappedExpr =
copy(child = newChild)
}

class UDFPartialProjectSuite extends WholeStageTransformerSuite {
disableFallbackCheck
override protected val resourcePath: String = "/tpch-data-parquet"
Expand Down Expand Up @@ -64,9 +79,22 @@ class UDFPartialProjectSuite extends WholeStageTransformerSuite {
spark.udf.register("no_argument", noArgument)
val concat = udf((x: String) => x + "_concat")
spark.udf.register("concat_concat", concat)
spark.sessionState.functionRegistry.registerFunction(
FunctionIdentifier("dummy_unmapped"),
new ExpressionInfo(classOf[DummyUnmappedExpr].getName, "dummy_unmapped"),
(children: Seq[Expression]) => DummyUnmappedExpr(children.head)
)

}

test("fallback generic unmapped expression via partial project") {
runQueryAndCompare(
"SELECT sum(cast(dummy_unmapped(cast(l_orderkey as long)) as int)" +
" + hash(l_partkey)) from lineitem") {
checkGlutenPlan[ColumnarPartialProjectExec]
}
}

ignore("test plus_one") {
runQueryAndCompare("SELECT sum(plus_one(cast(l_orderkey as long))) from lineitem") {
checkGlutenPlan[ColumnarPartialProjectExec]
Expand Down
Loading