use crate::diagnostic::{ParseError, ParseErrorKind};
use crate::lexer::{QuoteForm, Span};
pub(crate) fn schema_refused(message: impl Into<String>, span: Span) -> ParseError {
ParseError::new(ParseErrorKind::Refused(message.into()), span)
}
pub(crate) fn unsupported(what: &'static str, span: Span) -> ParseError {
ParseError::new(ParseErrorKind::Unsupported(what), span)
}
pub(crate) fn no_such_table(name: &[u8], span: Span) -> ParseError {
let _ = span;
ParseError::new(
ParseErrorKind::Refused(format!("no such table: {}", String::from_utf8_lossy(name))),
Span::default(),
)
}
pub(crate) fn no_such_column_quoted(name: &[u8], quote: QuoteForm, span: Span) -> ParseError {
if quote != QuoteForm::Double {
return no_such_column(name, span);
}
ParseError::new(
ParseErrorKind::Refused(format!(
"no such column: \"{}\" - should this be a string literal in single-quotes?",
String::from_utf8_lossy(name)
)),
span,
)
}
pub(crate) fn no_such_index(name: &[u8], span: Span) -> ParseError {
ParseError::new(
ParseErrorKind::Refused(format!("no such index: {}", String::from_utf8_lossy(name))),
span,
)
}
pub(crate) fn no_query_solution(span: Span) -> ParseError {
ParseError::new(
ParseErrorKind::Refused("no query solution".to_string()),
span,
)
}
pub(crate) fn no_such_column(name: &[u8], span: Span) -> ParseError {
ParseError::new(
ParseErrorKind::Refused(format!("no such column: {}", String::from_utf8_lossy(name))),
span,
)
}
pub(crate) fn ambiguous_column(name: &[u8], span: Span) -> ParseError {
ParseError::new(
ParseErrorKind::Refused(format!(
"ambiguous column name: {}",
String::from_utf8_lossy(name)
)),
span,
)
}
const WINDOW_ONLY: &[&[u8]] = &[
b"cume_dist",
b"dense_rank",
b"first_value",
b"lag",
b"last_value",
b"lead",
b"nth_value",
b"ntile",
b"percent_rank",
b"rank",
b"row_number",
];
const CONTEXT_ONLY: &[&[u8]] = &[
b"bm25",
b"fts5",
b"fts5_get_locale",
b"fts5_insttoken",
b"fts5_locale",
b"highlight",
b"match",
b"matchinfo",
b"offsets",
b"optimize",
b"snippet",
];
pub(crate) fn no_such_function(name: &[u8], span: Span) -> ParseError {
if let Some(said) = crate::function::needs_a_component(name) {
return ParseError::new(ParseErrorKind::Unsupported(said), span);
}
if WINDOW_ONLY.contains(&name) {
return ParseError::new(
ParseErrorKind::Refused(format!(
"misuse of window function {}()",
String::from_utf8_lossy(name)
)),
span,
);
}
if CONTEXT_ONLY.contains(&name) {
let spelled = if name == b"match" {
"MATCH".to_string()
} else {
String::from_utf8_lossy(name).into_owned()
};
return ParseError::new(
ParseErrorKind::Refused(format!(
"unable to use function {spelled} in the requested context"
)),
span,
);
}
ParseError::new(
ParseErrorKind::Refused(format!(
"no such function: {}",
String::from_utf8_lossy(name)
)),
span,
)
}
pub(crate) fn wrong_arguments(name: &[u8], span: Span) -> ParseError {
ParseError::new(
ParseErrorKind::Refused(format!(
"wrong number of arguments to function {}()",
String::from_utf8_lossy(name)
)),
span,
)
}
pub(crate) fn no_such_collation(name: &[u8], span: Span) -> ParseError {
ParseError::new(
ParseErrorKind::Refused(format!(
"no such collation sequence: {}",
String::from_utf8_lossy(name)
)),
span,
)
}
pub(crate) fn order_out_of_range(ordinal: usize, span: Span) -> ParseError {
ParseError::new(ParseErrorKind::Refused(format!(
"{ordinal}th ORDER BY term out of range - should be between 1 and the number of result columns"
)), span)
}
pub(crate) fn compound_order_unmatched(span: Span) -> ParseError {
ParseError::new(
ParseErrorKind::Refused(
"ORDER BY term does not match any column in the result set".to_string(),
),
span,
)
}