Skip to content

Commit fa1f483

Browse files
committed
tests: Add newline handling to slt when multiline is not specified
Newlines are represented as a ⏎ character in the result specification.
1 parent e2ba39b commit fa1f483

File tree

4 files changed

+114
-26
lines changed

4 files changed

+114
-26
lines changed

src/sqllogictest/src/ast.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ impl std::fmt::Display for Output {
101101
pub struct QueryOutput<'a> {
102102
pub types: Vec<Type>,
103103
pub sort: Sort,
104+
pub multiline: bool,
104105
pub label: Option<&'a str>,
105106
pub column_names: Option<Vec<mz_repr::ColumnName>>,
106107
pub mode: Mode,

src/sqllogictest/src/parser.rs

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -300,30 +300,47 @@ impl<'a> Parser<'a> {
300300
Output::Values(vec![])
301301
} else {
302302
let mut vals: Vec<String> = output_str.lines().map(|s| s.to_owned()).collect();
303-
if let Mode::Cockroach = self.mode {
304-
let mut rows: Vec<Vec<String>> = vec![];
305-
for line in vals {
306-
let cols = split_cols(&line, types.len());
307-
if sort != Sort::No && cols.len() != types.len() {
308-
// We can't check this condition for
309-
// Sort::No, because some tests use strings
310-
// with whitespace that look like extra
311-
// columns. (Note that these tests never
312-
// use any of the sorting options.)
313-
bail!(
314-
"col len ({}) did not match declared col len ({})",
315-
cols.len(),
316-
types.len()
317-
);
303+
match self.mode {
304+
Mode::Standard => {
305+
if !multiline {
306+
vals = vals.into_iter().map(|val| val.replace('⏎', "\n")).collect();
318307
}
319-
rows.push(cols.into_iter().map(|col| col.replace('␠', " ")).collect());
320-
}
321-
if sort == Sort::Row {
322-
rows.sort();
323308
}
324-
vals = rows.into_iter().flatten().collect();
325-
if sort == Sort::Value {
326-
vals.sort();
309+
Mode::Cockroach => {
310+
let mut rows: Vec<Vec<String>> = vec![];
311+
for line in vals {
312+
let cols = split_cols(&line, types.len());
313+
if sort != Sort::No && cols.len() != types.len() {
314+
// We can't check this condition for
315+
// Sort::No, because some tests use strings
316+
// with whitespace that look like extra
317+
// columns. (Note that these tests never
318+
// use any of the sorting options.)
319+
bail!(
320+
"col len ({}) did not match declared col len ({})",
321+
cols.len(),
322+
types.len()
323+
);
324+
}
325+
rows.push(
326+
cols.into_iter()
327+
.map(|col| {
328+
let mut col = col.replace('␠', " ");
329+
if !multiline {
330+
col = col.replace('⏎', "\n");
331+
}
332+
col
333+
})
334+
.collect(),
335+
);
336+
}
337+
if sort == Sort::Row {
338+
rows.sort();
339+
}
340+
vals = rows.into_iter().flatten().collect();
341+
if sort == Sort::Value {
342+
vals.sort();
343+
}
327344
}
328345
}
329346
Output::Values(vals)
@@ -335,6 +352,7 @@ impl<'a> Parser<'a> {
335352
output: Ok(QueryOutput {
336353
types,
337354
sort,
355+
multiline,
338356
label,
339357
column_names,
340358
mode: self.mode,

src/sqllogictest/src/runner.rs

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2001,6 +2001,7 @@ pub async fn rewrite_file(runner: &mut Runner<'_>, filename: &Path) -> Result<()
20012001
types: &Vec<Type>,
20022002
column_names: Option<&Vec<ColumnName>>,
20032003
actual_output: &Vec<String>,
2004+
multiline: bool,
20042005
) {
20052006
buf.append_header(input, expected_output, column_names);
20062007

@@ -2013,20 +2014,46 @@ pub async fn rewrite_file(runner: &mut Runner<'_>, filename: &Path) -> Result<()
20132014
buf.append("\n");
20142015
}
20152016

2016-
if row.len() <= 1 {
2017-
buf.append(&row.iter().join(" "));
2017+
if row.len() == 0 {
2018+
// nothing to do
2019+
} else if row.len() == 1 {
2020+
// If there is only one column, then there is no need for space
2021+
// substitution, so we only do newline substitution.
2022+
if multiline {
2023+
buf.append(&row[0]);
2024+
} else {
2025+
buf.append(&row[0].replace('\n', "⏎"))
2026+
}
20182027
} else {
2019-
buf.append(&row.iter().map(|col| col.replace(' ', "␠")).join(" "));
2028+
// Substitute spaces with ␠ to avoid mistaking the spaces in the result
2029+
// values with spaces that separate columns.
2030+
buf.append(
2031+
&row.iter()
2032+
.map(|col| {
2033+
let mut col = col.replace(' ', "␠");
2034+
if !multiline {
2035+
col = col.replace('\n', "⏎");
2036+
}
2037+
col
2038+
})
2039+
.join(" "),
2040+
);
20202041
}
20212042
}
20222043
// In standard mode, output each value on its own line,
20232044
// and ignore row boundaries.
2045+
// No need to substitute spaces, because every value (not row) is on a separate
2046+
// line. But we do need to substitute newlines.
20242047
Mode::Standard => {
20252048
for (j, col) in row.iter().enumerate() {
20262049
if i != 0 || j != 0 {
20272050
buf.append("\n");
20282051
}
2029-
buf.append(col);
2052+
buf.append(&if multiline {
2053+
col.clone()
2054+
} else {
2055+
col.replace('\n', "⏎")
2056+
});
20302057
}
20312058
}
20322059
}
@@ -2048,6 +2075,7 @@ pub async fn rewrite_file(runner: &mut Runner<'_>, filename: &Path) -> Result<()
20482075
output_str: expected_output,
20492076
types,
20502077
column_names,
2078+
multiline,
20512079
..
20522080
}),
20532081
..
@@ -2065,6 +2093,7 @@ pub async fn rewrite_file(runner: &mut Runner<'_>, filename: &Path) -> Result<()
20652093
types,
20662094
column_names.as_ref(),
20672095
actual_output,
2096+
*multiline,
20682097
);
20692098
}
20702099
(
@@ -2075,6 +2104,7 @@ pub async fn rewrite_file(runner: &mut Runner<'_>, filename: &Path) -> Result<()
20752104
output: Output::Values(_),
20762105
output_str: expected_output,
20772106
types,
2107+
multiline,
20782108
..
20792109
}),
20802110
..
@@ -2093,6 +2123,7 @@ pub async fn rewrite_file(runner: &mut Runner<'_>, filename: &Path) -> Result<()
20932123
types,
20942124
Some(actual_column_names),
20952125
actual_output,
2126+
*multiline,
20962127
);
20972128
}
20982129
(

test/sqllogictest/slt.slt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,41 @@ column␠name␠with␠spaces! nospaces space␠again
3838
1
3939
2
4040
3
41+
42+
mode standard
43+
44+
query TT
45+
SELECT 'result' || chr(10) || 'with' || chr(10) || 'newline', 'no newline in this one, but there are spaces'
46+
UNION
47+
SELECT 'one' || chr(10) || 'more' || chr(10) || 'row (with spaces)', 'easy'
48+
----
49+
one⏎more⏎row (with spaces)
50+
easy
51+
result⏎with⏎newline
52+
no newline in this one, but there are spaces
53+
54+
query T multiline
55+
SELECT 'result' || chr(10) || 'with' || chr(10) || 'newline';
56+
----
57+
result
58+
with
59+
newline
60+
EOF
61+
62+
mode cockroach
63+
64+
query TT
65+
SELECT 'result' || chr(10) || 'with' || chr(10) || 'newline', 'no newline in this one, but there are spaces'
66+
UNION
67+
SELECT 'one' || chr(10) || 'more' || chr(10) || 'row (with spaces)', 'easy'
68+
----
69+
one⏎more⏎row␠(with␠spaces) easy
70+
result⏎with⏎newline no␠newline␠in␠this␠one,␠but␠there␠are␠spaces
71+
72+
query T multiline
73+
SELECT 'result' || chr(10) || 'with' || chr(10) || 'newline';
74+
----
75+
result
76+
with
77+
newline
78+
EOF

0 commit comments

Comments
 (0)