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
113/// 式
114#[derive(Debug, Clone, Serialize, Deserialize)]
115#[serde(untagged)]
116pub enum Expr {
117    Var(String),
118    Const(Value),
119    Fn { fn_: String, args: Vec<Expr> },
120}
121
122impl std::fmt::Display for Expr {
123    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
124        match self {
125            Expr::Var(v) => write!(f, "{}", v),
126            Expr::Const(val) => write!(f, "{:?}", val),
127            Expr::Fn { fn_, args } => {
128                write!(f, "{}({})", fn_, args.len())
129            }
130        }
131    }
132}
133
134/// 集計関数
135#[derive(Debug, Clone, Serialize, Deserialize)]
136pub struct Aggregation {
137    pub fn_: String,
138    pub args: Vec<String>,
139    pub as_: String,
140}
141
142/// ソートキー
143#[derive(Debug, Clone, Serialize, Deserialize)]
144pub struct SortKey {
145    pub expr: Expr,
146    pub asc: bool,
147}
148
149/// 論理プラン
150#[derive(Debug, Clone, Serialize, Deserialize)]
151pub struct PlanIR {
152    pub plan: LogicalOp,
153    #[serde(skip_serializing_if = "Option::is_none")]
154    pub limit: Option<usize>,
155}
156
157/// 実行結果行
158#[derive(Debug, Clone)]
159pub struct Row {
160    pub values: HashMap<String, Value>,
161}
162
163/// 結果ストリーム
164pub type RowStream = Vec<Row>;