Skip to content

Send DbType.Decimal and DbType.DateTime2 as their types - #382

Open
alaricd wants to merge 1 commit into
Giorgi:developfrom
pengdows:fix/decimal-dbtype
Open

alaricd wants to merge 1 commit into
Giorgi:developfrom
pengdows:fix/decimal-dbtype

Conversation

@alaricd

@alaricd alaricd commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Summary

DbType.Decimal and DbType.DateTime2 have no entry in ClrToDuckDBConverter.ValueCreators. A parameter declared with either type falls through to NativeMethods.Value.DuckDBCreateVarchar(item.ToString()), so the value is sent as text in the current culture. Under fr-FR or de-DE, a declared decimal is sent as 1234,5:

Statement (DuckDB.NET 1.5.6.1, de-DE) DbType.Decimal, Value = 1234.5m
INSERT into a VARCHAR column stores 1234,5
INSERT into a DOUBLE column Conversion Error: Could not convert string '1234,5' to DOUBLE
SELECT ? returns the string 1234,5, not a decimal

A DECIMAL column is not affected, because the target type routes the value through (DuckDBType.Decimal, decimal value) first.

Today this mostly stays hidden because a decimal value infers DbType.Currency, which does have a converter. Once #369 lets an explicit DbType survive assigning Value, every caller that sets DbType.Decimal hits this path.

Changes

  • DbType.Decimal gets a converter: a decimal is sent as a DECIMAL, exactly like DbType.Currency. Any other value keeps the previous fallback, so DbType.Decimal with an int still works.
  • DbType.DateTime2 is sent like DbType.DateTime (a TIMESTAMP). Any other value keeps the previous fallback.
  • A decimal value now infers DbType.Decimal instead of DbType.Currency. This matches the ADO.NET inference table and DuckDB.NET's own GetSchema("DataTypes") (Support ADO.NET schema data types and metadata probing #364), which maps DECIMAL to System.Decimal. Binding does not change: both types send the same DECIMAL value, and DbType.Currency keeps working when set explicitly.

Tests

  • DecimalValueInfersDbTypeDecimal
  • ExplicitDecimalDbTypeIsSentAsADecimalInAnyCulture (Decimal and Currency, under fr-FR: SELECT ?, a VARCHAR column and a DOUBLE column)
  • ExplicitDecimalDbTypeWithAnIntegerValueIsStillSent
  • ExplicitDateTime2DbTypeIsSentAsATimestampInAnyCulture (de-DE)
  • ExplicitDateTime2DbTypeWithATextValueIsStillSent

Three tests failed before the change (the inference, the Decimal case and DateTime2); the Currency case and the two fallback guards passed before and after. The full DuckDB.NET.Test suite passes locally (net8.0), including the connection stress tests, because the change touches PreparedStatement/. The new tests passed 5 runs in a row.

Found by pengdows.AdoNetApiTest.conformance (Bind_works_with_values_of_their_own_DbType_in_any_culture, DbType_is_inferred_from_Value).

🤖 Generated with Claude Code

Neither had a value converter, so a parameter declared with one was sent
as ToString() in the current culture: "1234,5" under fr-FR, stored as such
in a VARCHAR column and refused by a DOUBLE one. A decimal value now infers
DbType.Decimal, as the ADO.NET inference table and GetSchema("DataTypes")
say, instead of DbType.Currency.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coveralls

Copy link
Copy Markdown

Coverage Report for CI Build 39939109057

Coverage increased (+0.08%) to 92.874%

Details

  • Coverage increased (+0.08%) from the base build.
  • Patch coverage: 7 of 7 lines across 2 files are fully covered (100%).
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 4276
Covered Lines: 4036
Line Coverage: 94.39%
Relevant Branches: 2572
Covered Branches: 2324
Branch Coverage: 90.36%
Branches in Coverage %: Yes
Coverage Strength: 973373.88 hits per line

💛 - Coveralls

This branch is waiting to be deployed

1 waiting deployment
external — 56707feb Waiting Oct 23, 2026 by alaricd via Authorize #712
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.

2 participants