Skip to main content

feldera_ir/
hir.rs

1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5use utoipa::ToSchema;
6
7/// The Calcite plan representation of a dataflow graph.
8#[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    /// This is a vector where the elements concatenated form a fully qualified table name.
22    ///
23    /// e.g., usually is of the form `[$namespace, $table] / [schema, table]`
24    #[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}