uqa_sql/catalog/
stored_view.rs1use super::security::BoundTableSecurity;
8use std::ops::{Deref, DerefMut};
9
10#[derive(Debug, Clone, serde::Serialize)]
12pub struct StoredView {
13 #[serde(skip)]
15 pub security: BoundTableSecurity,
16 #[serde(flatten)]
17 pub definition: StoredViewDefinition,
18}
19
20#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
22pub struct StoredViewDefinition {
23 #[serde(default)]
25 pub object_id: [u8; 16],
26 pub query: crate::plan::QueryPlan,
27 #[serde(default, skip_serializing_if = "Option::is_none")]
28 pub output_columns: Option<Vec<String>>,
29 #[serde(default)]
30 pub persistence: crate::ast::RelationPersistence,
31 #[serde(default, skip_serializing_if = "Vec::is_empty")]
32 pub options: Vec<(String, String)>,
33 #[serde(default)]
34 pub kind: StoredViewKind,
35 #[serde(default, skip_serializing_if = "Vec::is_empty")]
36 pub materialized_rows: Vec<crate::ResultRow>,
37 #[serde(default, skip_serializing_if = "Vec::is_empty")]
38 pub materialized_column_types: Vec<Option<crate::ast::ColumnType>>,
39 #[serde(default, skip_serializing_if = "Option::is_none")]
40 pub materialized_column_collations: Option<Vec<u32>>,
41 #[serde(default = "default_view_populated")]
42 pub populated: bool,
43 #[serde(default, skip_serializing_if = "Option::is_none")]
45 pub catalog_oids: Option<super::relation_oids::RelationCatalogOids>,
46 #[serde(default, skip_serializing_if = "Option::is_none")]
47 pub row_type_array_name: Option<String>,
48}
49
50impl StoredViewDefinition {
51 pub fn restore_materialized_collations(
53 &mut self,
54 query_schema: &crate::RowSchema,
55 ) -> Result<(), crate::SQLError> {
56 if self.materialized_column_collations.is_some() {
57 return self.materialized_schema().map(|_| ());
58 }
59 if query_schema.column_types() != self.materialized_column_types {
60 return Err(crate::SQLError::Internal("materialized view query types differ from its stored column types during migration".into()));
61 }
62 crate::schema::table_creation::create_table_as_columns(
63 query_schema,
64 self.output_columns.as_deref().unwrap_or_default(),
65 )?;
66 let collations = (0..query_schema.len())
67 .map(|index| query_schema.column_collation(index).unwrap_or(0))
68 .collect::<Vec<_>>();
69 super::view::materialized_view_schema(
70 self.output_columns.as_deref().unwrap_or_default(),
71 &self.materialized_column_types,
72 Some(&collations),
73 )?;
74 self.materialized_column_collations = Some(collations);
75 Ok(())
76 }
77
78 pub fn materialized_schema(&self) -> Result<crate::RowSchema, crate::SQLError> {
79 super::view::materialized_view_schema(
80 self.output_columns.as_deref().unwrap_or_default(),
81 &self.materialized_column_types,
82 self.materialized_column_collations.as_deref(),
83 )
84 }
85
86 #[must_use]
88 pub fn relation_oids(&self) -> super::relation_oids::RelationCatalogOids {
89 self.catalog_oids.unwrap_or_else(|| {
90 super::relation_oids::RelationCatalogOids::legacy(
91 super::relation_oids::RelationOidKind::View,
92 &self.object_id,
93 )
94 })
95 }
96}
97
98use super::view::StoredViewKind;
99
100const fn default_view_populated() -> bool {
101 true
102}
103
104impl Deref for StoredView {
105 type Target = StoredViewDefinition;
106 fn deref(&self) -> &Self::Target {
107 &self.definition
108 }
109}
110
111impl DerefMut for StoredView {
112 fn deref_mut(&mut self) -> &mut Self::Target {
113 &mut self.definition
114 }
115}
116
117impl StoredView {
118 pub fn security(&self) -> BoundTableSecurity {
119 self.security.clone()
120 }
121
122 pub fn set_security(&mut self, security: BoundTableSecurity) {
123 self.security = security;
124 }
125
126 pub fn security_invoker(&self) -> bool {
127 self.options.iter().any(|(name, value)| {
128 name == "security_invoker" && matches!(value.as_str(), "true" | "on" | "yes" | "1")
129 })
130 }
131}
132
133impl StoredView {
134 pub fn rewrite_definition(&self) -> crate::catalog::view::ViewRewriteDefinition {
135 crate::catalog::view::ViewRewriteDefinition {
136 query: self.query.clone(),
137 output_columns: self.output_columns.clone(),
138 options: self.options.clone(),
139 kind: self.kind,
140 materialized_column_types: self.materialized_column_types.clone(),
141 materialized_column_collations: self.materialized_column_collations.clone(),
142 }
143 }
144 pub fn row_schema(
145 &self,
146 routines: &dyn crate::routines::RoutineResolution,
147 catalog: super::analysis::CatalogReadView,
148 resolution: super::resolution::RelationNameResolution,
149 ) -> Result<crate::RowSchema, crate::SQLError> {
150 self.rewrite_definition()
151 .row_schema(routines, catalog, resolution)
152 }
153}
154
155pub mod dependencies;
156
157pub mod restoration;
158
159pub mod references;
160pub mod removal;