kotoba_core/ir/
query.rs

1//! Query-IR(GQL論理プラン代数)
2
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5use crate::types::*;
6
7/// 論理演算子
8#[derive(Debug, Clone, Serialize, Deserialize)]
9#[serde(tag = "op")]
10pub enum LogicalOp {
11    /// ノードスキャン
12    NodeScan {
13        label: Label,
14        as_: String,
15        #[serde(skip_serializing_if = "Option::is_none")]
16        props: Option<Properties>,
17    },
18
19    /// インデックススキャン
20    IndexScan {
21        label: Label,
22        as_: String,
23        index: String,
24        value: Value,
25    },
26
27    /// フィルタ
28    Filter {
29        pred: Predicate,
30        input: Box<LogicalOp>,
31    },
32
33    /// エッジ展開
34    Expand {
35        edge: EdgePattern,
36        to_as: String,
37        from: Box<LogicalOp>,
38    },
39
40    /// 結合
41    Join {
42        left: Box<LogicalOp>,
43        right: Box<LogicalOp>,
44        on: Vec<String>,  // 結合キー
45    },
46
47    /// 射影
48    Project {
49        cols: Vec<String>,
50        input: Box<LogicalOp>,
51    },
52
53    /// グループ化
54    Group {
55        keys: Vec<String>,
56        aggregations: Vec<Aggregation>,
57        input: Box<LogicalOp>,
58    },
59
60    /// ソート
61    Sort {
62        keys: Vec<SortKey>,
63        input: Box<LogicalOp>,
64    },
65
66    /// リミット
67    Limit {
68        count: usize,
69        input: Box<LogicalOp>,
70    },
71
72    /// 重複除去
73    Distinct {
74        input: Box<LogicalOp>,
75    },
76}
77
78/// エッジパターン
79#[derive(Debug, Clone, Serialize, Deserialize)]
80pub struct EdgePattern {
81    pub label: Label,
82    pub dir: Direction,
83    #[serde(skip_serializing_if = "Option::is_none")]
84    pub props: Option<Properties>,
85}
86
87/// 方向
88#[derive(Debug, Clone, Serialize, Deserialize)]
89pub enum Direction {
90    #[serde(rename = "out")]
91    Out,
92    #[serde(rename = "in")]
93    In,
94    #[serde(rename = "both")]
95    Both,
96}
97
98/// 述語
99#[derive(Debug, Clone, Serialize, Deserialize)]
100#[serde(untagged)]
101pub enum Predicate {
102    Eq { eq: [Expr; 2] },
103    Ne { ne: [Expr; 2] },
104    Lt { lt: [Expr; 2] },
105    Le { le: [Expr; 2] },
106    Gt { gt: [Expr; 2] },
107    Ge { ge: [Expr; 2] },
108    And { and: Vec<Predicate> },
109    Or { or: Vec<Predicate> },
110    Not { not: Box<Predicate> },
111}
112
113impl std::fmt::Display for Predicate {
114    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
115        match self {
116            Predicate::Eq { eq } => write!(f, "{} = {}", eq[0], eq[1]),
117            Predicate::Ne { ne } => write!(f, "{} <> {}", ne[0], ne[1]),
118            Predicate::Lt { lt } => write!(f, "{} < {}", lt[0], lt[1]),
119            Predicate::Le { le } => write!(f, "{} <= {}", le[0], le[1]),
120            Predicate::Gt { gt } => write!(f, "{} > {}", gt[0], gt[1]),
121            Predicate::Ge { ge } => write!(f, "{} >= {}", ge[0], ge[1]),
122            Predicate::And { and } => {
123                write!(f, "(")?;
124                for (i, p) in and.iter().enumerate() {
125                    if i > 0 {
126                        write!(f, " AND ")?;
127                    }
128                    write!(f, "{}", p)?;
129                }
130                write!(f, ")")
131            }
132            Predicate::Or { or } => {
133                write!(f, "(")?;
134                for (i, p) in or.iter().enumerate() {
135                    if i > 0 {
136                        write!(f, " OR ")?;
137                    }
138                    write!(f, "{}", p)?;
139                }
140                write!(f, ")")
141            }
142            Predicate::Not { not } => write!(f, "NOT {}", not),
143        }
144    }
145}
146
147/// 式
148#[derive(Debug, Clone, Serialize, Deserialize)]
149#[serde(untagged)]
150pub enum Expr {
151    Var(String),
152    Const(Value),
153    Fn { fn_: String, args: Vec<Expr> },
154}
155
156impl std::fmt::Display for Expr {
157    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
158        match self {
159            Expr::Var(v) => write!(f, "{}", v),
160            Expr::Const(val) => write!(f, "{:?}", val),
161            Expr::Fn { fn_, args } => {
162                write!(f, "{}({})", fn_, args.len())
163            }
164        }
165    }
166}
167
168/// 集計関数
169#[derive(Debug, Clone, Serialize, Deserialize)]
170pub struct Aggregation {
171    pub fn_: String,
172    pub args: Vec<String>,
173    pub as_: String,
174}
175
176/// ソートキー
177#[derive(Debug, Clone, Serialize, Deserialize)]
178pub struct SortKey {
179    pub expr: Expr,
180    pub asc: bool,
181}
182
183/// 論理プラン
184#[derive(Debug, Clone, Serialize, Deserialize)]
185pub struct PlanIR {
186    pub plan: LogicalOp,
187    #[serde(skip_serializing_if = "Option::is_none")]
188    pub limit: Option<usize>,
189}
190
191/// 実行結果行
192#[derive(Debug, Clone)]
193pub struct Row {
194    pub values: HashMap<String, Value>,
195}
196
197/// 結果ストリーム
198pub type RowStream = Vec<Row>;