1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5use utoipa::ToSchema;
6
7#[derive(Debug, Deserialize, Serialize, ToSchema, PartialEq, Eq, Clone)]
9pub struct CalcitePlan {
10 pub rels: Vec<Rel>,
11}
12
13#[derive(Debug, Deserialize, Serialize, ToSchema, PartialEq, Eq, Clone)]
14pub struct Rel {
15 pub id: usize,
16 #[serde(default)]
17 pub inputs: Vec<usize>,
18 #[serde(rename = "relOp")]
19 pub rel_op: String,
20
21 #[serde(default)]
25 pub table: Option<Vec<String>>,
26
27 #[serde(default)]
28 pub condition: Option<Condition>,
29
30 #[serde(default)]
31 #[serde(rename = "joinType")]
32 pub join_type: Option<String>,
33
34 #[serde(default)]
35 pub exprs: Option<Vec<Operand>>,
36
37 #[serde(default)]
38 pub fields: Option<Vec<String>>,
39
40 #[serde(default)]
41 pub all: Option<bool>,
42
43 #[serde(default)]
44 pub aggs: Option<Vec<Value>>,
45
46 #[serde(default)]
47 pub group: Option<Vec<usize>>,
48
49 #[serde(flatten)]
50 pub extra: HashMap<String, Value>,
51}
52
53#[derive(Debug, Deserialize, Serialize, ToSchema, PartialEq, Eq, Clone)]
54pub struct Condition {
55 pub op: Option<Op>,
56 pub operands: Option<Vec<Operand>>,
57 #[serde(default)]
58 pub literal: bool,
59
60 #[serde(flatten)]
61 pub extra: HashMap<String, Value>,
62}
63
64#[derive(Debug, Deserialize, Serialize, ToSchema, PartialEq, Eq, Clone)]
65pub struct Op {
66 pub kind: String,
67 pub name: String,
68 pub syntax: String,
69
70 #[serde(flatten)]
71 pub extra: HashMap<String, Value>,
72}
73
74#[derive(Debug, Deserialize, Serialize, ToSchema, PartialEq, Eq, Clone)]
75pub struct Operand {
76 pub input: Option<usize>,
77 pub name: Option<String>,
78
79 #[serde(flatten)]
80 pub extra: HashMap<String, Value>,
81}
82
83#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, PartialEq, Eq)]
84#[serde(untagged)]
85pub enum CalciteId {
86 Partial {
87 partial: usize,
88 },
89 Final {
90 #[serde(rename = "final")]
91 final_: usize,
92 },
93 And {
94 and: Vec<CalciteId>,
95 },
96 Seq {
97 seq: Vec<CalciteId>,
98 },
99 Null,
100}
101
102impl CalciteId {
103 #[allow(unused)]
104 fn contains(&self, id: usize) -> bool {
105 match self {
106 CalciteId::Partial { partial } => *partial == id,
107 CalciteId::Final { final_ } => *final_ == id,
108 CalciteId::And { and } => and.iter().any(|cid| cid.contains(id)),
109 CalciteId::Seq { seq } => seq.iter().any(|cid| cid.contains(id)),
110 CalciteId::Null => false,
111 }
112 }
113}
114
115impl From<CalciteId> for Vec<usize> {
116 fn from(val: CalciteId) -> Self {
117 match val {
118 CalciteId::Partial { partial } => vec![partial],
119 CalciteId::Final { final_ } => vec![final_],
120 CalciteId::And { and } => and.into_iter().flat_map(Into::<Vec<usize>>::into).collect(),
121 CalciteId::Seq { seq } => seq.into_iter().flat_map(Into::<Vec<usize>>::into).collect(),
122 CalciteId::Null => vec![],
123 }
124 }
125}