Skip to content

feat(expression): cast numeric literals to decimal type#805

Open
huan233usc wants to merge 3 commits into
apache:mainfrom
huan233usc:feat/default-values-numeric-decimal-cast
Open

feat(expression): cast numeric literals to decimal type#805
huan233usc wants to merge 3 commits into
apache:mainfrom
huan233usc:feat/default-values-numeric-decimal-cast

Conversation

@huan233usc

@huan233usc huan233usc commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

What

Add casting of numeric literals (int, long, float, double) to a decimal target type in Literal::CastTo, so a numeric value can be used as a default for a decimal column.

Previously CastFromInt / CastFromLong / CastFromFloat / CastFromDouble had no kDecimal case and fell through to NotSupported, so a default like Literal::Int(12) or Literal::Double(9.99) for a decimal(9, 2) column was rejected. Java allows these (IntegerLiteral.to, DoubleLiteral.to, etc. scale the value to the target scale), so this brings the C++ literal cast layer to parity for numeric sources.

How

  • Integer → decimal: CastIntegerToDecimal scales the integer (scale 0) up to the target scale via Decimal::Rescale(0, scale), then verifies the result fits the target precision (FitsInPrecision). Example: 12decimal(9,2) yields unscaled 1200 (12.00).
  • Float/double → decimal: CastRealToDecimal parses the value's shortest round-tripping decimal representation (matching Java's BigDecimal.valueOf(double) via Double.toString), then rounds to the target scale with HALF_UP rounding (round half away from zero, as Java does — 2.53, -2.5-3), and checks precision. Non-finite values are rejected.
  • Both paths reject an out-of-range decimal scale before indexing the powers-of-ten table (DecimalType does not bound its scale on construction, so decimal(9, 40) would otherwise read past the table).

Scope

Follow-up split out from the v3 default-value work (see the CastDefaultToType discussion on #793). It only extends the shared Literal::CastTo layer for numeric sources.

Testing

LiteralTest.IntegerCastToDecimal (int/long scaling, out-of-precision rejection, out-of-range scale rejection) and LiteralTest.RealCastToDecimal (float/double scaling, HALF_UP rounding incl. negative, round-down, out-of-precision and non-finite rejection), all verified fail-without / pass-with. Full expression_test passes (495 tests).

@huan233usc huan233usc changed the title feat(expression): cast integer literals to decimal type feat(expression): cast numeric literals to decimal type Jul 3, 2026
@huan233usc huan233usc marked this pull request as ready for review July 3, 2026 21:18
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.

1 participant