-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Fixes serialization of big decimals to json (#6530) #6531
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
Fixes serialization of big decimals to json (#6530) #6531
Conversation
f65ef0b to
3b6ef2f
Compare
1477283 to
b0be989
Compare
| val stripped = v.bigDecimal.stripTrailingZeros | ||
| val raw = if (shouldWritePlain) stripped.toPlainString else stripped.toString | ||
|
|
||
| if (raw contains ".") json.writeTree(new DecimalNode(new JBigDec(raw))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this was checking if number contains a . but 2e128 has no dot and still needs to be printed as BigDecimal
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm suggesting we remove the conditional and write as:
json.writeTree(new DecimalNode(new JBigDec(raw)))Because of the formatting logic above, raw should be written as a plain string for a number within the range such as 50.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunetly this breaks the tests as well. Whole issue is around jackson not beaing able to print 50 as bigdecimal and that's why we have this if to print it as bigInt.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops. I guess I didn't notice that Jackson had that special case.
|
Thanks. Maybe now we should just always use BigDecimal? It would make the logic a lot simpler and I'm not sure if we get much benefit from using BigInteger in some cases, as long as we know the number is being printed properly. |
|
Yes, this code seems a bit overcomplicated. Let me check if using BigDecimal always will not cause any huge regression. |
b0be989 to
beb751e
Compare
|
Ok, simplified code still works, but reintroduces #3784 which is still questionable. Imo makes no difference. Updating jackson didn't help. |
| val stripped = v.bigDecimal.stripTrailingZeros | ||
| val raw = if (shouldWritePlain) stripped.toPlainString else stripped.toString | ||
|
|
||
| if (raw contains ".") json.writeTree(new DecimalNode(new JBigDec(raw))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We still want to write a DecimalNode though, to preserve the formatting.
|
I don't think it makes a difference either but I'd rather avoid people complaining about the formatting change. |
beb751e to
fa815ae
Compare
framework/project/Dependencies.scala
Outdated
| "com.fasterxml.jackson.datatype" % "jackson-datatype-jdk8", | ||
| "com.fasterxml.jackson.datatype" % "jackson-datatype-jsr310" | ||
| ).map(_ % "2.7.6") | ||
| ).map(_ % "2.8.2") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In master this should be okay but I think minor versions of Jackson can have breaking changes, so I'd rather not upgrade in 2.5.x/2.4.x. I'd suggest we do this change in another PR so we can easily backport this one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reverted. Do you want me move this PR to 2.5.x branch? It's were the bug is after all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually we backport things by cherry-pick the commit from master. and if that's not possible we manually adjust it.
fa815ae to
ee653bb
Compare
| "Deserialize integer JsNumber as Jackson number node" in { | ||
| val jsNum = JsNumber(new java.math.BigDecimal("50")) | ||
| fromJson[JsonNode](jsNum).map(_.toString) must_== JsSuccess("50") | ||
| fromJson[JsonNode](jsNum).map(_.toString) must_== JsSuccess("5E+1") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you update the code so this passes again? It's fine to only use BigDecimal but I don't want to screw up the formatting behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I'm on it. Will be fixed today.
I also started looking in jackson for the solution but with no luck so far.
|
So the issue is I think in Jackson. This is the only piece that seems to fail: |
a6e4e10 to
022d6f0
Compare
|
@mkljakubowski The reason for reading as Can you just put back all of the old code besides the special case for integers that was causing the bug? I think that will fix it. |
022d6f0 to
d08f674
Compare
|
@gmethvin reverted old code |
| val raw = if (shouldWritePlain) stripped.toPlainString else stripped.toString | ||
|
|
||
| if (raw contains ".") json.writeTree(new DecimalNode(new JBigDec(raw))) | ||
| if (raw.exists(ch => ".eE".contains(ch))) json.writeTree(new DecimalNode(new JBigDec(raw))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that this is common code path, maybe the most optimal way to write it is:
if (raw.indexOf('E') < 0 && raw.indexOf('.') < 0) {
json.writeTree(new BigIntegerNode(new JBigInt(raw)))
}
json.writeTree(new DecimalNode(new JBigDec(raw)))There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
d08f674 to
c2b82e2
Compare
Possible fix for #6530
Fixes serialization of BigDecimals to json in some particular case which was failing