use super::QueryPipelineManager;
use crate::binder::Binder;
use crate::binder::BoundStatement;
use crate::parser::Parser;
use crate::storage::QueryStorage;
use crate::QueryContext;
use linkrs_core::error::{DBError, DBResult, QueryError};
use linkrs_metrics::MetricType;
use std::sync::Arc;
impl<S: QueryStorage + 'static> QueryPipelineManager<S> {
pub(crate) fn parse_into_context(
&mut self,
query_text: &str,
) -> DBResult<crate::parser::ParserResult> {
let rewritten_text;
let effective_text = match self.extensions.try_parse_transform(query_text) {
Some(Ok(rewritten)) => {
rewritten_text = rewritten;
rewritten_text.as_str()
}
Some(Err(error)) => return Err(error),
None => query_text,
};
let mut parser = Parser::new(effective_text)
.with_type_alias_manager(self.type_alias_manager.clone());
let result = match parser.parse() {
Ok(parsed) => parsed,
Err(e) => {
if parser.has_errors() {
return Err(DBError::from(QueryError::pipeline_parse_error(
parser.take_errors(),
)));
}
return Err(DBError::from(QueryError::pipeline_parse_error(e)));
}
};
if parser.has_errors() {
return Err(DBError::from(QueryError::pipeline_parse_error(
parser.take_errors(),
)));
}
Ok(result)
}
pub(crate) fn record_query_type_counter(&self, stmt: &crate::parser::ast::Stmt) {
use crate::parser::ast::Stmt;
let metric_type = match stmt {
Stmt::Match(_) => Some(MetricType::NumMatchQueries),
Stmt::Create(_) => Some(MetricType::NumCreateQueries),
Stmt::Update(_) => Some(MetricType::NumUpdateQueries),
Stmt::Delete(_) => Some(MetricType::NumDeleteQueries),
Stmt::Insert(_) => Some(MetricType::NumInsertQueries),
Stmt::Go(_) => Some(MetricType::NumGoQueries),
Stmt::Fetch(_) => Some(MetricType::NumFetchQueries),
Stmt::Lookup(_) => Some(MetricType::NumLookupQueries),
Stmt::Show(_) => Some(MetricType::NumShowQueries),
_ => None,
};
if let Some(metric) = metric_type {
self.stats_manager.add_value(metric);
}
}
pub(crate) fn bind_parsed_statement(
&mut self,
ast: Arc<crate::parser::ast::stmt::Ast>,
qctx: Arc<QueryContext>,
) -> DBResult<Option<BoundStatement>> {
let space_id = qctx.space_id().unwrap_or(0);
let space_name = qctx
.space_name()
.or_else(|| qctx.request_context().space_name.clone());
let mut binder = Binder::new().with_space(space_name.clone(), space_id);
let extension_ctx = crate::extensions::BinderExtensionContext {
space_name: space_name.clone(),
space_id,
};
if let Some(rewritten) = self.extensions.try_bind(&ast, &extension_ctx) {
return rewritten.map(Some);
}
if let Some(ref schema_manager) = self.schema_manager {
binder = binder.with_schema_manager(schema_manager.clone());
}
binder = binder.with_macro_manager(self.macro_manager.clone());
binder.bind(ast).map(Some)
}
}