Skip to main content

mentedb_query/
ast.rs

1//! AST types for MQL statements.
2
3use mentedb_core::edge::EdgeType;
4use mentedb_core::memory::MemoryType;
5use mentedb_core::types::MemoryId;
6use serde::{Deserialize, Serialize};
7use uuid::Uuid;
8
9/// Top-level MQL statement.
10#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
11pub enum Statement {
12    Recall(RecallStatement),
13    Relate(RelateStatement),
14    Forget(ForgetStatement),
15    Consolidate(ConsolidateStatement),
16    Traverse(TraverseStatement),
17}
18
19#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
20pub struct RecallStatement {
21    /// The top-level ANDed leaf filters. For a pure `a AND b AND c` WHERE clause
22    /// this holds every filter and `condition` is `None`, so the planner keeps all
23    /// its index optimizations. When the WHERE uses OR, NOT, or parentheses,
24    /// `condition` carries the full boolean tree and this is empty.
25    pub filters: Vec<Filter>,
26    /// The full boolean WHERE expression, set only when it is not a pure AND of
27    /// leaves (i.e. it contains OR, NOT, or grouping). When present, the executor
28    /// evaluates this tree; the planner falls back to a full scan and lets the
29    /// post-filter decide, so results are always correct even if less optimized.
30    pub condition: Option<Condition>,
31    pub near: Option<Vec<f32>>,
32    pub limit: Option<usize>,
33    pub order_by: Option<OrderBy>,
34}
35
36/// A boolean combination of filters. `Leaf` is a single comparison; `And`/`Or`
37/// combine sub-conditions; `Not` negates one. This is the general form of a WHERE
38/// clause; a pure AND of leaves is represented directly as `RecallStatement.filters`
39/// instead, so the common case needs no tree walk.
40#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
41pub enum Condition {
42    And(Vec<Condition>),
43    Or(Vec<Condition>),
44    Not(Box<Condition>),
45    Leaf(Filter),
46}
47
48#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
49pub struct RelateStatement {
50    pub source: MemoryId,
51    pub target: MemoryId,
52    pub edge_type: EdgeType,
53    pub weight: Option<f32>,
54}
55
56#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
57pub struct ForgetStatement {
58    pub target: MemoryId,
59}
60
61#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
62pub struct ConsolidateStatement {
63    pub filters: Vec<Filter>,
64}
65
66#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
67pub struct TraverseStatement {
68    pub start: MemoryId,
69    pub depth: usize,
70    pub edge_filter: Option<Vec<EdgeType>>,
71}
72
73#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
74pub struct Filter {
75    pub field: Field,
76    pub op: Operator,
77    pub value: Value,
78}
79
80#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
81pub enum Field {
82    Content,
83    Type,
84    Tag,
85    Agent,
86    Space,
87    Salience,
88    Confidence,
89    Created,
90    Accessed,
91    /// Temporal validity at a point in time: `AS OF <t>` keeps only memories that
92    /// were valid at timestamp `t` (valid_from <= t < valid_until), so a query can
93    /// see what was true at a past moment, including facts later superseded.
94    ValidAt,
95}
96
97#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
98pub enum Operator {
99    Eq,
100    Neq,
101    Gt,
102    Lt,
103    Gte,
104    Lte,
105    SimilarTo,
106    /// Set membership: the field equals any element of a list value.
107    In,
108    /// Substring (content) or membership (tag) test against a text value.
109    Contains,
110}
111
112#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
113pub enum Value {
114    Text(String),
115    Number(f64),
116    Integer(i64),
117    Bool(bool),
118    Uuid(Uuid),
119    Vector(Vec<f32>),
120    MemoryType(MemoryType),
121    EdgeType(EdgeType),
122    /// A list of values, for the `IN` operator.
123    List(Vec<Value>),
124}
125
126#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
127pub struct OrderBy {
128    pub field: Field,
129    pub descending: bool,
130}