You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datafusion.apache.org by gi...@apache.org on 2026/09/30 10:24:11 UTC
(datafusion) branch main updated: fix: Substrait serialization mishandles sliced map literals (#25543)
This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion.git
The following commit(s) were added to refs/heads/main by this push:
new dd1d709929 fix: Substrait serialization mishandles sliced map literals (#25543)
dd1d709929 is described below
commit dd1d709929c349fc1dfd47dc1069a8d7a5e6f0ea
Author: Neil Conway <ne...@gmail.com>
AuthorDate: Wed Sep 30 10:14:27 2026 +0000
fix: Substrait serialization mishandles sliced map literals (#25543)
## Which issue does this PR close?
- N/A
## Rationale for this change
`ScalarValue::Map` has an unfortunate property: it exposes the `keys()`
and `values()` methods from the underlying Arrow `MapArray`, but those
methods return all of the keys/values in the backing array, _not_ just
keys/values in the visible span. As a result, calling `keys()` on a
`ScalarValue::Map` can return values outside the logical content of the
scalar map.
Fix an instance of this bug in the substrait serialization code.
## What changes are included in this PR?
* Fix substrait map literal serialization bug
* Add unit test
## What is the testing strategy for this PR?
Existing tests pass, new test added.
## Are there any user-facing changes?
No, aside from fixing the bug.
---
.../src/logical_plan/producer/expr/literal.rs | 35 +++++++++++++++++++---
1 file changed, 31 insertions(+), 4 deletions(-)
diff --git a/datafusion/substrait/src/logical_plan/producer/expr/literal.rs b/datafusion/substrait/src/logical_plan/producer/expr/literal.rs
index f26984ad4a..f81333e630 100644
--- a/datafusion/substrait/src/logical_plan/producer/expr/literal.rs
+++ b/datafusion/substrait/src/logical_plan/producer/expr/literal.rs
@@ -286,19 +286,20 @@ pub(crate) fn to_substrait_literal(
}?;
LiteralType::EmptyMap(mt)
} else {
- let keys = (0..m.keys().len())
+ let entries = m.value(0);
+ let keys = (0..entries.len())
.map(|i| {
to_substrait_literal(
producer,
- &ScalarValue::try_from_array(&m.keys(), i)?,
+ &ScalarValue::try_from_array(entries.column(0), i)?,
)
})
.collect::<datafusion::common::Result<Vec<_>>>()?;
- let values = (0..m.values().len())
+ let values = (0..entries.len())
.map(|i| {
to_substrait_literal(
producer,
- &ScalarValue::try_from_array(&m.values(), i)?,
+ &ScalarValue::try_from_array(entries.column(1), i)?,
)
})
.collect::<datafusion::common::Result<Vec<_>>>()?;
@@ -548,6 +549,32 @@ mod tests {
Ok(())
}
+ #[test]
+ fn round_trip_sliced_map_literals() -> Result<()> {
+ let mut builder =
+ MapBuilder::new(None, StringBuilder::new(), Int64Builder::new());
+ builder.keys().append_value("prefix");
+ builder.values().append_value(10);
+ builder.append(true)?;
+ builder.keys().append_value("selected");
+ builder.values().append_value(20);
+ builder.keys().append_value("null_value");
+ builder.values().append_null();
+ builder.append(true)?;
+ builder.append(true)?;
+ builder.append(false)?;
+ builder.keys().append_value("suffix");
+ builder.values().append_value(30);
+ builder.append(true)?;
+ let maps = builder.finish();
+
+ // Scalar extraction retains the other rows' entries in the backing arrays.
+ for row in 0..maps.len() {
+ round_trip_literal(ScalarValue::try_from_array(&maps, row)?)?;
+ }
+ Ok(())
+ }
+
fn round_trip_literal(scalar: ScalarValue) -> Result<()> {
println!("Checking round trip of {scalar:?}");
let state = SessionContext::default().state();
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datafusion.apache.org
For additional commands, e-mail: commits-help@datafusion.apache.org