1use std::collections::HashSet;
16use thiserror::Error;
17
18use crate::ast;
19
20const ERR_PARSE: &str = "parser error";
21const ERR_MISSING_GROUP_BY: &str = "Non-grouped RETURN expressions must appear in GROUP BY clause";
22const ERR_UNALIASED_COMPLEX: &str = "Complex expression must have an alias";
23const ERR_ID_NOT_IN_SCOPE: &str = "Identifier not found in current scope";
24
25pub trait QueryParser: Send + Sync {
26 fn parse(&self, input: &str) -> Result<ast::Query, QueryParseError>;
27}
28
29pub trait QueryConfiguration: Send + Sync {
30 fn get_aggregating_function_names(&self) -> HashSet<String>;
31}
32
33#[derive(Error, Debug)]
34pub enum QueryParseError {
35 #[error("{ERR_PARSE}: {0}")]
36 ParserError(Box<dyn std::error::Error + Send + Sync>),
37
38 #[error("{ERR_MISSING_GROUP_BY}")]
39 MissingGroupByKey,
40
41 #[error("{ERR_UNALIASED_COMPLEX}: {0}")]
42 UnaliasedComplexExpression(String),
43
44 #[error("{ERR_ID_NOT_IN_SCOPE}: {0}")]
45 IdentifierNotInScope(String),
46}
47
48impl QueryParseError {
52 pub fn as_peg_error(&self) -> &'static str {
53 match self {
54 QueryParseError::ParserError(_) => ERR_PARSE,
55 QueryParseError::MissingGroupByKey => ERR_MISSING_GROUP_BY,
56 QueryParseError::UnaliasedComplexExpression(_) => ERR_UNALIASED_COMPLEX,
57 QueryParseError::IdentifierNotInScope(_) => ERR_ID_NOT_IN_SCOPE,
58 }
59 }
60}