Skip to content

Commit

Permalink
refactor: extract multiline parsing to a function (risinglightdb#201)
Browse files Browse the repository at this point in the history
Signed-off-by: xxchan <xxchan22f@gmail.com>
  • Loading branch information
xxchan authored Nov 9, 2023
1 parent cf02605 commit 52d5122
Showing 1 changed file with 34 additions and 40 deletions.
74 changes: 34 additions & 40 deletions sqllogictest/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -487,12 +487,12 @@ fn parse_inner<T: ColumnType>(loc: &Location, script: &str) -> Result<Vec<Record
if let Some(text) = line.strip_prefix('#') {
comments.push(text.to_string());
if lines.peek().is_none() {
// Special handling for the case where the last line is a comment.
records.push(Record::Comment(comments));
comments = vec![];
break;
}
continue;
}

if !comments.is_empty() {
records.push(Record::Comment(comments));
comments = vec![];
Expand Down Expand Up @@ -567,17 +567,7 @@ fn parse_inner<T: ColumnType>(loc: &Location, script: &str) -> Result<Vec<Record
}
_ => return Err(ParseErrorKind::InvalidLine(line.into()).at(loc)),
};
let mut sql = match lines.next() {
Some((_, line)) => line.into(),
None => return Err(ParseErrorKind::UnexpectedEOF.at(loc.next_line())),
};
for (_, line) in &mut lines {
if line.is_empty() {
break;
}
sql += "\n";
sql += line;
}
let (sql, _) = parse_lines(&mut lines, &loc, None)?;
records.push(Record::Statement {
loc,
conditions: std::mem::take(&mut conditions),
Expand Down Expand Up @@ -619,22 +609,7 @@ fn parse_inner<T: ColumnType>(loc: &Location, script: &str) -> Result<Vec<Record

// The SQL for the query is found on second an subsequent lines of the record
// up to first line of the form "----" or until the end of the record.
let mut sql = match lines.next() {
Some((_, line)) => line.into(),
None => return Err(ParseErrorKind::UnexpectedEOF.at(loc.next_line())),
};
let mut has_result = false;
for (_, line) in &mut lines {
if line.is_empty() {
break;
}
if line == "----" {
has_result = true;
break;
}
sql += "\n";
sql += line;
}
let (sql, has_result) = parse_lines(&mut lines, &loc, Some("----"))?;
// Lines following the "----" are expected results of the query, one value per line.
let mut expected_results = vec![];
if has_result {
Expand All @@ -659,17 +634,7 @@ fn parse_inner<T: ColumnType>(loc: &Location, script: &str) -> Result<Vec<Record
}
["system", "ok"] => {
// TODO: we don't support asserting error message for system command
let mut command = match lines.next() {
Some((_, line)) => line.into(),
None => return Err(ParseErrorKind::UnexpectedEOF.at(loc.next_line())),
};
for (_, line) in &mut lines {
if line.is_empty() {
break;
}
command += "\n";
command += line;
}
let (command, _) = parse_lines(&mut lines, &loc, None)?;
records.push(Record::System {
loc,
conditions: std::mem::take(&mut conditions),
Expand Down Expand Up @@ -742,6 +707,35 @@ fn parse_file_inner<T: ColumnType>(loc: Location) -> Result<Vec<Record<T>>, Pars
Ok(records)
}

/// Parse one or more lines until empty line or a delimiter.
fn parse_lines<'a>(
lines: &mut impl Iterator<Item = (usize, &'a str)>,
loc: &Location,
delimiter: Option<&str>,
) -> Result<(String, bool), ParseError> {
let mut found_delimiter = false;
let mut out = match lines.next() {
Some((_, line)) => Ok(line.into()),
None => Err(ParseErrorKind::UnexpectedEOF.at(loc.clone().next_line())),
}?;

for (_, line) in lines {
if line.is_empty() {
break;
}
if let Some(delimiter) = delimiter {
if line == delimiter {
found_delimiter = true;
break;
}
}
out += "\n";
out += line;
}

Ok((out, found_delimiter))
}

#[cfg(test)]
mod tests {
use std::io::Write;
Expand Down

0 comments on commit 52d5122

Please sign in to comment.