Commit adcda16
authored
[BUG] Handle null regex captures in interval and regexp_extract_all (#15280)
**JaCoCo sql-plugin line coverage: +25 lines** (8 interval-parsing lines
covered by `CsvScanForIntervalSuite`, shim 351; 17 `regexp_extract_all`
lines covered by `test_regexp_extract_all_idx_positive`, shim 401)
Closes #15275.
Closes #15281.
## Root cause
[rapidsai/cudf#23123](rapidsai/cudf#23123)
changed regex extraction so optional capture groups that do not
participate in a match return null instead of an empty string. Two
cudf-spark paths relied on the previous representation:
- day-time interval parsing treated optional sign and fractional-seconds
captures as non-null values;
- `regexp_extract_all` removed null list elements, which lost Spark's
required empty-string placeholders for unmatched captures and could
change list cardinality.
Because both failures come from the same cuDF behavior change and
independently break premerge, this PR contains the two focused
compatibility fixes so the complete Blossom matrix can validate and
merge them together.
## Fix
Due to the nature of the premerge CI, I have to merge 2 different
fixes(though they are caused by the same upstream change) in 1 PR:
### Day-time intervals
- Normalize missing sign comparisons to `false` before combining the two
signs with XOR.
- Normalize a missing fractional-seconds capture to numeric zero before
decimal conversion.
### `regexp_extract_all`
- Preserve one output list element per regex match.
- Convert an unmatched requested capture from null to Spark's empty
string.
- Preserve empty lists for non-null inputs with no matches and null
lists for null inputs.
- Restore the input row count when cuDF returns a zero-row list column
for an all-no-match batch.
The longer-term proposal to move Spark-specific regex result
normalization behind the JNI boundary is tracked in
[NVIDIA/cudf-spark-jni#4821](NVIDIA/cudf-spark-jni#4821).
This PR keeps the current ownership boundaries and fixes the two
affected consumers without adding a temporary compatibility switch.
## Validation
- Scala 2.12 / Spark 3.5.1 `CsvScanForIntervalSuite`: `Tests: succeeded
6, failed 0, canceled 1, ignored 0, pending 0`; reactor `BUILD SUCCESS`.
- Scala 2.13 / Spark 4.0.1 production and integration-test build:
reactor `BUILD SUCCESS`.
- Spark 4.0.1 `regexp_test.py::test_regexp_extract_all_idx_positive`: `3
passed, 39627 deselected`.
- The same regex IT with forced OOM injection: `3 passed, 39627
deselected`.
- JaCoCo fix-line intersection: 8 of 16 added interval lines plus 17 of
30 added regex lines covered, for 25 unique added production lines.
- `scripts/check-shim-coverage.sh`: passed.
## Performance impact
The interval change adds null normalization only in the specialized
string-to-day-time-interval path. The regex change removes the previous
max-list-width expansion and reconstructs the existing variable-length
list column in place; the focused microbenchmark measured 0.538 s before
versus 0.464 s after (about 13.7% faster). No new regex match pass is
introduced.
Documentation
- [ ] Updated for new or modified user-facing features or behaviors
- [x] No user-facing change
Testing
- [ ] Added or modified tests to cover new code paths
- [x] Covered by existing tests
(`CsvScanForIntervalSuite` and
`regexp_test.py::test_regexp_extract_all_idx_positive`, including forced
OOM injection.)
- [ ] Not required
Performance
- [x] Tests ran and results are added in the PR description
- [ ] Issue filed with a link in the PR description
- [ ] Not required
---------
Signed-off-by: Allen Xu <allxu@nvidia.com>1 parent 306a657 commit adcda16
2 files changed
Lines changed: 46 additions & 46 deletions
File tree
- sql-plugin/src/main/scala
- com/nvidia/spark/rapids/shims
- org/apache/spark/sql/rapids
Lines changed: 16 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
286 | 286 | | |
287 | 287 | | |
288 | 288 | | |
289 | | - | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
290 | 297 | | |
291 | 298 | | |
292 | 299 | | |
| |||
307 | 314 | | |
308 | 315 | | |
309 | 316 | | |
310 | | - | |
311 | | - | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
312 | 325 | | |
313 | 326 | | |
314 | 327 | | |
| |||
Lines changed: 30 additions & 43 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
37 | 37 | | |
38 | 38 | | |
39 | 39 | | |
| 40 | + | |
40 | 41 | | |
41 | 42 | | |
42 | 43 | | |
| |||
1753 | 1754 | | |
1754 | 1755 | | |
1755 | 1756 | | |
1756 | | - | |
1757 | | - | |
1758 | | - | |
1759 | | - | |
1760 | | - | |
1761 | | - | |
1762 | | - | |
1763 | | - | |
1764 | | - | |
1765 | | - | |
1766 | | - | |
1767 | 1757 | | |
1768 | 1758 | | |
1769 | 1759 | | |
1770 | | - | |
1771 | | - | |
1772 | | - | |
1773 | | - | |
1774 | | - | |
1775 | | - | |
1776 | | - | |
1777 | | - | |
1778 | | - | |
1779 | | - | |
1780 | | - | |
1781 | | - | |
1782 | | - | |
1783 | | - | |
| 1760 | + | |
| 1761 | + | |
| 1762 | + | |
| 1763 | + | |
| 1764 | + | |
| 1765 | + | |
| 1766 | + | |
| 1767 | + | |
| 1768 | + | |
| 1769 | + | |
| 1770 | + | |
| 1771 | + | |
| 1772 | + | |
| 1773 | + | |
| 1774 | + | |
| 1775 | + | |
| 1776 | + | |
| 1777 | + | |
| 1778 | + | |
| 1779 | + | |
| 1780 | + | |
1784 | 1781 | | |
1785 | | - | |
1786 | | - | |
1787 | | - | |
1788 | | - | |
1789 | | - | |
1790 | | - | |
1791 | | - | |
1792 | | - | |
| 1782 | + | |
| 1783 | + | |
| 1784 | + | |
| 1785 | + | |
1793 | 1786 | | |
1794 | 1787 | | |
1795 | 1788 | | |
1796 | | - | |
1797 | | - | |
1798 | | - | |
1799 | | - | |
1800 | | - | |
1801 | | - | |
1802 | | - | |
1803 | | - | |
1804 | | - | |
| 1789 | + | |
| 1790 | + | |
1805 | 1791 | | |
1806 | | - | |
| 1792 | + | |
1807 | 1793 | | |
| 1794 | + | |
1808 | 1795 | | |
1809 | 1796 | | |
1810 | 1797 | | |
| |||
0 commit comments