Skip to content

fix(expr): align scalar UDF literal args with coerced return fields (refs spiceai/spiceai#15652) - #273

Merged
phillipleblanc merged 1 commit into
spiceai-55from
phillip/261027-round-literal-coercion
Oct 27, 2026
Merged

phillipleblanc merged 1 commit into
spiceai-55from
phillip/261027-round-literal-coercion

Conversation

@phillipleblanc

Copy link
Copy Markdown

WHAT

Backport apache#23232 to spiceai-55. round(decimal_col, 2) now reports the same result type before and after optimization. Refs spiceai/spiceai#15652.

WHY

Spice advertises the analyzed plan schema over Flight SQL, so round on decimals announced decimal(p+1,s) but streamed decimal(p,2), which made ADBC clients fail.

HOW

Clean cherry-pick of upstream c857382. Type coercion turns an implicit cast of a scalar-function literal into a literal of the coerced type. return_field_from_args then sees Int32(2) instead of CAST(Int64(2) AS Int32). Explicit user-written casts stay as expressions.

…refs spiceai/spiceai#15652)

Backport of apache#23232 (c857382).

Type coercion now materializes implicit literal casts on scalar function
arguments, so return_field_from_args sees the literal at its coerced type.
Without it, round(decimal, <int literal>) computes one return type after
analysis (literal hidden behind CAST) and another after simplification.
Copilot AI balanced review requested due to automatic review settings October 27, 2026 03:48
@phillipleblanc phillipleblanc self-assigned this Oct 27, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Materialized literal casts retain extension metadata that the previous cast path stripped, potentially attaching incompatible type annotations to UDF arguments.

1 open issue
What changed in this PR

Backports scalar-function literal coercion to spiceai-55 so decimal round reports consistent types during planning and execution, addressing the Flight SQL schema mismatch.

Changes:

  • Aligns literal arguments with coerced fields used for return-type inference.
  • Materializes successful implicit literal casts while preserving explicit cast expressions.
  • Adds coercion regression tests and removes an outdated round comment.
File Description
datafusion/​sqllogictest/​test_files/​string_numeric_coercion.slt Tests rejection of an explicitly cast arrow_cast type argument.
datafusion/​optimizer/​src/​analyzer/​type_coercion.rs Materializes implicit scalar-function literal casts and updates plan expectations.
datafusion/​functions/​src/​math/​round.rs Removes an outdated comment about pre-coercion literals.
datafusion/​expr/​src/​expr_schema.rs Aligns scalar literals with coerced argument fields and adds unit tests.
datafusion/​core/​tests/​user_defined/​user_defined_scalar_functions.rs Adds integration coverage for coerced literal types supplied to UDFs.

Review effort: Balanced

if value.data_type() != *data_type
&& let Ok(value) = value.cast_to(data_type)
{
return Ok(Expr::Literal(value, metadata));
@phillipleblanc
phillipleblanc merged commit 3a75c40 into spiceai-55 Oct 27, 2026
2 checks passed
@phillipleblanc
phillipleblanc deleted the phillip/261027-round-literal-coercion branch October 27, 2026 03:53
WhaleChao pushed a commit to WhaleChao/spiceai that referenced this pull request Oct 28, 2026
…eai#15656)

* fix(flight): announce the streamed type for round() on decimals

Pin spiceai/datafusion#273, which backports apache/datafusion#23232.
Type coercion now turns an implicit cast of a scalar-function literal
into a literal of the coerced type. round(decimal, 2) therefore plans the
same result type after analysis (the schema Flight SQL GetFlightInfo
announces) as after optimization (the type the stream sends).

Fixes spiceai#15652

* docs(fork-patches): record the datafusion pin and the literal-coercion backport

* fix(substrait-compliance): report the bumped datafusion pin
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants