Repository navigation
Commit 35922ab
[SPARK-60103][SQL] Length-check XML CHAR/VARCHAR map keys without pad or trim
### What changes were proposed in this pull request?
When `spark.sql.charVarchar.standardSemantics.enabled` is true, `from_xml` and the XML datasource length-check XML names used as `MAP<CHAR(n), _>` / `MAP<VARCHAR(n), _>` keys without rewriting them. This matches SPARK-60108 for JSON.
The checked names are element names, `attributePrefix` plus attribute names (default `_`), and the `valueTag` (default `_VALUE`) when mixed text is present.
- `CHAR(n)` keys must already be exactly `n` characters (no pad).
- `VARCHAR(n)` keys must already be at most `n` characters (no trim).
- Exact repeated names last-win. `spark.sql.mapKeyDedupPolicy` is not applied.
- Length failures follow the XML parse mode (`PERMISSIVE` / `FAILFAST`).
Mismatched keys raise a new `UNSUPPORTED_XML_CHAR_VARCHAR_MAP_KEY` condition (SQLSTATE `0A000`) instead of `EXCEED_LIMIT_LENGTH`, because pad/trim of map keys is not supported. XML CHAR/VARCHAR values still use the same pad and `EXCEED_LIMIT_LENGTH` checks as other parsed text. JSON, CSV, and TRANSFORM are unchanged.
Struct-field maps still go through `convertField`. Empty, attribute-only, and text-only `MAP<STRING, _>` elements stay SQL NULL or a malformed record, as on master. `convertMap` is used for non-empty string-family keys (including CHAR/VARCHAR) and owns element bounding so a key-check failure still drains `ARRAY<MAP<...>>` siblings.
This PR drops `convertConstrainedMap` and `DuplicateMapKeyUtils`. SPARK-59722-style assign-after-parse is not used.
JIRA: https://issues.apache.org/jira/browse/SPARK-60103
### Why are the changes needed?
SPARK-59274 padded and trimmed CHAR/VARCHAR XML map keys during the walk, then applied `mapKeyDedupPolicy` to invented collisions. SPARK-59722 would have done the same via write-side assignment after a STRING parse; that approach was abandoned for JSON in favor of SPARK-60108. XML names are the key identity, so they should be length-checked in place rather than rewritten.
### Does this PR introduce _any_ user-facing change?
Yes, under `spark.sql.charVarchar.standardSemantics.enabled=true`:
```sql
SELECT from_xml('<ROW><m><a>1</a></m></ROW>', 'm MAP<CHAR(2), INT>', map('mode', 'FAILFAST'));
-- [UNSUPPORTED_XML_CHAR_VARCHAR_MAP_KEY] XML map keys of CHAR or VARCHAR cannot be padded or trimmed.
-- The key 'a' is not valid for type "CHAR(2)". SQLSTATE: 0A000
```
Exact-width CHAR keys and in-limit VARCHAR keys are kept as-is. Repeated names last-win. When the standard-semantics flag is false and `spark.sql.preserveCharVarcharTypeInfo` is true, short CHAR keys are padded and over-length CHAR or VARCHAR keys raise `EXCEED_LIMIT_LENGTH`.
Documented in `docs/sql-migration-guide.md` (Spark SQL 4.3 to 4.4). In Spark 4.3, `from_xml` and XML reader schemas rejected CHAR/VARCHAR with `UNSUPPORTED_CHAR_OR_VARCHAR_AS_STRING`, or replaced them with STRING when `spark.sql.legacy.charVarcharAsString` was true.
### How was this patch tested?
Added SPARK-60103 coverage in `BasicCharVarcharTestSuite` (too-short CHAR, exact-width CHAR, CHAR/VARCHAR overflow, last-wins duplicates, prefixed attributes and `valueTag` in mixed content, PERMISSIVE vs FAILFAST, nested maps, `ARRAY<MAP>`, collated keys, `from_xml` and the XML datasource, empty/attribute-only/text-only `MAP<STRING>`, `format("xml")` `MAP<INT>`, flag-off pad/overflow including over-length CHAR). Also re-ran SPARK-59274 XML value, sibling, and `rowTag` tests.
Ran:
```
JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 build/sbt -Dsbt.override.build.repos=true \
'sql/testOnly org.apache.spark.sql.BasicCharVarcharTestSuite -- -z SPARK-60103 -z "SPARK-59274: from_json/csv/xml" -z "SPARK-59274: ordinary STRING" -z "SPARK-59274: collated" -z "SPARK-59274: XML rowTag" -z "SPARK-59274: mixed XML" -z "SPARK-59274: nested XML"'
```
### Was this patch authored or co-authored using generative AI tooling?
Generated-by: Cursor Grok 4.6
Closes #59316 from srielau/SPARK-60103.
Authored-by: Serge Rielau <serge@rielau.com>
Signed-off-by: Hyukjin Kwon <hyukjin.kwon@databricks.com>
(cherry picked from commit ccc8f69)
Signed-off-by: Hyukjin Kwon <hyukjin.kwon@databricks.com>1 parent b628a94 commit 35922ab
7 files changed
Lines changed: 376 additions & 345 deletions
File tree
- common/utils/src/main/resources/error
- docs
- sql
- catalyst/src/main/scala/org/apache/spark/sql
- catalyst
- util
- xml
- errors
- internal
- core/src/test/scala/org/apache/spark/sql
Lines changed: 7 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9889 | 9889 | | |
9890 | 9890 | | |
9891 | 9891 | | |
| 9892 | + | |
| 9893 | + | |
| 9894 | + | |
| 9895 | + | |
| 9896 | + | |
| 9897 | + | |
| 9898 | + | |
9892 | 9899 | | |
9893 | 9900 | | |
9894 | 9901 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
| 28 | + | |
28 | 29 | | |
29 | 30 | | |
30 | 31 | | |
| |||
Lines changed: 0 additions & 82 deletions
This file was deleted.
Lines changed: 73 additions & 107 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
29 | | - | |
30 | 29 | | |
31 | 30 | | |
32 | 31 | | |
| |||
42 | 41 | | |
43 | 42 | | |
44 | 43 | | |
45 | | - | |
| 44 | + | |
46 | 45 | | |
47 | 46 | | |
48 | 47 | | |
| |||
86 | 85 | | |
87 | 86 | | |
88 | 87 | | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
89 | 91 | | |
90 | 92 | | |
91 | 93 | | |
| |||
233 | 235 | | |
234 | 236 | | |
235 | 237 | | |
236 | | - | |
237 | 238 | | |
238 | 239 | | |
239 | 240 | | |
| |||
330 | 331 | | |
331 | 332 | | |
332 | 333 | | |
333 | | - | |
334 | | - | |
335 | | - | |
336 | | - | |
337 | | - | |
| 334 | + | |
338 | 335 | | |
339 | 336 | | |
340 | 337 | | |
341 | 338 | | |
342 | | - | |
343 | 339 | | |
344 | 340 | | |
345 | 341 | | |
| |||
383 | 379 | | |
384 | 380 | | |
385 | 381 | | |
386 | | - | |
387 | | - | |
388 | | - | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
389 | 386 | | |
390 | 387 | | |
391 | 388 | | |
| |||
445 | 442 | | |
446 | 443 | | |
447 | 444 | | |
448 | | - | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
449 | 462 | | |
450 | 463 | | |
451 | 464 | | |
452 | 465 | | |
453 | | - | |
454 | | - | |
455 | | - | |
456 | | - | |
457 | | - | |
458 | | - | |
459 | | - | |
460 | | - | |
461 | | - | |
462 | | - | |
463 | | - | |
464 | | - | |
465 | | - | |
466 | | - | |
467 | | - | |
468 | | - | |
469 | | - | |
470 | | - | |
471 | | - | |
472 | | - | |
473 | | - | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
474 | 492 | | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
475 | 496 | | |
476 | | - | |
477 | 497 | | |
478 | 498 | | |
479 | | - | |
480 | | - | |
481 | | - | |
482 | | - | |
483 | | - | |
484 | | - | |
485 | | - | |
486 | | - | |
487 | | - | |
488 | | - | |
489 | | - | |
490 | | - | |
491 | | - | |
492 | | - | |
493 | | - | |
494 | | - | |
495 | | - | |
496 | | - | |
497 | | - | |
498 | | - | |
499 | | - | |
500 | | - | |
501 | | - | |
502 | | - | |
503 | | - | |
504 | | - | |
505 | | - | |
506 | | - | |
507 | | - | |
508 | | - | |
509 | | - | |
510 | | - | |
511 | | - | |
512 | | - | |
513 | | - | |
514 | | - | |
515 | | - | |
516 | | - | |
517 | | - | |
518 | | - | |
519 | | - | |
520 | | - | |
521 | | - | |
522 | | - | |
523 | | - | |
524 | | - | |
525 | | - | |
526 | | - | |
527 | | - | |
528 | | - | |
529 | | - | |
530 | | - | |
531 | | - | |
532 | | - | |
533 | | - | |
534 | | - | |
535 | | - | |
536 | | - | |
537 | | - | |
538 | | - | |
539 | | - | |
540 | | - | |
541 | | - | |
542 | | - | |
543 | | - | |
544 | | - | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
545 | 515 | | |
| 516 | + | |
| 517 | + | |
546 | 518 | | |
547 | | - | |
548 | | - | |
549 | | - | |
550 | | - | |
551 | 519 | | |
552 | 520 | | |
553 | 521 | | |
| |||
583 | 551 | | |
584 | 552 | | |
585 | 553 | | |
586 | | - | |
587 | 554 | | |
588 | 555 | | |
589 | 556 | | |
| |||
722 | 689 | | |
723 | 690 | | |
724 | 691 | | |
725 | | - | |
726 | 692 | | |
727 | 693 | | |
728 | 694 | | |
| |||
Lines changed: 14 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2727 | 2727 | | |
2728 | 2728 | | |
2729 | 2729 | | |
| 2730 | + | |
| 2731 | + | |
| 2732 | + | |
| 2733 | + | |
| 2734 | + | |
| 2735 | + | |
| 2736 | + | |
| 2737 | + | |
| 2738 | + | |
| 2739 | + | |
| 2740 | + | |
| 2741 | + | |
| 2742 | + | |
| 2743 | + | |
2730 | 2744 | | |
2731 | 2745 | | |
2732 | 2746 | | |
| |||
0 commit comments