fix: honor target sorted flag and preserve map field metadata in cast_map_to_map - #5227
fix: honor target sorted flag and preserve map field metadata in cast_map_to_map#5227Smallfu666 wants to merge 1 commit into
Conversation
|
Review assisted by an LLM (Claude Code). I checked the branch out, ran the tests, and verified the claims below myself. Thanks for taking this on. The two core fixes are right. Using What I ran locally on the branch:
A few things I would like to resolve before merge. The sorted rejectionIssue #5097 asked for the target The code comment points to the PR description for planner reachability, but I could not find that discussion there. When I traced it, That suggests no Comet plan ever asks for a Cast options in the fast pathThe fast path passes the static Test coverage
Along the same lines, a test that casts the same input through both paths and compares results would guard against the two drifting. One thing I checked that is fineCasting Separately, Comet's CIThere are no CI results on this yet and the branch is 35 commits behind main. Could you rebase so a full run can be triggered? My local runs only covered the Rust tests and the three map cast suites. |
…_map_to_map (apache#5097) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
23ccf79 to
89d30fb
Compare
|
Thanks for the review, and for checking out the branch and running it yourself. Your read is right, so I dropped the rejection branch and kept the I confirmed your four sites and then looked for a producer you had not covered. I could not find One correction on the count. 2 of the 16 tests exercised the rejection, not 5, and those are the 2 I Cast options are now built by an Both coverage tests are in, and I verified with a temporary probe which branch each test actually Separately, all of this was pinned only by Rust assertions, which proves agreement with my own Nothing under Rebased onto current main. CI has not started, since fork runs still need a maintainer to approve If you still think the |
Which issue does this PR close?
Related to #5097. Intentionally not
Closes, see the scope note below: the "entries null buffer"part of the issue is not representable through safe Arrow APIs.
Rationale for this change
cast_map_to_maphad two bugs:sortedflag for the result, so a cast to a map type with a differentsortedflag returned the wrong type.nullability, so
data_type()did not equal the requested target.What changes are included in this PR?
common Parquet
key_valueto Sparkentriesrelabel, delegate to arrow'scast. It relabels tothe target fields and preserves their metadata with no value transformation.
cast_array, and build theresult with the target sorted flag rather than the source one.
try_newreplacesnewso amalformed target returns
Errinstead of panicking, and the resultdata_type()equals therequested target.
[0]and[1], so a malformed entries struct with0, 1 or 3 or more fields returns
Errrather than panicking.CastOptionsthrough a sharedarrow_cast_options(eval_mode)helper. This is behaviorally inert today. Arrow 58.4's map castdelegates to
cast_with_optionsfor the key and value arrays, and this fast path requires bothchild data types to be unchanged, so those child casts take Arrow's same-type early return before
any
safe-dependent conversion. The shared helper still prevents this call site from drifting intoa hardcoded
safe: trueif the fast-path condition is ever widened.Scope note. Within the inspected safe Arrow constructors, an all-valid entries validity buffer is
normalized to
None, while actual null entries are invalid for a map. Entries-level null-bufferpreservation is therefore not observable through those construction paths and is not claimed here.
ArrayDataand FFI construction were not audited. Map-level null preservation is covered.How are these changes tested?
16 Rust unit tests in
cast.rs, covering:nulls
truetofalse, and a value-only castreturning
Errwithout panickingTwo are new from review.
test_cast_map_to_map_sliced_rename_only_fast_pathcovers a sliced inputwhose value type is unchanged, so it exercises the arrow delegation rather than the hand-built path.
test_cast_map_to_map_both_paths_agreesends equivalent input through both implementations, comparesthe results, and asserts the shared result is correct so the two cannot agree on a wrong answer and
still pass. Which branch each test takes was verified with a temporary probe rather than inferred
from the types.
Spark differential coverage in
cast_complex.sql, since Rust assertions only prove agreementwith my own expectations. The new cases cover map value casts, a map key cast, null maps, empty maps
and null values, plus the
DATATYPE_MISMATCHthat a key cast which could introduce nulls shouldraise.
Results on
cb36aa5fe, Spark 3.5 and Scala 2.12:cargo test --workspace: 890 passed, 0 failed.CometSqlFileTestSuite: 444 run, 444 succeeded, 0 failed.CometNativeCastSuite: 167 run, 167 succeeded, 0 failed, 1 canceled.cargo fmt --checkandcargo clippy --all-targets -- -D warningsclean.Production negative control: reverting only the
cast_map_to_mapimplementation tomainwhileretaining the 16 tests gives 8 passed and 8 failed. The failures cover the target sorted flag, field
metadata and schema preservation, and the malformed-target panic cases.
SQL harness negative control: adding cases to an existing SQL file does not move the suite count,
so the new map-cast expectation was broken on its own.
CometSqlFileTestSuitethen reports 443succeeded and 1 failed, confirming the added
cast_complex.sqlcase is active and independentlychecked.