Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add JsonNodeFeature.FAIL_ON_NAN_TO_BIG_DECIMAL_COERCION to determine what happens on JsonNode coercion to BigDecimal with NaN #4195

Merged
merged 5 commits into from
Nov 29, 2023

Conversation

@JooHyukKim JooHyukKim changed the title Add an option to fail on NaN to BigDecimal coercion when DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS enabled Add an option to allow NaN-> BigDecimal coercion when DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS enabled Nov 9, 2023
Copy link
Member

@pjfanning pjfanning left a comment

Choose a reason for hiding this comment

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

isNaN check is broken. It needs to be fixed first. I think it is too late in 2.16 release to do this.

@JooHyukKim
Copy link
Member Author

isNaN check is broken. It needs to be fixed first. I think it is too late in 2.16 release to do this.

Oh okay, will close for now since fixing isNaN may take a couple of discussions as per #1770 . Thank you for letting me know! 🙏🏼

@JooHyukKim JooHyukKim closed this Nov 9, 2023
@cowtowncoder
Copy link
Member

Yeah, let's tackle this in 2.17 once we get 2.16.0 final out (still hoping to get Android-records module in and that's it).

@JooHyukKim
Copy link
Member Author

isNaN check is broken. It needs to be fixed first.

Is there a open discussion about this that I can dig into/work on, @pjfanning ?

@cowtowncoder
Copy link
Member

I don't think there is a Discussion for this yet.

@JooHyukKim
Copy link
Member Author

If there is one, I assume FasterXML/jackson-core#1137 would be the one?

@pjfanning
Copy link
Member

NaN/Infinite s not part of JSON spec. I think this is low priority and not of great benefit. Could we wait until some real world users ask for this? Jackson is complicated enough already.

@JooHyukKim
Copy link
Member Author

JooHyukKim commented Nov 21, 2023

True 👍🏼. No need for proactive action.

@cowtowncoder
Copy link
Member

@pjfanning Actually there is one aspect that is within JSON spec: overflow/underflow for double (values beyond range) -- these become positive/negative infinity if decoded as double: cannot be converted to BigDecimal if decoded but could be decoded as BigDecimal directly.

@JooHyukKim There are existing failures due to problems with combination of:

  1. Limited range of fixed-length floating-point types (float, double) -- but can represent NaN (NaN, +INF, -INF)
  2. No support for NaNs by BigDecimal (but unlimited -- expect wrt max-number-length limit -- magnitude)

so this is not completely theoretical problem.

@JooHyukKim JooHyukKim reopened this Nov 22, 2023
@JooHyukKim JooHyukKim marked this pull request as draft November 22, 2023 15:06
@JooHyukKim JooHyukKim marked this pull request as ready for review November 22, 2023 15:12
@JooHyukKim JooHyukKim marked this pull request as draft November 22, 2023 15:36
@JooHyukKim
Copy link
Member Author

JooHyukKim commented Nov 22, 2023

@JooHyukKim There are existing failures due to problems with combination of:

Thank you for the explanation, @cowtowncoder!. I digged into other related issues then added a list in the PR description, to save anyone's search time.

Depending on how we apprach the isNaN problem, this new USE_BIG_DECIMAL_FOR_FLOATS might not even make sense, or valid. Approaching from jackson-core also seems valid (I will see about this).

Turning into draft for now. Sorry for making a fuss by changing PR state 🥲.

@JooHyukKim JooHyukKim changed the base branch from 2.16 to 2.17 November 23, 2023 10:34
@JooHyukKim JooHyukKim marked this pull request as ready for review November 23, 2023 10:34
@cowtowncoder cowtowncoder changed the title Add an option to allow NaN-> BigDecimal coercion when DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS enabled Add DeserializationFeature.FAIL_ON_NAN_TO_BIG_DECIMAL_COERCION to determine what happens on JsonNode coercion to BigDecimal with NaN Nov 29, 2023
@cowtowncoder cowtowncoder merged commit 722edd4 into FasterXML:2.17 Nov 29, 2023
5 checks passed
@cowtowncoder cowtowncoder changed the title Add DeserializationFeature.FAIL_ON_NAN_TO_BIG_DECIMAL_COERCION to determine what happens on JsonNode coercion to BigDecimal with NaN Add JsonNodeFeature.FAIL_ON_NAN_TO_BIG_DECIMAL_COERCION to determine what happens on JsonNode coercion to BigDecimal with NaN Nov 29, 2023
@@ -755,6 +755,12 @@ protected final JsonNode _fromFloat(JsonParser p, DeserializationContext ctxt,
return _fromBigDecimal(ctxt, nodeFactory, p.getDecimalValue());
}
if (ctxt.isEnabled(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)) {
// [databind#4194] Add an option to fail coercing NaN to BigDecimal
// Currently, Jackson 2.x allows such coercion, but Jackson 3.x will not
if (p.isNaN() && ctxt.isEnabled(JsonNodeFeature.FAIL_ON_NAN_TO_BIG_DECIMAL_COERCION)) {
Copy link
Member

Choose a reason for hiding this comment

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

@JooHyukKim p.isNaN is broken - I don't understand why this is merged - we need p.isNan to be fixed first - please can we revert this? FasterXML/jackson-core#1135

Copy link
Member

Choose a reason for hiding this comment

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

this code can be made to work if the code is moved to the catch block of the try - the try/catch is there because the p.isNaN does not work reliably

Copy link
Member Author

Choose a reason for hiding this comment

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

this code can be made to work if the code is moved to the catch block of the try - the try/catch is there because the p.isNaN does not work reliably

Right, makes sense. Thank you for providing a solution @pjfanning 🙏🏼
🔗PR

Copy link
Member

Choose a reason for hiding this comment

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

@pjfanning I looked through ParserBase.isNaN() and I am not sure why you think it is broken wrt usage here.
Not only are all tests passing (but there may be gaps in coverage), but I think logic makes sense: when a NaN value is encountered, value is immediately assigned with resetAsNaN(); otherwise parsing is deferred.
And ParserBase.isNaN() should not trigger parsing as double.

One thing to specifically note is that since JsonNodeDeserializer gets to call accessors first, there should not be cases for getDoubleValue() to get called first.

So... how specifically do you think isNaN() is broken wrt this specific use case?

@JooHyukKim JooHyukKim deleted the 4194-add-an-option branch November 29, 2023 15:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants