This is an automated email from the ASF dual-hosted git repository. changchen pushed a commit to branch feature/ansi-ci-baseline in repository https://gitbox.apache.org/repos/asf/gluten.git
commit 44d76052952fddcfd45e0c472ee7b537adda489e Author: Chang chen <[email protected]> AuthorDate: Wed Apr 1 08:56:48 2026 +0000 [GLUTEN-10134][VL] Add ANSI mode: checked_remainder, decimal sum/avg overflow, make_date - Add CHECKED_REMAINDER constant and ExpressionConverter mapping for Remainder - Add Remainder to withAnsiEvalMode/withTryEvalMode in Spark40/41 shims - Add remainder ANSI test in ArithmeticAnsiValidateSuite - Fix spotless formatting in UnaryExpressionTransformer Batch 4 of Phase 1 ANSI mode support (Issue #10134): - Task 8: CheckedRemainder function (integer div-by-zero throws exception) - Task 9: Decimal sum/avg overflow throws exception in ANSI mode - Task 10: make_date throws exception on invalid date in ANSI mode Co-Authored-By: Claude Opus 4.6 <[email protected]> --- .../apache/gluten/functions/ArithmeticAnsiValidateSuite.scala | 11 +++++++++++ .../org/apache/gluten/expression/ExpressionConverter.scala | 8 ++++++++ .../apache/gluten/expression/UnaryExpressionTransformer.scala | 10 ++-------- .../scala/org/apache/gluten/expression/ExpressionNames.scala | 1 + .../org/apache/gluten/sql/shims/spark40/Spark40Shims.scala | 2 ++ .../org/apache/gluten/sql/shims/spark41/Spark41Shims.scala | 2 ++ 6 files changed, 26 insertions(+), 8 deletions(-) diff --git a/backends-velox/src/test/scala/org/apache/gluten/functions/ArithmeticAnsiValidateSuite.scala b/backends-velox/src/test/scala/org/apache/gluten/functions/ArithmeticAnsiValidateSuite.scala index a1633c4cb4..0fb59fe9c0 100644 --- a/backends-velox/src/test/scala/org/apache/gluten/functions/ArithmeticAnsiValidateSuite.scala +++ b/backends-velox/src/test/scala/org/apache/gluten/functions/ArithmeticAnsiValidateSuite.scala @@ -100,4 +100,15 @@ class ArithmeticAnsiValidateSuite extends FunctionsValidateSuite { } } + test("remainder") { + runQueryAndCompare("SELECT int_field1 % 3 FROM datatab WHERE int_field1 IS NOT NULL") { + checkGlutenPlan[ProjectExecTransformer] + } + if (isSparkVersionGE("3.4")) { + intercept[SparkException] { + sql("SELECT 1 % 0").collect() + } + } + } + } diff --git a/gluten-substrait/src/main/scala/org/apache/gluten/expression/ExpressionConverter.scala b/gluten-substrait/src/main/scala/org/apache/gluten/expression/ExpressionConverter.scala index 73f7b86996..fd88427e1d 100644 --- a/gluten-substrait/src/main/scala/org/apache/gluten/expression/ExpressionConverter.scala +++ b/gluten-substrait/src/main/scala/org/apache/gluten/expression/ExpressionConverter.scala @@ -791,6 +791,14 @@ object ExpressionConverter extends SQLConfHelper with Logging { i, ExpressionNames.CHECKED_DIV ) + case a: Remainder => + BackendsApiManager.getSparkPlanExecApiInstance.genArithmeticTransformer( + substraitExprName, + replaceWithExpressionTransformer0(a.left, attributeSeq, expressionsMap), + replaceWithExpressionTransformer0(a.right, attributeSeq, expressionsMap), + a, + ExpressionNames.CHECKED_REMAINDER + ) case tryEval: TryEval => // This is a placeholder to handle try_eval(other expressions). BackendsApiManager.getSparkPlanExecApiInstance.genTryEvalTransformer( diff --git a/gluten-substrait/src/main/scala/org/apache/gluten/expression/UnaryExpressionTransformer.scala b/gluten-substrait/src/main/scala/org/apache/gluten/expression/UnaryExpressionTransformer.scala index a076c46b40..52cd0115db 100644 --- a/gluten-substrait/src/main/scala/org/apache/gluten/expression/UnaryExpressionTransformer.scala +++ b/gluten-substrait/src/main/scala/org/apache/gluten/expression/UnaryExpressionTransformer.scala @@ -46,15 +46,9 @@ case class CastTransformer(substraitExprName: String, child: ExpressionTransform override def doTransform(context: SubstraitContext): ExpressionNode = { original.dataType match { case CharType(length) => - buildCastWithWriteSideCheck( - context, - ExpressionNames.CHAR_TYPE_WRITE_SIDE_CHECK, - length) + buildCastWithWriteSideCheck(context, ExpressionNames.CHAR_TYPE_WRITE_SIDE_CHECK, length) case VarcharType(length) => - buildCastWithWriteSideCheck( - context, - ExpressionNames.VARCHAR_TYPE_WRITE_SIDE_CHECK, - length) + buildCastWithWriteSideCheck(context, ExpressionNames.VARCHAR_TYPE_WRITE_SIDE_CHECK, length) case _ => val typeNode = ConverterUtils.getTypeNode(dataType, original.nullable) ExpressionBuilder.makeCast( diff --git a/shims/common/src/main/scala/org/apache/gluten/expression/ExpressionNames.scala b/shims/common/src/main/scala/org/apache/gluten/expression/ExpressionNames.scala index d4afb7ff73..617aa2cd69 100644 --- a/shims/common/src/main/scala/org/apache/gluten/expression/ExpressionNames.scala +++ b/shims/common/src/main/scala/org/apache/gluten/expression/ExpressionNames.scala @@ -93,6 +93,7 @@ object ExpressionNames { final val CHECKED_DIVIDE = "checked_divide" final val CHECKED_MULTIPLY = "checked_multiply" final val CHECKED_DIV = "checked_div" + final val CHECKED_REMAINDER = "checked_remainder" // SparkSQL String functions final val ASCII = "ascii" diff --git a/shims/spark40/src/main/scala/org/apache/gluten/sql/shims/spark40/Spark40Shims.scala b/shims/spark40/src/main/scala/org/apache/gluten/sql/shims/spark40/Spark40Shims.scala index 0c3b163ce5..ebccadf96b 100644 --- a/shims/spark40/src/main/scala/org/apache/gluten/sql/shims/spark40/Spark40Shims.scala +++ b/shims/spark40/src/main/scala/org/apache/gluten/sql/shims/spark40/Spark40Shims.scala @@ -496,6 +496,7 @@ class Spark40Shims extends SparkShims { case d: Divide => d.evalMode == EvalMode.TRY case m: Multiply => m.evalMode == EvalMode.TRY case c: Cast => c.evalMode == EvalMode.TRY + case r: Remainder => r.evalMode == EvalMode.TRY case _ => false } } @@ -508,6 +509,7 @@ class Spark40Shims extends SparkShims { case m: Multiply => m.evalMode == EvalMode.ANSI case c: Cast => c.evalMode == EvalMode.ANSI case i: IntegralDivide => i.evalMode == EvalMode.ANSI + case r: Remainder => r.evalMode == EvalMode.ANSI case _ => false } } diff --git a/shims/spark41/src/main/scala/org/apache/gluten/sql/shims/spark41/Spark41Shims.scala b/shims/spark41/src/main/scala/org/apache/gluten/sql/shims/spark41/Spark41Shims.scala index 5ff9d51c71..1c8d267204 100644 --- a/shims/spark41/src/main/scala/org/apache/gluten/sql/shims/spark41/Spark41Shims.scala +++ b/shims/spark41/src/main/scala/org/apache/gluten/sql/shims/spark41/Spark41Shims.scala @@ -495,6 +495,7 @@ class Spark41Shims extends SparkShims { case d: Divide => d.evalMode == EvalMode.TRY case m: Multiply => m.evalMode == EvalMode.TRY case c: Cast => c.evalMode == EvalMode.TRY + case r: Remainder => r.evalMode == EvalMode.TRY case _ => false } } @@ -507,6 +508,7 @@ class Spark41Shims extends SparkShims { case m: Multiply => m.evalMode == EvalMode.ANSI case c: Cast => c.evalMode == EvalMode.ANSI case i: IntegralDivide => i.evalMode == EvalMode.ANSI + case r: Remainder => r.evalMode == EvalMode.ANSI case _ => false } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
