feat(expression): cast numeric literals to decimal type#805
Open
huan233usc wants to merge 3 commits into
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Add casting of numeric literals (
int,long,float,double) to a decimal target type inLiteral::CastTo, so a numeric value can be used as a default for a decimal column.Previously
CastFromInt/CastFromLong/CastFromFloat/CastFromDoublehad nokDecimalcase and fell through toNotSupported, so a default likeLiteral::Int(12)orLiteral::Double(9.99)for adecimal(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
CastIntegerToDecimalscales the integer (scale 0) up to the target scale viaDecimal::Rescale(0, scale), then verifies the result fits the target precision (FitsInPrecision). Example:12→decimal(9,2)yields unscaled1200(12.00).CastRealToDecimalparses the value's shortest round-tripping decimal representation (matching Java'sBigDecimal.valueOf(double)viaDouble.toString), then rounds to the target scale with HALF_UP rounding (round half away from zero, as Java does —2.5→3,-2.5→-3), and checks precision. Non-finite values are rejected.DecimalTypedoes not bound its scale on construction, sodecimal(9, 40)would otherwise read past the table).Scope
Follow-up split out from the v3 default-value work (see the
CastDefaultToTypediscussion on #793). It only extends the sharedLiteral::CastTolayer for numeric sources.Testing
LiteralTest.IntegerCastToDecimal(int/long scaling, out-of-precision rejection, out-of-range scale rejection) andLiteralTest.RealCastToDecimal(float/double scaling, HALF_UP rounding incl. negative, round-down, out-of-precision and non-finite rejection), all verified fail-without / pass-with. Fullexpression_testpasses (495 tests).