databendlabs/databend · error · InvalidData
Expected to have quotes in string literal.
Error message
Expected to have quotes in string literal.
What it means
Raised by the `check_pos` helper used by `fast_read_quoted_text`. The fast path pre-records the byte positions of quote/escape characters and verifies them while rescanning; if the cursor's current position does not match any recorded quote position, the literal is assumed malformed and this InvalidData error is returned.
Solutions
- Fall back to the non-fast `read_quoted_text` (via `read_string_text`) which is more tolerant and gives better diagnostics.
- Verify the literal is valid UTF-8 and uses a single consistent quote character.
- Check for unbalanced or unescaped quotes/escapes in the offending literal.
- If parsing third-party text, pre-normalize it (re-escape quotes) before calling the fast parser.
Example fix
// before: fast path on suspicious input let s = "'weird\\\"literal".as_bytes().fast_read_quoted_text(&mut buf)?; // after: use the robust reader for untrusted input let s = "'weird\\\"literal'".as_bytes().read_quoted_text(&mut buf)?;
Defensive patterns
Strategy: fallback
Validate before calling
fn valid_utf8_literal(input: &[u8]) -> bool {
std::str::from_utf8(input).is_ok()
} Type guard
fn usable_by_fast_path(input: &[u8]) -> bool {
std::str::from_utf8(input).map(|s| {
s.starts_with('\'') && s.ends_with('\'')
}).unwrap_or(false)
} Try / catch
let result = match fast_read_quoted_text(&mut buf) {
Ok(s) => Ok(s),
Err(_) => input.as_bytes().read_quoted_text(&mut buf), // tolerant fallback
}; Prevention
- Validate UTF-8 before using the fast path.
- Fall back to read_quoted_text whenever the fast scanner fails.
- Keep literal content free of control/invalid bytes.
When it happens
Trigger: Calling `fast_read_quoted_text` on input whose escape/quote structure is inconsistent — e.g. the scanner lands on a position that was not registered as a quote, which happens with malformed escapes, unbalanced quotes, or bytes that altered the scan trajectory (multi-byte/invalid UTF-8 sequences in the middle of the literal).
Common situations: String literals containing invalid UTF-8, mixed quote styles, or hand-edited SQL where an escape was removed but its target position stayed — any case where the fast scanner's recorded quote positions no longer line up with the actual input.
Related errors
- Expected to have char
- Expected to have terminated string literal after escaped…
- Expected to have terminated string literal after quota
- Expected to have terminated string literal after quota '…
- {e}
AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11).
Data as JSON: /api/errors/88bd40ecece7121a.
Report an issue: GitHub.
Appendix: source
Thrown at src/common/io/src/cursor_ext/cursor_read_string_ext.rs:198
}
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,
"Expected to have quotes in string literal.".to_string(),
))
}
fn unescape(c: u8) -> u8 {
match c {
b'a' => b'\x07', // \a in c
b'b' => b'\x08', // \b in c
b'v' => b'\x0B', // \v in c
b'f' => b'\x0C', // \f in c
b'e' => b'\x1B', // \e in c
b'n' => b'\n',
b'r' => b'\r',
b't' => b'\t',
b'0' => b'\0',
_ => c,
}View on GitHub (pinned to 288d84d76e)