uqa_sql/catalog/stored_view/
restoration.rs1use super::StoredView;
9use crate::{catalog::roles::guards::RoleCatalogGuards, plan::QueryPlan, RowSchema};
10use std::collections::{BTreeMap, BTreeSet};
11use uqa_core::RelationIdentity;
12
13mod collations;
14pub use collations::view_metadata_dependency_order;
15
16#[derive(serde::Deserialize)]
17#[serde(untagged)]
18pub enum RestoredView {
19 Current(super::StoredViewDefinition),
20 Legacy(QueryPlan),
21}
22
23pub fn validate_restored_view_object_ids(
24 views: &BTreeMap<RelationIdentity, StoredView>,
25) -> Result<(), String> {
26 let mut object_ids = BTreeSet::new();
27 let mut oids = BTreeSet::new();
28 for (relation, view) in views {
29 if !object_ids.insert(view.object_id) {
30 return Err(format!(
31 "view `{}` has a duplicate object identity",
32 relation.qualified_name()
33 ));
34 }
35 if let Some(recorded) = view.catalog_oids {
36 if !recorded.is_valid_for(
37 crate::catalog::relation_oids::RelationOidKind::View,
38 &view.object_id,
39 ) || !recorded.claimed().all(|oid| oids.insert(oid))
40 {
41 return Err(format!(
42 "view `{}` records invalid catalog OIDs",
43 relation.qualified_name()
44 ));
45 }
46 }
47 }
48 Ok(())
49}
50
51pub fn validate_restored_view_security(
52 roles: &dyn RoleCatalogGuards,
53 view_name: &str,
54 view: &StoredView,
55) -> Result<(), String> {
56 view.security
57 .validate(view.output_columns.as_deref(), &roles.role_definitions())
58 .map_err(|error| format!("view `{view_name}` has invalid privilege metadata: {error}"))?;
59 Ok(())
60}
61pub fn validate_migrated_view_security(
62 roles: &dyn RoleCatalogGuards,
63 views: &BTreeMap<RelationIdentity, StoredView>,
64) -> Result<(), String> {
65 for (relation, view) in views {
66 let output_columns = view.output_columns.as_deref().ok_or_else(|| {
67 format!(
68 "view `{}` has no public column metadata after catalog migration",
69 relation.qualified_name()
70 )
71 })?;
72 view.security
73 .validate(Some(output_columns), &roles.role_definitions())
74 .map_err(|error| {
75 format!(
76 "view `{}` has invalid privilege metadata after migration: {error}",
77 relation.qualified_name()
78 )
79 })?;
80 }
81 Ok(())
82}
83pub fn restored_view_output_columns(schema: &RowSchema) -> Vec<String> {
84 schema
85 .columns()
86 .iter()
87 .enumerate()
88 .map(|(position, column)| schema.public_name(position).unwrap_or(column).to_string())
89 .collect()
90}
91
92#[cfg(test)]
93mod tests;