diff --git a/docs/source/user-guide/latest/expressions.md b/docs/source/user-guide/latest/expressions.md index 2ba71e93c4..e744067dd0 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 a0ea76cc06..6cbbade3fa 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,11 @@ object CometUnhex extends CometExpressionSerde[Unhex] with MathExprBase { } } -object CometAbs extends CometExpressionSerde[Abs] with MathExprBase { +object CometAbs extends CometExpressionSerde[Abs] with MathExprBase with CodegenDispatchFallback { - val unsupportedReason: String = "Only integral, floating-point, and decimal types are supported" + val unsupportedReason: String = + "Interval types are not supported natively and are handled via JVM codegen dispatch; " + + "this fallback only applies when the dispatcher is disabled" 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..9eef45f35d 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,25 @@ 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) + +-- abs() on intervals has no native impl; routed through the JVM codegen dispatcher. +-- Interval values are built inline: native Parquet scan of interval columns is unsupported +-- (https://github.com/apache/datafusion-comet/issues/5060), and a top-level YearMonthIntervalType projection column is still rejected by the +-- projection type gate (https://github.com/apache/datafusion-comet/issues/5061), so the ym result is wrapped in a struct. +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 + +-- interval year to month: dispatched the same way; wrapped in a struct because a top-level +-- YearMonthIntervalType column is rejected by the projection output type gate (https://github.com/apache/datafusion-comet/issues/5061) +query +SELECT named_struct('v', abs(make_ym_interval(1, 6))) AS ym_pos, + named_struct('v', abs(make_ym_interval(-1, -6))) AS ym_neg + +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..2ce672df72 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,9 @@ SELECT abs(v) FROM ansi_test_abs_byte -- literal query expect_error(overflow) SELECT abs(cast(-128 as tinyint)) + +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))