sunchao commented on code in PR #6826:
URL: https://github.com/apache/datafusion-comet/pull/6826#discussion_r4253039520


##########
native/spark-expr/src/conversion_funcs/string.rs:
##########
@@ -616,9 +626,9 @@ fn parse_string_to_decimal(input_str: &str, precision: u8, 
scale: i8) -> SparkRe
         return Ok(Some(0));
     }
 
-    // scale adjustment
-    let target_scale = scale as i32;
-    let scale_adjustment = target_scale - exponent;
+    // scale adjustment, in i64 so that an exponent near the i32 bounds cannot 
wrap
+    let target_scale = scale as i64;
+    let scale_adjustment = target_scale - exponent as i64;

Review Comment:
   [P2] Preserve failure for extreme negative-scale column casts. With 
`spark.sql.ansi.enabled=true` and 
`spark.sql.legacy.allowNegativeScaleOfDecimal=true`, read a Parquet string 
column `s` containing `'1e-2147483647'` and evaluate 
`df.select(col("s").cast(DecimalType(10, -2))).collect()`. Spark throws 
`ArithmeticException: Underflow`. The widened subtraction now produces 
`-2147483649`, reaches the zero-return branch, and silently yields zero. The 
base returned an error under ANSI, so this materially worsens existing 
behavior. The new literal fallback does not protect column inputs. Please 
retain the widened arithmetic but detect unsupported rescaling and preserve 
Spark execution or failure, with a negative-scale column regression test.
   
   Evidence: On OpenJDK 21.0.12.1, Spark 3.5.9, 4.1.3 and 4.2.0 all threw 
`ArithmeticException: Underflow` for this bound string-column cast in both 
interpreted and generated execution. Release-mode reproductions using verified 
base/head parser bodies and the unchanged Arrow decimal conversion loop 
produced base `Err(CastInvalidValue)` versus head `Decimal128(10, -2) [0, 
null]` for input `["1e-2147483647", null]` under ANSI. 
`CometCast.canCastFromString` marks this target compatible, and `spark_cast` 
routes it to this kernel. Reproduction: 
`/tmp/pr6826-review-current-pfnzv_nz/bench/src/bin/decimal.rs`. No end-to-end 
Comet query was run.



##########
native/spark-expr/src/conversion_funcs/string.rs:
##########
@@ -254,6 +255,15 @@ where
         } else {
             s
         };
+    // Every special value Spark accepts is handled above. Java only allows 
the suffix after a
+    // decimal number, so reject anything else before Rust's parser, which 
also accepts
+    // `nan`, `inf` and `infinity` in any case (e.g. `NaNF` or `-nan`).
+    if !pruned_float_str
+        .bytes()
+        .all(|b| b.is_ascii_digit() || matches!(b, b'.' | b'e' | b'E' | b'+' | 
b'-'))

Review Comment:
   [P2] Avoid a second full scan for ordinary floating-point strings. This 
`.all(...)` runs for every numeric column value before `parse::<F>()` scans it 
again, slowing the existing `STRING` to `FLOAT`/`DOUBLE` path. In repeated 
release-mode Arrow-batch measurements, ordinary double strings increased from 
about 29.6 to 40.0 ns/value, and long numeric strings from about 75 to 147 
ns/value. Please reject unhandled special values using a bounded prefix check, 
such as the first byte after an optional sign, and leave remaining numeric 
syntax validation to Rust. A disposable version of that guard retained the 
special-value tests and removed most of the measured overhead.
   
   Evidence: Verified both parser bodies and `cast_string_to_float_impl` 
against the exact base/head sources. Benchmarked Arrow 59.3.0 batches of 8,192 
varied strings with release settings matching Comet, seven alternating samples 
of 150 batches, and two complete runs. Ordinary double inputs were generated 
with `format!("{}.{:013}", i + 1000, i * 7 + 1)`. Second-run medians were 29.67 
ns/value at base, 40.03 at head, and 31.30 with the prefix guard. FLOAT, 
scientific notation and nullable batches reproduced the slowdown. Both head and 
candidate special-value tests passed. Harness: 
`/tmp/pr6826-review-current-pfnzv_nz/bench/src/main.rs`. These are 
conversion-kernel measurements, not end-to-end query timings.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to