mod condition_vectors;
mod conditions;
mod dml;
pub(crate) mod helpers;
mod match_parser;
mod select;
mod train;
mod values;
#[allow(dead_code)]
pub mod match_clause;
#[cfg(test)]
mod match_clause_tests;
#[cfg(test)]
mod match_query_tests;
#[cfg(test)]
mod robustness_tests;
#[cfg(test)]
mod sparse_search_tests;
#[cfg(test)]
mod subquery_tests;
#[cfg(test)]
mod temporal_tests;
use pest::iterators::Pair;
use pest::Parser as PestParser;
use pest_derive::Parser;
use super::ast::Query;
use super::error::{ParseError, ParseErrorKind};
use super::{QueryValidator, ValidationConfig};
#[derive(Parser)]
#[grammar = "velesql/grammar.pest"]
pub(crate) struct VelesQLParser;
pub(crate) fn extract_identifier(pair: &Pair<'_, Rule>) -> String {
match pair.as_rule() {
Rule::identifier => {
if let Some(inner) = pair.clone().into_inner().next() {
extract_identifier(&inner)
} else {
pair.as_str().to_string()
}
}
Rule::quoted_identifier => {
if let Some(inner) = pair.clone().into_inner().next() {
extract_identifier(&inner)
} else {
pair.as_str().to_string()
}
}
Rule::backtick_identifier => {
let s = pair.as_str();
s[1..s.len() - 1].to_string()
}
Rule::doublequote_identifier => {
let s = pair.as_str();
let inner = &s[1..s.len() - 1];
inner.replace("\"\"", "\"")
}
_ => pair.as_str().to_string(),
}
}
pub struct Parser;
impl Parser {
pub fn parse(input: &str) -> Result<Query, ParseError> {
let pairs = VelesQLParser::parse(Rule::query, input).map_err(|e| {
let position = match e.location {
pest::error::InputLocation::Pos(p) => p,
pest::error::InputLocation::Span((s, _)) => s,
};
ParseError::new(
ParseErrorKind::SyntaxError,
position,
input.chars().take(50).collect::<String>(),
e.to_string(),
)
})?;
let query_pair = pairs
.into_iter()
.next()
.ok_or_else(|| ParseError::syntax(0, input, "Empty query"))?;
let query = Self::parse_query(query_pair)?;
QueryValidator::enforce_query_complexity(&query, input, &ValidationConfig::default())?;
Ok(query)
}
}