velesdb_core/velesql/parser/
mod.rs1mod admin;
4mod condition_vectors;
5mod conditions;
6mod conditions_specialized;
7mod ddl;
8mod ddl_helpers;
9mod dml;
10mod dml_helpers;
11pub(crate) mod helpers;
12mod hints;
13mod introspection;
14mod match_parser;
15mod prescan;
16mod select;
17mod train;
18mod values;
19
20#[allow(dead_code)]
21pub mod match_clause;
22#[cfg(test)]
23mod match_clause_tests;
24mod match_patterns;
25#[cfg(test)]
26mod match_query_tests;
27#[cfg(test)]
28mod robustness_tests;
29#[cfg(test)]
30mod sparse_search_tests;
31#[cfg(test)]
32mod subquery_tests;
33#[cfg(test)]
34mod temporal_tests;
35
36use pest::iterators::Pair;
37use pest::Parser as PestParser;
38use pest_derive::Parser;
39
40use super::ast::Query;
41use super::error::{ParseError, ParseErrorKind};
42use super::{QueryValidator, ValidationConfig};
43
44#[derive(Parser)]
45#[grammar = "velesql/grammar.pest"]
46pub(crate) struct VelesQLParser;
47
48pub(crate) fn extract_identifier(pair: &Pair<'_, Rule>) -> String {
51 match pair.as_rule() {
52 Rule::identifier => {
53 if let Some(inner) = pair.clone().into_inner().next() {
55 extract_identifier(&inner)
56 } else {
57 pair.as_str().to_string()
59 }
60 }
61 Rule::quoted_identifier => {
62 if let Some(inner) = pair.clone().into_inner().next() {
64 extract_identifier(&inner)
65 } else {
66 pair.as_str().to_string()
67 }
68 }
69 Rule::backtick_identifier => {
70 let s = pair.as_str();
72 s[1..s.len() - 1].to_string()
73 }
74 Rule::doublequote_identifier => {
75 let s = pair.as_str();
77 let inner = &s[1..s.len() - 1];
78 inner.replace("\"\"", "\"")
79 }
80 _ => pair.as_str().to_string(),
82 }
83}
84
85pub struct Parser;
87
88impl Parser {
89 pub fn parse(input: &str) -> Result<Query, ParseError> {
103 let config = ValidationConfig::default();
104 prescan::prescan(input, config.max_query_length)?;
108
109 let pairs = VelesQLParser::parse(Rule::query, input).map_err(|e| {
110 let position = match e.location {
111 pest::error::InputLocation::Pos(p) => p,
112 pest::error::InputLocation::Span((s, _)) => s,
113 };
114 ParseError::new(
115 ParseErrorKind::SyntaxError,
116 position,
117 input.chars().take(50).collect::<String>(),
118 hints::enrich_message(input, position, &e.to_string()),
119 )
120 })?;
121
122 let query_pair = pairs
123 .into_iter()
124 .next()
125 .ok_or_else(|| ParseError::syntax(0, input, "Empty query"))?;
126
127 let query = Self::parse_query(query_pair)?;
128 QueryValidator::enforce_query_complexity(&query, input, &config)?;
129 Ok(query)
130 }
131}