Uh oh!
There was an error while loading. Please reload this page.
[SPARK-30292][SQL]Throw Exception when invalid string is cast to numeric type in ANSI mode - #26933
[SPARK-30292][SQL]Throw Exception when invalid string is cast to numeric type in ANSI mode#26933iRakson wants to merge 15 commits into
Conversation
maropu
commented
Dec 18, 2019
also cc: @gengliangwang |
cloud-fan
commented
Dec 18, 2019
ok to test |
cloud-fan
commented
Dec 18, 2019
we already have an |
SparkQA
commented
Dec 18, 2019
Test build #115509 has finished for PR 26933 at commit
|
iRakson
commented
Dec 18, 2019
I will move them to |
Well, I think the issue exists in converting a String to any Numeric types (short/int/long/float/double..) |
iRakson
commented
Dec 19, 2019
Okk. I will include all of them in this PR only. |
iRakson
commented
Dec 19, 2019
I have moved all rules to |
SparkQA
commented
Dec 19, 2019
Test build #115570 has finished for PR 26933 at commit
|
Uh oh!
There was an error while loading. Please reload this page.
maropu
commented
Dec 20, 2019
(Also, you need to add tests...) |
SparkQA
commented
Dec 27, 2019
Test build #115864 has finished for PR 26933 at commit
|
SparkQA
commented
Dec 27, 2019
Test build #115862 has finished for PR 26933 at commit
|
iRakson
commented
Dec 27, 2019
@cloud-fan@gengliangwang@maropu Kindly review the changes. Everything is moved inside |
SparkQA
commented
Dec 27, 2019
Test build #115866 has finished for PR 26933 at commit
|
SparkQA
commented
Dec 30, 2019
Test build #115952 has finished for PR 26933 at commit
|
Uh oh!
There was an error while loading. Please reload this page.
@cloud-fan@maropu@gengliangwang@HyukjinKwon Kindly review the changes. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
| try floatStr.toFloat catch { | ||
| case _: NumberFormatException => | ||
| val f = Cast.processFloatingPointSpecialLiterals(floatStr, true) | ||
| if (f == null) { |
There was a problem hiding this comment.
this is too much code duplication. How about unifying these 2 cases?
val f = Cast.processFloatingPointSpecialLiterals(floatStr, true)
if (f == null && ansiEnabled) {
throw ...
} else {
f
}
| $evPrim = Float.valueOf($floatStr); | ||
| } catch (java.lang.NumberFormatException e) { | ||
| final Float f = (Float) Cast.processFloatingPointSpecialLiterals($floatStr, true); | ||
| if (f == null) { |
There was a problem hiding this comment.
nit: we can unify the code a little bit
val handleNull = if (ansiEnabled) {
s"throw ..."
} else {
s"$evNull = true;"
}
...
code"""
...
if (f == null) {
$handleNull
} else ...
"""
Uh oh!
There was an error while loading. Please reload this page.
SparkQA
commented
Jan 6, 2020
Test build #116175 has finished for PR 26933 at commit
|
| """ | ||
| } | ||
| code""" | ||
| UTF8String.IntWrapper $wrapper = new UTF8String.IntWrapper(); |
There was a problem hiding this comment.
ah we don't need to create int wrapper at all for ansi mode
case StringType if ansi => (c, evPrim, evNull) => s"$evPrim = $c.toByteExact();"
case StringType => // the original code
iRakson
commented
Jan 8, 2020
@cloud-fan Please review this once. I have made all the required changes. |
SparkQA
commented
Jan 8, 2020
Test build #116291 has finished for PR 26933 at commit
|
| ${changePrecision(tmp, target, evPrim, evNull, canNullSafeCast)} | ||
| } catch (java.lang.NumberFormatException e) { | ||
| $evNull = true; | ||
| if ($ansiEnabled) { |
There was a problem hiding this comment.
nit: this will generate java code with if-else, we can do better
val handleException = if (ansiEnabled) {
s"throw new NumberFormatException("invalid input syntax for type numeric: $c");"
} else {
s"$evNull =true;"
}
code"""
...
} catch (java.lang.NumberFormatException e) {
$handleException
}
"""
Uh oh!
There was an error while loading. Please reload this page.
cloud-fan
left a comment
There was a problem hiding this comment.
LGTM except one comment, thanks for your patience!
iRakson
commented
Jan 8, 2020
Thanks for the all the code reviews and suggestions. :) |
SparkQA
commented
Jan 8, 2020
Test build #116296 has finished for PR 26933 at commit
|
SparkQA
commented
Jan 8, 2020
Test build #116297 has finished for PR 26933 at commit
|
SparkQA
commented
Jan 8, 2020
Test build #116304 has finished for PR 26933 at commit
|
| @@ -921,11 +850,6 @@ abstract class CastSuiteBase extends SparkFunSuite with ExpressionEvalHelper { | |||
| Seq("nan", "nAn", " nan ").foreach { value => | |||
| checkEvaluation(cast(value, DoubleType), Double.NaN) | |||
| } | |||
There was a problem hiding this comment.
cast('nan' as float) is working fine.
Although CAST(CAST(nan AS DECIMAL(10,0)) AS DOUBLE) is returning NaN in pgsql.
cloud-fan
commented
Jan 14, 2020
thanks, merging to master! |
…rs (byte/short/int/long) should fail with fraction ### What changes were proposed in this pull request? This is a followup of #26933 Fraction string like "1.23" is definitely not a valid integral format and we should fail to do the cast under the ANSI mode. ### Why are the changes needed? correct the ANSI cast behavior from string to integral ### Does this PR introduce any user-facing change? Yes under ANSI mode, but ANSI mode is off by default. ### How was this patch tested? new test Closes#27957 from cloud-fan/ansi. Authored-by: Wenchen Fan <wenchen@databricks.com> Signed-off-by: Takeshi Yamamuro <yamamuro@apache.org>
…rs (byte/short/int/long) should fail with fraction ### What changes were proposed in this pull request? This is a followup of #26933 Fraction string like "1.23" is definitely not a valid integral format and we should fail to do the cast under the ANSI mode. ### Why are the changes needed? correct the ANSI cast behavior from string to integral ### Does this PR introduce any user-facing change? Yes under ANSI mode, but ANSI mode is off by default. ### How was this patch tested? new test Closes#27957 from cloud-fan/ansi. Authored-by: Wenchen Fan <wenchen@databricks.com> Signed-off-by: Takeshi Yamamuro <yamamuro@apache.org> (cherry picked from commit ac262cb) Signed-off-by: Takeshi Yamamuro <yamamuro@apache.org>
…rs (byte/short/int/long) should fail with fraction ### What changes were proposed in this pull request? This is a followup of apache#26933 Fraction string like "1.23" is definitely not a valid integral format and we should fail to do the cast under the ANSI mode. ### Why are the changes needed? correct the ANSI cast behavior from string to integral ### Does this PR introduce any user-facing change? Yes under ANSI mode, but ANSI mode is off by default. ### How was this patch tested? new test Closesapache#27957 from cloud-fan/ansi. Authored-by: Wenchen Fan <wenchen@databricks.com> Signed-off-by: Takeshi Yamamuro <yamamuro@apache.org>
What changes were proposed in this pull request?
If spark.sql.ansi.enabled is set,
throw exception when cast to any numeric type do not follow the ANSI SQL standards.
Why are the changes needed?
ANSI SQL standards do not allow invalid strings to get casted into numeric types and throw exception for that. Currently spark sql gives NULL in such cases.
Before:
select cast('str' as decimal) => NULLAfter :
select cast('str' as decimal) => invalid input syntax for type numeric: strThese results are after setting
spark.sql.ansi.enabled=trueDoes this PR introduce any user-facing change?
Yes. Now when ansi mode is on users will get arithmetic exception for invalid strings.
How was this patch tested?
Unit Tests Added.