sunchao commented on code in PR #5614:
URL: https://github.com/apache/datafusion-comet/pull/5614#discussion_r3910237757


##########
spark/src/main/scala/org/apache/comet/serde/arrays.scala:
##########
@@ -924,4 +924,38 @@ object CometArraySort extends 
CometCodegenDispatch[ArraySort]
 
 object CometZipWith extends CometCodegenDispatch[ZipWith]
 
-object CometSequence extends CometCodegenDispatch[Sequence]
+object CometSequence extends CometExpressionSerde[Sequence] with 
CodegenDispatchFallback {
+
+  private val temporalUnsupportedReason =
+    "date and timestamp element types run through the JVM codegen dispatcher"
+
+  override def getSupportLevel(expr: Sequence): SupportLevel = 
expr.start.dataType match {
+    case ByteType | ShortType | IntegerType | LongType => Compatible()
+    case DateType | TimestampType | TimestampNTZType =>
+      // Temporal sequences step through timezone/DST/legacy-calendar 
arithmetic
+      // (https://github.com/apache/datafusion-comet/issues/5349), so they 
stay on the JVM
+      // codegen dispatcher.
+      Unsupported(Some(temporalUnsupportedReason))
+    case other =>
+      Unsupported(Some(s"sequence with element type $other is not supported 
natively"))
+  }
+
+  override def getUnsupportedReasons(): Seq[String] = 
Seq(temporalUnsupportedReason)
+
+  override def convert(
+      expr: Sequence,
+      inputs: Seq[Attribute],
+      binding: Boolean): Option[ExprOuterClass.Expr] = {
+    val startExprProto = exprToProto(expr.start, inputs, binding)
+    val stopExprProto = exprToProto(expr.stop, inputs, binding)
+    // With no step argument the native kernel computes Spark's per-row 
default,
+    // `start <= stop ? 1 : -1`, which cannot be expressed as a plan-time 
literal.
+    val argProtos = Seq(startExprProto, stopExprProto) ++
+      expr.stepOpt.map(exprToProto(_, inputs, binding))
+    scalarFunctionExprToProtoWithReturnType(

Review Comment:
   [P2] Preserve null short-circuiting before evaluating later arguments
   
   Could this lowering preserve `Sequence`'s left-to-right null guards? For a 
Parquet table `t(s INT, k INT)` containing `(NULL, -1)` and `(1, 1)`, consider 
`SELECT sequence(s, size(sequence(1, 5, k))) FROM t`. Spark returns `NULL` for 
the first row without evaluating the inner sequence, and `[1,2,3,4,5]` for the 
second. Here both sequences become scalar UDFs, whose arguments DataFusion 
evaluates over the batch before calling the outer kernel. The inner 
`sequence(1, 5, -1)` therefore throws before the outer `row_is_null` check can 
discard that row. The previous dispatcher kept the whole expression tree inside 
Spark's guarded evaluation. Could we retain those guards or dispatch such 
shapes, and add a composed null/error regression case?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to