Skip to content

[VL] Offload format_number to Velox native execution - #12775

Closed
minni31 wants to merge 1 commit into
apache:mainfrom
minni31:oss/format-number
Closed

[VL] Offload format_number to Velox native execution#12775
minni31 wants to merge 1 commit into
apache:mainfrom
minni31:oss/format-number

Conversation

@minni31

@minni31 minni31 commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

What changes are proposed in this pull request?

This PR offloads Spark's format_number(numeric, int) function to the Velox native implementation via Gluten.

Native offload is applied for integer and floating-point inputs (Byte/Short/Int/Long/Float/Double), which match Velox's registered format_number signatures. Two overloads are intentionally not supported natively and always fall back to vanilla Spark:

  • Format-pattern STRING second argument (e.g. format_number(x, '#,##0.00')) — Velox only implements the integer decimal-places second argument, not the Java DecimalFormat pattern overload.
  • DecimalType input — requires full-precision BigDecimal formatting; casting to Double would lose precision for values with more than 15 significant digits.

Fallback is achieved by throwing GlutenNotSupportException from genFormatNumberTransformer; the validation path (ValidatablePlan.failValidationWithException) converts this into a graceful fallback to vanilla Spark, so no query can crash on an unsupported overload.

The feature is controlled by a new config spark.gluten.sql.columnar.formatNumber (default true).

Wiring summary:

  • ExpressionNames / ExpressionMappings: register Sig[FormatNumber].
  • ExpressionConverter: dispatch FormatNumber to genFormatNumberTransformer.
  • SparkPlanExecApi: default hook throws GlutenNotSupportException so backends without native support fall back cleanly.
  • VeloxSparkPlanExecApi: override with the config gate plus StringType / DecimalType fallbacks.

How was this patch tested?

Added integration tests in VeloxStringFunctionsSuite (compared against vanilla Spark via runQueryAndCompare):

  • Native offload verified for int, bigint, float, and double inputs, and for zero decimal places. Each test asserts a ProjectExecTransformer actually carries the FormatNumber expression (not merely that some transformer exists in the plan).
  • Fallback verified for the string format-pattern overload, DecimalType input, and when the config kill-switch is disabled. Each fallback test asserts FormatNumber is absent from any ProjectExecTransformer and present in a vanilla ProjectExec.

Was this patch authored or co-authored using generative AI tooling?

Generated-by: GitHub Copilot

Wires Spark's format_number(numeric, int) Catalyst expression through
Gluten to the Velox native implementation for integer and floating-point
inputs. Two overloads are not supported natively and always fall back to
vanilla Spark:
  - the format-pattern STRING second argument (e.g. '#,##0.00'), which
    Velox does not implement, and
  - DecimalType inputs, which would lose precision when cast to Double.

Fallback is achieved by throwing GlutenNotSupportException from the
transformer, which the validation path converts into a graceful fallback.

Details:
- ExpressionNames / ExpressionMappings: register Sig[FormatNumber].
- ExpressionConverter: dispatch FormatNumber to genFormatNumberTransformer.
- SparkPlanExecApi: default hook throws GlutenNotSupportException so
  backends without native support fall back cleanly.
- VeloxSparkPlanExecApi: override with config gate plus StringType and
  DecimalType fallbacks.
- GlutenConfig: add spark.gluten.sql.columnar.formatNumber (default true).
- Tests: integration tests in VeloxStringFunctionsSuite covering native
  offload for int/bigint/float/double and fallback for string-pattern,
  DecimalType, and the disabled-config kill switch.
- docs/Configuration.md: document the new config.
Copilot AI lite review requested due to automatic review settings August 14, 2026 11:29
@github-actions github-actions Bot added CORE works for Gluten Core VELOX DOCS labels Aug 14, 2026
@github-actions

Copy link
Copy Markdown

Run Gluten Clickhouse CI on x86

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds Velox-native offload support for Spark SQL format_number(numeric, int) in Gluten (Velox backend), including a config gate and explicit fallbacks for unsupported overloads (string pattern overload and DecimalType input).

Changes:

  • Register FormatNumber in expression names/mappings and route it through ExpressionConverter into a backend hook.
  • Introduce spark.gluten.sql.columnar.formatNumber (default true) and implement Velox-side gating + type-based fallbacks via GlutenNotSupportException.
  • Add Velox integration tests asserting both offload presence and fallback behavior, and document the new config.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
shims/common/src/main/scala/org/apache/gluten/expression/ExpressionNames.scala Adds the FORMAT_NUMBER expression name constant.
gluten-substrait/src/main/scala/org/apache/gluten/expression/ExpressionMappings.scala Registers Sig[FormatNumber] mapping to format_number.
gluten-substrait/src/main/scala/org/apache/gluten/expression/ExpressionConverter.scala Adds a FormatNumber case to delegate lowering to the backend hook.
gluten-substrait/src/main/scala/org/apache/gluten/config/GlutenConfig.scala Adds config definition + accessor for spark.gluten.sql.columnar.formatNumber.
gluten-substrait/src/main/scala/org/apache/gluten/backendsapi/SparkPlanExecApi.scala Adds default genFormatNumberTransformer hook that forces fallback on non-supporting backends.
backends-velox/src/main/scala/org/apache/gluten/backendsapi/velox/VeloxSparkPlanExecApi.scala Implements Velox lowering with config gate and explicit fallbacks for String-pattern and DecimalType.
docs/Configuration.md Documents the new spark.gluten.sql.columnar.formatNumber config.
backends-velox/src/test/scala/org/apache/gluten/execution/VeloxStringFunctionsSuite.scala Adds integration tests for native offload and fallback scenarios.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +716 to +727
test("format_number executes natively for integer input") {
runQueryAndCompare(
s"select l_orderkey, format_number(l_orderkey, 2) " +
s"from $LINEITEM_TABLE limit $LENGTH")(assertFormatNumberOffloaded)
}

test("format_number executes natively for double input") {
runQueryAndCompare(
s"select l_orderkey, format_number(CAST(l_orderkey AS DOUBLE), 4) " +
s"from $LINEITEM_TABLE limit $LENGTH")(assertFormatNumberOffloaded)
}

@philo-he

Copy link
Copy Markdown
Member

Is this PR duplicate to #12754?

@minni31

minni31 commented Aug 14, 2026

Copy link
Copy Markdown
Contributor Author

Is this PR duplicate to #12754?

Looks like. Will close this one then. Thanks @philo-he

@minni31 minni31 closed this Aug 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CORE works for Gluten Core DOCS VELOX

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants