Repository navigation
fix: support RunEndEncoded arrays in function and window frame type coercion - #24565
Conversation
kumarUjjawal
left a comment
There was a problem hiding this comment.
Thank you @thorfour for working on this. I have left few comments please take a look.
| Ok(DataType::Interval(IntervalUnit::MonthDayNano)) | ||
| } else if let DataType::Dictionary(_, value_type) = col_type { | ||
| extract_window_frame_target_type(value_type) | ||
| } else if let DataType::RunEndEncoded(_, value_type) = col_type { |
There was a problem hiding this comment.
Unwrapping REE here also lets RANGE <offset> PRECEDING/FOLLOWING past planning. An offset frame adds the offset to each ordering value, and a value pulled from an REE column stays run-end wrapped, which arrow's arithmetic kernels don't handle. Keeping the plan time error until scalar arithmetic unwraps REE would be better.
There was a problem hiding this comment.
Good call out, we could fix this in the window state code but agreed that it should get implemented in the arrow kernels
There was a problem hiding this comment.
so whats the action that needs to be taken here
There was a problem hiding this comment.
Some options I could think of:
- We do nothing and wait for Arrow to implement this arithmetic.
- We special case the windowing function to check if REE and perform the necessary arithmetic itself.
- We add a step in planning to check if RANGE is being used on REE column and return the error in planning.
There was a problem hiding this comment.
perhaps do no.3 then raise an upstream issue for no.1
thoughts @kumarUjjawal?
There was a problem hiding this comment.
I've created the upstream issue: apache/arrow-rs#10891
There was a problem hiding this comment.
Removed this branch, and added an slt test to ensure error at planning time happens for REE.
There was a problem hiding this comment.
perhaps do no.3 then raise an upstream issue for no.1
thoughts @kumarUjjawal?
I was thinking we can put the unwrap back here, and make supports_offset_arithmetic false for a run-encoded order key? That keeps the plan time rejection for 1 PRECEDING and 1 FOLLOWING. An offset bound is the one case that needs add_checked on a wrapped value. The user then gets a plan error, not the internal "file a bug report" error.
There was a problem hiding this comment.
Good idea! I've added that behavior.
Jefffrey
left a comment
There was a problem hiding this comment.
as mentioned would be good to have an end to end test via SLT
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #24565 +/- ##
=======================================
Coverage 81.42% 81.42%
=======================================
Files 1121 1121
Lines 402142 402178 +36
Branches 402142 402178 +36
=======================================
+ Hits 327460 327493 +33
- Misses 55484 55486 +2
- Partials 19198 19199 +1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
2fd93a2 to
6663b37
Compare
6663b37 to
223d6ca
Compare
coerced_from() already special-cases Dictionary(_, value_type) so that functions declared with the old-style Exact/OneOf signature (which don't go through the newer Coercible/TypeSignatureClass system) match against the dictionary's value type. RunEndEncoded had no equivalent case, so any such function (e.g. date_bin) failed to plan when given a RunEndEncoded-wrapped column, even though the same column as a plain Dictionary would have matched fine. Add the symmetric RunEndEncoded case, unwrapping to the value field's type before recursing, mirroring the existing Dictionary handling.
extract_window_frame_target_type() already recurses through Dictionary(_, value_type) to find the natural type for a RANGE window frame bound, but had no equivalent case for RunEndEncoded, so ordering a RANGE window by a REE-dict-encoded column (the same column as a plain Dictionary would work) failed with "Cannot run range queries on datatype: RunEndEncoded(...)". Add the symmetric RunEndEncoded case, mirroring the existing Dictionary handling.
REE columns are rejected at plan time.
223d6ca to
0d21a8d
Compare
|
@kumarUjjawal anything else you require for this PR? |
## Which issue does this PR close? - Closes apache#26247. ## Rationale for this change `MIN` and `MAX` fail with an internal error on `RunEndEncoded` columns, while they work on `Dictionary` columns. See apache#26247 for a reproducer. ## What changes are included in this PR? `MIN`/`MAX` use a user-defined signature, so `get_min_max_result_type` alone decides the argument type. It unwraps `Dictionary` to its value type but passes `RunEndEncoded` through unchanged, so no cast is planned and the accumulator receives a type it has no implementation for. apache#24565 added `RunEndEncoded` handling to `coerced_from`, but user-defined signatures don't go through it. This PR adds a `RunEndEncoded` arm that recurses into the value type. With the recursion, `RunEndEncoded<_, Dictionary<K, V>>` coerces to `V`, the same result type `MAX` gives a plain `Dictionary<K, V>` column. Unwrapping one level would return the correct value, but type it as `Dictionary<K, V>`. The existing `Dictionary` arm unwraps only one level. I left it unchanged, because a dictionary whose values are themselves encoded seems rare. I'm happy to make it recursive in this PR if you'd prefer the two arms to match. ## What is the testing strategy for this PR? - `test_get_min_max_return_type_coerce_run_end_encoded` in `min_max.rs` covers `RunEndEncoded<Int32, UInt32>` → `UInt32` and `RunEndEncoded<Int32, Dictionary<UInt32, Utf8>>` → `Utf8`. - New cases in `run_end_encoded.slt` go through SQL planning, so they exercise the UDAF's coercion path rather than calling the accumulator directly: - ungrouped `MIN`/`MAX`; - their result types, via `arrow_typeof`; - grouped `MIN`/`MAX`; - `MAX` as a window function; - `MAX` over `RunEndEncoded<Int32, Dictionary<UInt32, Utf8>>`. Without the fix, the four `RunEndEncoded<Int32, UInt32>` cases fail with the internal error from apache#26247. ## Are there any user-facing changes? `MIN` and `MAX` now accept `RunEndEncoded` arguments and return the value type. There are no API changes. Generated-by: Claude Code (Claude Opus 5.5). I reviewed the change and can answer for it.
Which issue does this PR close?
coerced_fromandextract_window_frame_target_typedoesn't support RunEndEncoded arrays #24564.Rationale for this change
Adds missing support for coercing REE arrays and extracting range windows from REE arrays.
What changes are included in this PR?
Added case statements for supporting REE arrays
Are these changes tested?
Yes a unit test is included.
Are there any user-facing changes?
No