uqa_sql/catalog/index/
identity.rs1use super::IndexCatalogIdentity;
10use crate::schema::constraint_metadata::{
11 CatalogObjectAllocator, CatalogOidClass, ConstraintMetadataError, ConstraintMetadataResult,
12};
13use uqa_core::catalog_identity::CatalogObjectIdentity;
14
15impl IndexCatalogIdentity {
16 pub fn validate(&self, table_object_id: [u8; 16]) -> ConstraintMetadataResult<()> {
17 if !self.identity.is_valid()
18 || self.table_object_id == [0; 16]
19 || self.table_object_id != table_object_id
20 || self.physical_key.is_empty()
21 || self.physical_key.contains('\0')
22 {
23 return Err(ConstraintMetadataError::Invalid(
24 "invalid index catalog identity or indexed table incarnation".into(),
25 ));
26 }
27 Ok(())
28 }
29
30 pub fn allocate(
31 table_object_id: [u8; 16],
32 allocate: &mut dyn CatalogObjectAllocator,
33 ) -> ConstraintMetadataResult<Self> {
34 let object_id = allocate.allocate_object_id("index")?;
35 let oid = allocate.allocate_catalog_oid(CatalogOidClass::Relation, &object_id)?;
36 let identity = Self {
37 identity: CatalogObjectIdentity { object_id, oid },
38 table_object_id,
39 physical_key: format!("uqa:index:{:032x}", u128::from_be_bytes(object_id)),
41 };
42 identity.validate(table_object_id)?;
43 Ok(identity)
44 }
45}
46
47#[cfg(test)]
48mod tests {
49 use super::*;
50
51 #[test]
52 fn stored_index_identity_rejects_invalid_addresses_tables_and_physical_keys() {
53 let valid = IndexCatalogIdentity {
54 identity: CatalogObjectIdentity {
55 object_id: [1; 16],
56 oid: 17000,
57 },
58 table_object_id: [2; 16],
59 physical_key: "public.legacy_index".into(),
60 };
61 valid.validate([2; 16]).unwrap();
62 assert!(valid.validate([3; 16]).is_err());
63 for malformed in [
64 IndexCatalogIdentity {
65 table_object_id: [0; 16],
66 ..valid.clone()
67 },
68 IndexCatalogIdentity {
69 physical_key: String::new(),
70 ..valid.clone()
71 },
72 IndexCatalogIdentity {
73 physical_key: "invalid\0key".into(),
74 ..valid.clone()
75 },
76 IndexCatalogIdentity {
77 identity: CatalogObjectIdentity {
78 object_id: [0; 16],
79 ..valid.identity
80 },
81 ..valid.clone()
82 },
83 IndexCatalogIdentity {
84 identity: CatalogObjectIdentity {
85 oid: 0,
86 ..valid.identity
87 },
88 ..valid.clone()
89 },
90 IndexCatalogIdentity {
91 identity: CatalogObjectIdentity {
92 oid: i64::from(u32::MAX) + 1,
93 ..valid.identity
94 },
95 ..valid.clone()
96 },
97 ] {
98 assert!(malformed.validate([2; 16]).is_err());
99 }
100 }
101}