Skip to content

Commit 8c7fb0a

Browse files
bboissintustvold
andauthored
fix: fix incorrect splitting with line delimited streaming (#700)
* fix: fix incorrect splitting with line delimited streaming In some cases, valid CSV in datafusion would return: `Generic { store: "LineDelimiter", source: UnterminatedString }` due to incorrect logic. records_ends is a double ended iterator, so when calling next_back() the quoting/escaping logic would run in reverse, corrupting the internal state. * Use last instead of collecting into vec * Clippy --------- Co-authored-by: Raphael Taylor-Davies <r.taylordavies@googlemail.com>
1 parent 8bb878a commit 8c7fb0a

1 file changed

Lines changed: 35 additions & 1 deletion

File tree

src/delimited.rs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ impl LineDelimiter {
109109
}
110110
},
111111
};
112-
let end_offset = record_ends.next_back().unwrap_or(start_offset);
112+
let end_offset = record_ends.last().unwrap_or(start_offset);
113113
if start_offset != end_offset {
114114
self.complete.push_back(val.slice(start_offset..end_offset));
115115
}
@@ -270,4 +270,38 @@ mod tests {
270270
]
271271
)
272272
}
273+
274+
#[tokio::test]
275+
async fn test_delimiter_quotes_stream() {
276+
let input = vec!["x,y,z\n,\"new\nline\",\"with ", "space\""];
277+
let input_stream =
278+
futures_util::stream::iter(input.into_iter().map(|s| Ok(Bytes::from(s))));
279+
let stream = newline_delimited_stream(input_stream);
280+
281+
let results: Vec<_> = stream.try_collect().await.unwrap();
282+
assert_eq!(
283+
results,
284+
vec![
285+
Bytes::from("x,y,z\n"),
286+
Bytes::from(",\"new\nline\",\"with space\"")
287+
]
288+
)
289+
}
290+
291+
#[tokio::test]
292+
async fn test_delimiter_escape_stream() {
293+
let input = vec!["hello\n\n\"\\ttabulated\"", "world"];
294+
let input_stream =
295+
futures_util::stream::iter(input.into_iter().map(|s| Ok(Bytes::from(s))));
296+
let stream = newline_delimited_stream(input_stream);
297+
298+
let results: Vec<_> = stream.try_collect().await.unwrap();
299+
assert_eq!(
300+
results,
301+
vec![
302+
Bytes::from("hello\n\n"),
303+
Bytes::from("\"\\ttabulated\"world")
304+
]
305+
)
306+
}
273307
}

0 commit comments

Comments
 (0)