1#![recursion_limit = "256"]
5
6pub mod query;
7pub mod types;
8
9pub use query::executor::core::{OperatorStats, ProfileOutput};
10pub use query::executor::procedure::{
11 ProcedureOutput, ProcedureParam, ProcedureRegistry, ProcedureValueType, RegisteredProcedure,
12};
13pub use query::executor::{Executor, ResultNormalizer};
14pub use query::planner::{CostEstimates, ExplainOutput, IndexUsage, LogicalPlan, QueryPlanner};
15pub use types::{Edge, ExecuteResult, FromValue, Node, Path, QueryCursor, QueryResult, Row, Value};
16pub use uni_cypher::ast::{Query as CypherQuery, TimeTravelSpec};
17
18pub fn validate_read_only(query: &CypherQuery) -> Result<(), String> {
23 use uni_cypher::ast::{Clause, Query, Statement};
24
25 fn check_statement(stmt: &Statement) -> Result<(), String> {
26 for clause in &stmt.clauses {
27 match clause {
28 Clause::Create(_)
29 | Clause::Merge(_)
30 | Clause::Delete(_)
31 | Clause::Set(_)
32 | Clause::Remove(_) => {
33 return Err(
34 "Write clauses (CREATE, MERGE, DELETE, SET, REMOVE) are not allowed \
35 with VERSION AS OF / TIMESTAMP AS OF"
36 .to_string(),
37 );
38 }
39 _ => {}
40 }
41 }
42 Ok(())
43 }
44
45 fn check_query(q: &Query) -> Result<(), String> {
46 match q {
47 Query::Single(stmt) => check_statement(stmt),
48 Query::Union { left, right, .. } => {
49 check_query(left)?;
50 check_query(right)
51 }
52 Query::Explain(inner) => check_query(inner),
53 Query::TimeTravel { query, .. } => check_query(query),
54 Query::Schema(_) | Query::Transaction(_) => {
55 Err("Schema and transaction commands are not allowed \
56 with VERSION AS OF / TIMESTAMP AS OF"
57 .to_string())
58 }
59 }
60 }
61
62 check_query(query)
63}