databendlabs/databend · error · InvalidData
Expected to have terminated string literal after quota '…
Error message
Expected to have terminated string literal after quota ', while consumed buf: {:?} What it means
Raised by `CursorReadStringExt::fast_read_quoted_text` when it scans a single-quoted literal but never encounters the terminating `'`. It reports the whole buffer consumed so far so the developer can locate where the quote should have appeared.
Solutions
- Examine the consumed buffer in the error and add the missing closing `'` at the end.
- Ensure quote characters inside the literal are escaped (`\'`) so they do not prematurely interact with the scanner.
- Fix the generator/serializer emitting the literal to always close quotes.
- Add a pre-parse sanity check that the literal contains an even number of unescaped quotes.
Example fix
// before let input = "'hello world"; // after let input = "'hello world'";
Defensive patterns
Strategy: validation
Validate before calling
fn balanced_quotes(input: &str, quote: char) -> bool {
let mut escaped = false;
let mut count = 0;
for c in input.chars() {
if escaped { escaped = false; continue; }
match c { '\\' => escaped = true, _ if c == quote => count += 1, _ => {} }
}
count % 2 == 0
} Type guard
fn is_closed_single_quoted(s: &str) -> bool {
s.starts_with('\'') && s.len() >= 2 && s.ends_with('\'')
} Try / catch
match fast_read_quoted_text(&mut buf) {
Ok(s) => s,
Err(e) => {
let consumed = e.to_string(); // includes consumed buf
return Err(anyhow!("missing closing quote; consumed: {consumed}"));
}
} Prevention
- Count unescaped single quotes before parsing; require an even number.
- Escape embedded quotes as \'.
- Ensure multi-line inputs aren't split mid-literal by line-oriented readers.
When it happens
Trigger: Calling `fast_read_quoted_text` on input like `'hello world` — quote opens the literal but EOF is reached before a matching `'` is consumed by the fast-path scanner.
Common situations: Hand-written query/text literals missing the closing quote, template strings where a variable value contained content that consumed the closing quote, or line-oriented input that split a literal across records.
Related errors
- Expected to have terminated string literal after quota
- Expected to have char
- Expected to have quotes in string literal.
- Expected to have terminated string literal after escaped…
- {e}
AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11).
Data as JSON: /api/errors/034f8c3b28a66262.
Report an issue: GitHub.
Appendix: source
Thrown at src/common/io/src/cursor_ext/cursor_read_string_ext.rs:181
b'\'' => {
check_pos(pos + 1, positions)?;
buf.push(b'\'');
}
b'\\' => {
check_pos(pos + 1, positions)?;
buf.push(b'\\');
}
_ => {
buf.push(b'\\');
buf.push(c);
}
}
} else {
break;
}
start = self.position() as usize;
}
Err(std::io::Error::new(
ErrorKind::InvalidData,
format!(
"Expected to have terminated string literal after quota \', while consumed buf: {:?}",
buf
),
))
}
}
// Check that the pre-calculated position is correct.
fn check_pos(curr_pos: usize, positions: &mut VecDeque<usize>) -> Result<()> {
if let Some(pos) = positions.pop_front()
&& curr_pos == pos
{
return Ok(());
}
Err(std::io::Error::new(
ErrorKind::InvalidData,View on GitHub (pinned to 288d84d76e)