cloud-fan commented on code in PR #58545:
URL: https://github.com/apache/spark/pull/58545#discussion_r3944096858


##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/json/JacksonParser.scala:
##########
@@ -636,9 +640,8 @@ class JacksonParser(
       }
     }
 
-    // The JSON map will never have null or duplicated map keys, it's safe to 
create a
-    // ArrayBasedMapData directly here.
-    val mapData = ArrayBasedMapData(keys.toArray, values.toArray)
+    val mapData = new ArrayBasedMapBuilder(keyType, valueType).from(

Review Comment:
   **Blocking (P1):** The new top-level bypass only works while 
`DUPLICATED_MAP_KEY` remains the root cause. Here an outer `convertMap` can 
catch an inner duplicate as generic `NonFatal`, omit its value, and then 
replace it with the key/value-length error from `from`; `convertObject` can 
likewise retain an earlier field error and discard a later duplicate. In both 
cases PERMISSIVE mode can bypass `mapKeyDedupPolicy=EXCEPTION`. Could we 
rethrow or prioritize this condition in the inner partial-result paths and 
cover both a map nested as a map value and a duplicate after an unrelated bad 
struct field?
   
   **Recommended change:** Make DUPLICATED_MAP_KEY terminal at every 
JacksonParser partial-result boundary while leaving other conversion failures 
under the existing permissive partial-result policy.
   
   **Why this works:** Detect the duplicate-key condition before generic 
NonFatal handling in convertMap and before first-error accumulation can hide it 
in convertObject, using one consistent condition/cause check across the parser.
   
   **Scope:** JacksonParser convertMap and convertObject error handling plus 
BasicCharVarcharTestSuite regressions for nested-map and earlier-bad-field 
ordering cases.
   
   **Compatibility:** EXCEPTION reliably fails on normalized duplicates 
regardless of nesting or field order; LAST_WIN and partial results for 
non-duplicate conversion errors remain unchanged.
   
   **Risks:** An overly broad cause-chain rethrow could disable permissive 
handling for unrelated SparkRuntimeException conditions. Changing accumulator 
precedence must not discard valid partial results for errors other than 
duplicate map keys.
   
   **Constraints:** Match only the established DUPLICATED_MAP_KEY condition. 
Preserve JSON partial-result behavior and parse-mode handling for all other 
failures.
   
   **Success:** A CHAR-key collision nested under another map and the same 
collision after an unrelated malformed struct field both raise 
DUPLICATED_MAP_KEY under EXCEPTION, without changing non-duplicate permissive 
results.



##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/json/JacksonParser.scala:
##########
@@ -636,9 +640,8 @@ class JacksonParser(
       }
     }
 
-    // The JSON map will never have null or duplicated map keys, it's safe to 
create a
-    // ArrayBasedMapData directly here.
-    val mapData = ArrayBasedMapData(keys.toArray, values.toArray)
+    val mapData = new ArrayBasedMapBuilder(keyType, valueType).from(

Review Comment:
   **Blocking (P1):** `ArrayBasedMapBuilder` is now used for every 
`StringType`-keyed map, not only CHAR/VARCHAR keys. That changes existing 
default-mode behavior: duplicate JSON object names (and repeated XML map 
element names) now raise `DUPLICATED_MAP_KEY`, while the old JSON path 
constructed `MapData` directly and the old XML path used last-wins `toMap`. 
This is reachable with the standard-semantics flag still off, e.g. 
`from_json('{"a":1,"a":2}', 'MAP<STRING, INT>')`. Could we preserve the old 
construction path for ordinary STRING keys and select policy-aware construction 
only where CHAR/VARCHAR normalization can introduce collisions?
   
   **Recommended change:** Keep the previous JSON/XML map construction behavior 
for every non-CHAR/VARCHAR string key type, and use ArrayBasedMapBuilder plus 
duplicate-key escape handling only for CHAR/VARCHAR keys whose new 
normalization can create collisions.
   
   **Why this works:** Classify the declared map key type at the parser 
conversion boundary instead of treating every StringType subtype as part of the 
new deduplication path; gate the corresponding duplicate-error bypass by the 
same classification.
   
   **Scope:** JacksonParser.convertMap, StaxXmlParser.convertMap, their 
duplicate-error propagation hooks, and compatibility tests for ordinary STRING 
maps alongside the CHAR/VARCHAR collision tests.
   
   **Compatibility:** Ordinary MAP<STRING, ...> inputs retain their pre-PR 
duplicate behavior with standard semantics both disabled and enabled, while 
normalized CHAR/VARCHAR collisions continue to honor EXCEPTION and LAST_WIN.
   
   **Risks:** The type gate must distinguish first-class CHAR/VARCHAR keys 
without changing behavior for other StringType variants or collations. The JSON 
and XML construction branches must remain aligned with their respective pre-PR 
duplicate semantics.
   
   **Constraints:** Do not broaden spark.sql.mapKeyDedupPolicy beyond the 
normalized CHAR/VARCHAR collision path introduced by this PR. Preserve existing 
parse-mode and partial-result behavior for ordinary STRING maps.
   
   **Success:** The ordinary JSON and XML duplicate examples return their 
pre-PR last value under default settings, and CHAR/VARCHAR normalization 
collisions still throw under EXCEPTION and retain the last value under LAST_WIN.



-- 
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