Repository navigation
feat: admit every array and map type in Spark-to-Comet conversion #6726
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -33,7 +33,7 @@ import org.apache.spark.sql.comet.execution.arrow.{CometArrowStream, CometNative | |
| import org.apache.spark.sql.comet.util.Utils | ||
| import org.apache.spark.sql.execution.{RowToColumnarTransition, SparkPlan} | ||
| import org.apache.spark.sql.execution.metric.{SQLMetric, SQLMetrics} | ||
| import org.apache.spark.sql.types._ | ||
| import org.apache.spark.sql.types.{CalendarIntervalType, DataType} | ||
| import org.apache.spark.sql.vectorized.ColumnarBatch | ||
|
|
||
| import org.apache.comet.{CometConf, DataTypeSupport} | ||
|
|
@@ -138,13 +138,20 @@ object CometSparkToColumnarExec extends CometSink[SparkPlan] with DataTypeSuppor | |
| CometScanWrapper(nativeOp, CometSparkToColumnarExec(op)) | ||
| } | ||
|
|
||
| /** | ||
| * Declines calendar intervals at any depth. Arrow holds the time part of an interval in | ||
| * nanoseconds, so `IntervalMonthDayNanoWriter` overflows on one of more than about 292 years, | ||
| * which Spark accepts (#5279). | ||
| */ | ||
| override def isTypeSupported( | ||
| dt: DataType, | ||
| name: String, | ||
| fallbackReasons: ListBuffer[String]): Boolean = dt match { | ||
| case ArrayType(StringType, _) => true | ||
| case MapType(StringType, StringType, _) => true | ||
| case _: ArrayType | _: MapType => false | ||
| case CalendarIntervalType => | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [P1] [P1] Preserve Spark-compatible decimal partitioning after collection conversion Removing the collection rejection makes previously correct mixed-shuffle joins silently lose rows. With The existing wide-decimal guard recognizes typed Dataset conversions, and Evidence: Reproduced after a fresh full-reactor JVM compilation on Spark 4.1.3 with the exact-head CI native library. For each i in 0..99, the left row was
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can reproduce this on
So this is #3079. Any native shuffle hashing a wide-decimal key next to a JVM columnar one loses rows. A guard on the conversion paths would not cover the last case, while #6005 and #6548 fix it at the shuffle. This PR does widen what reaches the bug. Array- and map-bearing inputs used to stay on the columnar shuffle on both sides of such a join. @andygrove could this land after #6005 or #6548? Once it's rebased on one of them, a join like sunchao's, with an |
||
| fallbackReasons += s"Unsupported $name of type $dt: Arrow holds the time part of an " + | ||
| "interval in nanoseconds, which overflows past about 292 years " + | ||
| "(https://github.com/apache/datafusion-comet/issues/5279)" | ||
| false | ||
| case _ => super.isTypeSupported(dt, name, fallbackReasons) | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With this case gone, the shared rule admits
CalendarIntervalTypeinside arrays and maps too.IntervalMonthDayNanoWritermultiplies microseconds by 1000 withmultiplyExact. So an interval whose time part is longer than about 292 years fails the task withArithmeticException: long overflow, where Spark returns it. An RDD with anARRAY<INTERVAL>column holdingnew CalendarInterval(1, 2, Long.MaxValue / 10)reproduces it underspark.comet.convert.rdd.enabled=true, and so does a map value. Before this PR those columns fell back.Top-level intervals already had this (#5279), and #6607 rules intervals out of the shuffle-input conversion for the same reason. Could this sink decline
CalendarIntervalTypewith a reason pointing at #5279, at least inside arrays and maps?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sink now declines
CalendarIntervalTypewith a reason that links #5279. I made it decline at every level rather than only inside arrays and maps, because the shared rule's recursion calls this sameisTypeSupportedand the writer overflows on a top-level interval too. Onmain, the top-level case of the new test fails with the samelong overflow. It also matches what #6607 does for the shuffle-input conversion. The cost is that a top-level interval column from an RDD, a cache or a typed Dataset now keeps the operators above it on Spark, but each of those conversions is opt-in.SparkToColumnar leaves calendar intervals to Sparkruns your repro as a top-level value, an array element and a map value, and checks Spark's answer with no conversion in the plan.