okhsunrog opened a new issue, #10925:
URL: https://github.com/apache/arrow-rs/issues/10925

   ### Describe the bug
   
   Combining `DictionaryArray`s whose dictionaries were built independently 
requires
   merging their values. `merge_dictionary_values` deduplicates, so the merged
   dictionary holds only the distinct referenced values; the `MutableArrayData`
   fallback concatenates them and can exceed what the key type addresses even 
when
   the distinct values fit comfortably.
   
   Since #10675 this surfaces as a `DictionaryKeyOverflowError` rather than a 
panic,
   which is the right behaviour for a genuine overflow. But in the two cases 
below
   the distinct values *do* fit, and the error is avoidable.
   
   **1. View-typed dictionary values are never merged.**
   `should_merge_dictionary_values` matches primitives and offset-based byte 
arrays.
   `Utf8View`/`BinaryView` are neither, so it returns early with
   `should_merge = false` and such dictionaries always take the 
non-deduplicating
   path. Were it to reach the merge, `get_masked_values` would hit
   `unimplemented!()` — it has no arm for the view layouts either.
   
   The two are indistinguishable to a caller: identical data merges as `Utf8` 
and
   fails as `Utf8View`.
   
   **2. The interner alone can overflow the key type.**
   `Interner` is best-effort by design — a hash collision evicts the previous
   occupant, so one value may be handed several keys. In practice this leaves 
~42%
   duplicates, enough to overflow a `UInt16` key at realistic cardinalities. 
This
   affects `Utf8` dictionaries too; it is simply less visible there.
   
   ### To Reproduce
   
   ```rust
   // (1) identical data, only the value layout differs
   let utf8 = || {
       let v: StringArray = (0..200).map(|i| Some(format!("v{i}"))).collect();
       DictionaryArray::<UInt8Type>::new(UInt8Array::from_iter_values(0..200), 
Arc::new(v))
   };
   let view = || {
       let v: StringViewArray = (0..200).map(|i| 
Some(format!("v{i}"))).collect();
       DictionaryArray::<UInt8Type>::new(UInt8Array::from_iter_values(0..200), 
Arc::new(v))
   };
   
   concat(&[&utf8(), &utf8()]);  // Ok(400)
   concat(&[&view(), &view()]);  // Err("Dictionary key bigger than the key 
type")
   ```
   
   ```rust
   // (2) 4 dictionaries over the same distinct values, UInt16 keys, Utf8 values
   // (so the merge path is actually taken)
   4 x 20000 distinct -> Ok, merged dict = 28445  (+42%)
   4 x 40000 distinct -> Ok, merged dict = 57433  (+43%)
   4 x 60000 distinct -> Err(DictionaryKeyOverflowError)
   ```
   
   ### Expected behavior
   
   Both should succeed with a merged dictionary holding one key per distinct 
value:
   200 in the first case, 60000 in the second. `DictionaryKeyOverflowError` 
should
   be reserved for a genuine overflow — more distinct values than the key type 
can
   address.
   
   ### Additional context
   
   Encountered in a column store that declares dictionary-encoded columns as
   `Dictionary(UInt16, Utf8View)`. Every data source builds its own dictionary, 
so
   any query combining batches hits this: a sort-preserving merge, a hash join's
   build side, or plain `CoalesceBatchesExec` — the last of which means it
   reproduces with a single partition.
   
   Follow-up to #10674 / #10675, which made this an error instead of a panic.
   I have a fix and can open a PR.
   


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

Reply via email to