1use crate::ast::identifiers::ObjectId;
3use crate::model::column::Column;
4use serde::{Deserialize, Serialize};
5use std::collections::HashSet;
6
7#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
8pub enum RelationKind {
9 Table,
10 View,
11 MaterializedView,
12}
13
14#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
15pub enum Persistence {
16 Permanent,
17 Temporary,
18 Unlogged,
19}
20
21#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
22pub struct RelationState {
23 pub id: ObjectId,
24 pub columns: Vec<Column>,
25 pub generation: u64,
26 pub estimated_rows: Option<u64>,
27 pub relpages: Option<u64>,
28 pub kind: RelationKind,
29 pub persistence: Persistence,
30 pub triggers: HashSet<String>,
31 pub policies: HashSet<String>,
32 pub last_analyze: Option<String>,
33 pub last_autoanalyze: Option<String>,
34 pub created_at_tx_depth: usize, }
36
37impl Default for RelationState {
38 fn default() -> Self {
39 Self {
40 id: ObjectId::new("public", "dummy"),
41 columns: Vec::new(),
42 generation: 0,
43 estimated_rows: Some(0),
44 relpages: None,
45 kind: RelationKind::Table,
46 persistence: Persistence::Permanent,
47 triggers: HashSet::new(),
48 policies: HashSet::new(),
49 last_analyze: None,
50 last_autoanalyze: None,
51 created_at_tx_depth: 0,
52 }
53 }
54}
55
56impl RelationState {
57 pub fn new(
58 id: ObjectId,
59 generation: u64,
60 estimated_rows: Option<u64>,
61 kind: RelationKind,
62 persistence: Persistence,
63 created_at_tx_depth: usize,
64 ) -> Self {
65 Self {
66 id,
67 columns: Vec::new(),
68 generation,
69 estimated_rows,
70 relpages: None,
71 kind,
72 persistence,
73 triggers: HashSet::new(),
74 policies: HashSet::new(),
75 last_analyze: None,
76 last_autoanalyze: None,
77 created_at_tx_depth,
78 }
79 }
80
81 pub fn apply_column_action(&mut self, action: &ColumnAction) {
82 match action {
83 ColumnAction::Add {
84 name,
85 data_type,
86 not_null,
87 default,
88 } => {
89 if !self.columns.iter().any(|c| c.name == *name) {
90 self.columns.push(Column {
91 name: name.clone(),
92 data_type: data_type.clone(),
93 default: default.clone(),
94 is_nullable: !not_null,
95 avg_width: None,
96 });
97 }
98 }
99 ColumnAction::Drop { name } => {
100 self.columns.retain(|c| c.name != *name);
101 }
102 ColumnAction::Rename { from, to } => {
103 if let Some(col) = self.columns.iter_mut().find(|c| c.name == *from) {
104 col.name = to.clone();
105 }
106 }
107 ColumnAction::SetNotNull { name } => {
108 if let Some(col) = self.columns.iter_mut().find(|c| c.name == *name) {
109 col.is_nullable = false;
110 }
111 }
112 ColumnAction::DropNotNull { name } => {
113 if let Some(col) = self.columns.iter_mut().find(|c| c.name == *name) {
114 col.is_nullable = true;
115 }
116 }
117 ColumnAction::SetType { name, data_type } => {
118 if let Some(col) = self.columns.iter_mut().find(|c| c.name == *name) {
119 col.data_type = Some(data_type.clone());
120 }
121 }
122 ColumnAction::SetDefault { name, default } => {
123 if let Some(col) = self.columns.iter_mut().find(|c| c.name == *name) {
124 col.default = default.clone();
125 }
126 }
127 }
128 }
129
130 pub fn has_column(&self, name: &str) -> bool {
131 self.columns.iter().any(|c| c.name == name)
132 }
133
134 pub fn get_column(&self, name: &str) -> Option<&Column> {
135 self.columns.iter().find(|c| c.name == name)
136 }
137
138 pub fn is_stale(&self) -> bool {
139 self.last_analyze.is_none() && self.last_autoanalyze.is_none()
140 }
141}
142
143#[derive(Debug, Clone, PartialEq)]
144pub enum ColumnAction {
145 Add {
146 name: String,
147 data_type: Option<String>,
148 not_null: bool,
149 default: Option<crate::analysis::expr_ir::ExprIr>,
150 },
151 Drop {
152 name: String,
153 },
154 Rename {
155 from: String,
156 to: String,
157 },
158 SetNotNull {
159 name: String,
160 },
161 DropNotNull {
162 name: String,
163 },
164 SetType {
165 name: String,
166 data_type: String,
167 },
168 SetDefault {
169 name: String,
170 default: Option<crate::analysis::expr_ir::ExprIr>,
171 },
172}
173
174#[allow(clippy::large_enum_variant)]
175#[derive(Debug, Clone, PartialEq)]
176pub enum RelationOverlay {
177 Present(RelationState),
178 Dropped,
179}