This is an automated email from the ASF dual-hosted git repository.
andygrove pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion-comet.git
The following commit(s) were added to refs/heads/main by this push:
new 04f744475f feat: route `abs` on interval types through the codegen
dispatcher (#5622)
04f744475f is described below
commit 04f744475fd337ab84c5e57aa6fd7a97fdee1d60
Author: Kazantsev Maksim <[email protected]>
AuthorDate: Thu Sep 10 01:08:20 2026 +0400
feat: route `abs` on interval types through the codegen dispatcher (#5622)
* impl map_from_entries
* Revert "impl map_from_entries"
This reverts commit 768b3e90f261c7aea58bdb98dc698b90deeeae34.
* work
* address comments
* address comments
* address comments
* address comments
* address comments
---------
Co-authored-by: Kazantsev Maksim <[email protected]>
---
docs/source/user-guide/latest/expressions.md | 2 +-
.../main/scala/org/apache/comet/serde/math.scala | 10 ++++-
.../resources/sql-tests/expressions/math/abs.sql | 44 ++++++++++++++++++++++
.../sql-tests/expressions/math/abs_ansi.sql | 12 ++++++
.../expressions/math/abs_ansi_spark42.sql | 12 ++++++
5 files changed, 77 insertions(+), 3 deletions(-)
diff --git a/docs/source/user-guide/latest/expressions.md
b/docs/source/user-guide/latest/expressions.md
index 01d898cd46..b3c8e1334c 100644
--- a/docs/source/user-guide/latest/expressions.md
+++ b/docs/source/user-guide/latest/expressions.md
@@ -418,7 +418,7 @@ The type-name conversion functions (`bigint`, `binary`,
`boolean`, `date`, `deci
| `+` | ✅ | Native | |
| `-` | ✅ | Native | |
| `/` | ✅ | Native | |
-| `abs` | ✅ | Native | Interval types fall back |
+| `abs` | ✅ | Hybrid | Interval types route through the JVM codegen
dispatcher; numeric types run natively |
| `acos` | ✅ | Native | |
| `acosh` | ✅ | Native | |
| `asin` | ✅ | Native | |
diff --git a/spark/src/main/scala/org/apache/comet/serde/math.scala
b/spark/src/main/scala/org/apache/comet/serde/math.scala
index 65e2bf673e..e9f957b20c 100644
--- a/spark/src/main/scala/org/apache/comet/serde/math.scala
+++ b/spark/src/main/scala/org/apache/comet/serde/math.scala
@@ -169,9 +169,15 @@ object CometUnhex extends CometExpressionSerde[Unhex] with
MathExprBase {
}
}
-object CometAbs extends CometExpressionSerde[Abs] with MathExprBase {
+/**
+ * `abs` lowers to the native `abs` kernel for numeric inputs. Interval inputs
have no native
+ * implementation, so `CodegenDispatchFallback` keeps them in the Comet
pipeline by running
+ * Spark's own `Abs.doGenCode` in the JVM codegen dispatcher, which matches
Spark exactly.
+ */
+object CometAbs extends CometExpressionSerde[Abs] with MathExprBase with
CodegenDispatchFallback {
- val unsupportedReason: String = "Only integral, floating-point, and decimal
types are supported"
+ private val unsupportedReason: String =
+ "`INTERVAL YEAR TO MONTH` and `INTERVAL DAY TO SECOND` inputs"
override def getUnsupportedReasons(): Seq[String] = Seq(unsupportedReason)
diff --git a/spark/src/test/resources/sql-tests/expressions/math/abs.sql
b/spark/src/test/resources/sql-tests/expressions/math/abs.sql
index 5e811e7ea5..ff28bfd3e9 100644
--- a/spark/src/test/resources/sql-tests/expressions/math/abs.sql
+++ b/spark/src/test/resources/sql-tests/expressions/math/abs.sql
@@ -27,3 +27,47 @@ SELECT abs(i), abs(l), abs(f), abs(d) FROM test_abs
-- literal arguments
query
SELECT abs(-5), abs(-1.5), abs(0), abs(NULL)
+
+query
+SELECT abs(make_dt_interval(1, 2, 3, 4.5)) AS dt_pos,
+ abs(make_dt_interval(-1, -2, -3, -4.5)) AS dt_neg,
+ abs(make_dt_interval(0, 0, 0, 0)) AS dt_zero,
+ abs(CAST(NULL AS INTERVAL DAY TO SECOND)) AS dt_null
+
+-- intervals derived from numeric Parquet columns: exercises per-row dispatch,
the null mask,
+-- and mixed-sign components (#5060 blocks reading interval columns directly)
+statement
+CREATE TABLE test_abs_iv(d int, h int, m int, s decimal(8,6)) USING parquet
+
+statement
+INSERT INTO test_abs_iv VALUES (1, 2, 3, 4.5), (-1, -2, -3, -4.5), (0, 0, 0,
0), (NULL, 0, 0, 0), (5, -1, 30, -0.000001)
+
+query
+SELECT abs(make_dt_interval(d, h, m, s)) FROM test_abs_iv ORDER BY d
+
+-- mid-batch overflow: one Long.MinValue-microseconds row among valid rows
must throw the same
+-- error Spark does, not silently produce a value
+statement
+CREATE TABLE test_abs_iv_overflow(d int, h int, m int, s decimal(8,6)) USING
parquet
+
+statement
+INSERT INTO test_abs_iv_overflow VALUES (1, 2, 3, 4.5), (-106751991, -4, 0,
-54.775808), (2, 0, 0, 0)
+
+query expect_error(overflow)
+SELECT abs(make_dt_interval(d, h, m, s)) FROM test_abs_iv_overflow
+
+-- pinned fallback: NullPropagation folds the ym null into a bare typed
literal that CometLiteral
+-- does not admit (it special-cases only DayTimeIntervalType,
literals.scala:63), so the whole
+-- projection falls back. Pre-existing gap (#5061); this flips to a failure
when it is fixed.
+query expect_fallback(Unsupported data type YearMonthIntervalType)
+SELECT abs(CAST(NULL AS INTERVAL YEAR TO MONTH))
+
+query
+SELECT abs(make_ym_interval(1, 6)),
+ abs(make_ym_interval(-1, -6))
+
+query expect_error(overflow)
+SELECT abs(make_dt_interval(-106751991, -4, 0, -54.775808))
+
+query expect_error(overflow)
+SELECT abs(make_ym_interval(0, -2147483648))
diff --git a/spark/src/test/resources/sql-tests/expressions/math/abs_ansi.sql
b/spark/src/test/resources/sql-tests/expressions/math/abs_ansi.sql
index 879b24f3f6..0d6b909b41 100644
--- a/spark/src/test/resources/sql-tests/expressions/math/abs_ansi.sql
+++ b/spark/src/test/resources/sql-tests/expressions/math/abs_ansi.sql
@@ -104,3 +104,15 @@ SELECT abs(v) FROM ansi_test_abs_byte
-- literal
query expect_error(overflow)
SELECT abs(cast(-128 as tinyint))
+
+-- valid nearby interval query: asserts the dispatched path actually executes
and produces a
+-- representable result in ANSI mode
+query
+SELECT abs(make_dt_interval(-106751991, -4, 0, -54.775807)),
+ abs(make_ym_interval(0, -2147483647))
+
+query expect_error(overflow)
+SELECT abs(make_dt_interval(-106751991, -4, 0, -54.775808))
+
+query expect_error(overflow)
+SELECT abs(make_ym_interval(0, -2147483648))
diff --git
a/spark/src/test/resources/sql-tests/expressions/math/abs_ansi_spark42.sql
b/spark/src/test/resources/sql-tests/expressions/math/abs_ansi_spark42.sql
index 6e8ec50094..a462a1b352 100644
--- a/spark/src/test/resources/sql-tests/expressions/math/abs_ansi_spark42.sql
+++ b/spark/src/test/resources/sql-tests/expressions/math/abs_ansi_spark42.sql
@@ -101,3 +101,15 @@ SELECT abs(v) FROM ansi_test_abs_byte
-- literal
query expect_error(overflow)
SELECT abs(cast(-128 as tinyint))
+
+-- interval abs negates with MathUtils.negateExact unconditionally in Spark's
codegen, so overflow
+-- behavior is identical in both ANSI modes; mirrored from abs_ansi.sql
(capped at 4.1)
+query
+SELECT abs(make_dt_interval(-106751991, -4, 0, -54.775807)),
+ abs(make_ym_interval(0, -2147483647))
+
+query expect_error(overflow)
+SELECT abs(make_dt_interval(-106751991, -4, 0, -54.775808))
+
+query expect_error(overflow)
+SELECT abs(make_ym_interval(0, -2147483648))
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]