Skip to content

GH-1377: [FlightRPC][Java] Bind DOUBLE to DECIMAL parameters - #1378

Open
shahriyar-novruzov wants to merge 3 commits into
apache:mainfrom
shahriyar-novruzov:gh-1377-decimal-double-binding
Open

shahriyar-novruzov wants to merge 3 commits into
apache:mainfrom
shahriyar-novruzov:gh-1377-decimal-double-binding

Conversation

@shahriyar-novruzov

@shahriyar-novruzov shahriyar-novruzov commented Oct 20, 2026 •

Copy link
Copy Markdown

Rationale for this change

JDBC allows setDouble on a DECIMAL column, and tools rely on it.

What changes are included in this PR?

DecimalParameterNarrower widens the Avatica rep to BigDecimal and scales it to the target vector; the converter calls it instead of casting.

Are these changes tested?

Yes. DecimalAvaticaParameterConverterTest covers DOUBLE, FLOAT, INTEGER, LONG and BigDecimal binding, rounding to the vector scale, and a non-decimal vector. Reverting the converter to the cast fails 8 of its 10 tests.

Are there any user-facing changes?

setDouble, setFloat, setInt and setLong now bind to DECIMAL parameters, and setBigDecimal accepts a value whose scale differs from the column's.

DecimalAvaticaParameterConverter cast the local value to BigDecimal, which
only holds when the client called setBigDecimal. TypedValue.toLocal() returns
a Double for Rep.DOUBLE, so setDouble against a decimal parameter failed with
"Binding value of type DOUBLE is not yet supported".

The converter now widens the value and scales it to the vector, which rejects
any scale but its own.
/**
* Converts the local value to a {@link BigDecimal}, keeping the digits the client sent.
*
* <p>{@code BigDecimal.valueOf} rather than {@code new BigDecimal(double)}: the constructor keeps

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This should be a brief code comment and not a doc comment, IMO

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Moved it to a code comment on the BigDecimal.valueOf line itself. Thanks.

@lidavidm
lidavidm requested a balanced review from Copilot October 20, 2026 11:01

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.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Copilot review overview

3 open issues
What changed in this PR

Enables JDBC-style numeric bindings (e.g., setDouble) to Arrow DECIMAL parameters by coercing Avatica TypedValue inputs into scaled BigDecimal values before writing to DecimalVector.

Changes:

  • Added DecimalParameterNarrower to widen numeric Avatica reps into BigDecimal and apply vector scale rounding (HALF_UP).
  • Updated DecimalAvaticaParameterConverter to use the new coercion path instead of directly casting.
  • Added comprehensive JUnit tests for multiple numeric reps, rounding behavior, and non-decimal vectors.
File Description
flight/​flight-sql-jdbc-core/​src/​main/​java/​org/​apache/​arrow/​driver/​jdbc/​converter/​impl/​DecimalAvaticaParameterConverter.java Uses DecimalParameterNarrower to coerce inputs to scaled BigDecimal before writing to the vector.
flight/​flight-sql-jdbc-core/​src/​main/​java/​org/​apache/​arrow/​driver/​jdbc/​converter/​impl/​DecimalParameterNarrower.java Introduces shared logic to widen/scale Avatica values to BigDecimal with HALF_UP rounding.
flight/​flight-sql-jdbc-core/​src/​test/​java/​org/​apache/​arrow/​driver/​jdbc/​converter/​impl/​DecimalAvaticaParameterConverterTest.java Adds coverage for DOUBLE/FLOAT/INTEGER/LONG/BigDecimal bindings, scaling/rounding, and non-decimal rejection.

Review effort: Lite

@lidavidm
lidavidm requested a balanced review from Copilot October 20, 2026 14:18

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.

Comment on lines +47 to +51
if (local instanceof Double || local instanceof Float) {
// valueOf, not new BigDecimal(double): the constructor keeps the binary expansion, so 0.1
// arrives as 0.1000000000000000055511151231257827.
return BigDecimal.valueOf(((Number) local).doubleValue());
}
Comment on lines +52 to +54
if (local instanceof Number) {
return BigDecimal.valueOf(((Number) local).longValue());
}
Comment on lines +68 to +71
@Test
public void testBindDouble() {
// The reported shape: setDouble of 123.456 against a DECIMAL(38,3) parameter.
TypedValue typedValue = TypedValue.ofLocal(ColumnMetaData.Rep.DOUBLE, 123.456d);
Comment on lines +37 to +38
BigDecimal value =
DecimalParameterCoercer.toBigDecimal(typedValue, decimalVector.getScale());
@github-actions

Copy link
Copy Markdown

Thank you for opening a pull request!

Please label the PR with one or more of:

  • bug-fix
  • chore
  • dependencies
  • documentation
  • enhancement

Also, add the 'breaking-change' label if appropriate.

See CONTRIBUTING.md for details.

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