From caa9fd0f4861d1fa5a61c2f095f1105cdda2def8 Mon Sep 17 00:00:00 2001 From: MarekSpodBiedry <73122968+MarekSpodBiedry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:02:34 +0200 Subject: [PATCH] Fix row keys merging distinct text rows in UNIQUE and grouping (#1012) --- crates/functions/src/dynamic.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/crates/functions/src/dynamic.rs b/crates/functions/src/dynamic.rs index 2e29b416c..0e5c5aa17 100644 --- a/crates/functions/src/dynamic.rs +++ b/crates/functions/src/dynamic.rs @@ -86,8 +86,11 @@ fn key_of(v: &Value) -> String { fn row_key(r: &[Value]) -> String { let mut s = String::new(); for v in r { - s.push_str(&key_of(v)); - s.push('\u{1}'); + let k = key_of(v); + // Length prefix keeps the encoding unambiguous even when a text value contains the separator. + s.push_str(&k.len().to_string()); + s.push(':'); + s.push_str(&k); } s } @@ -1102,6 +1105,12 @@ mod tests { is_err(ev("SORTBY", vec![av(col(&[1.0, 2.0])), av(col(&[1.0, 2.0])), n(0.0)]), CellError::Value); } + #[test] + fn unique_keeps_rows_containing_separator_apart() { + let m = arr(vec![vec![tv("a"), tv("b\u{1}tc")], vec![tv("a\u{1}tb"), tv("c")]]); + assert_eq!(rows_of(&ev("UNIQUE", vec![av(m)])).len(), 2); + } + #[test] fn unique() { let v = arr(vec![vec![tv("a")], vec![tv("B")], vec![tv("A")], vec![tv("c")], vec![tv("b")]]);