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 Self::reserved(table_object_id, CatalogObjectIdentity { object_id, oid })
37 }
38
39 pub fn reserved(
41 table_object_id: [u8; 16],
42 identity: CatalogObjectIdentity,
43 ) -> ConstraintMetadataResult<Self> {
44 let identity = Self {
45 identity,
46 table_object_id,
47 physical_key: format!("uqa:index:{:032x}", u128::from_be_bytes(identity.object_id)),
49 };
50 identity.validate(table_object_id)?;
51 Ok(identity)
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58
59 #[test]
60 fn stored_index_identity_rejects_invalid_addresses_tables_and_physical_keys() {
61 let valid = IndexCatalogIdentity {
62 identity: CatalogObjectIdentity {
63 object_id: [1; 16],
64 oid: 17000,
65 },
66 table_object_id: [2; 16],
67 physical_key: "public.legacy_index".into(),
68 };
69 valid.validate([2; 16]).unwrap();
70 assert!(valid.validate([3; 16]).is_err());
71 for malformed in [
72 IndexCatalogIdentity {
73 table_object_id: [0; 16],
74 ..valid.clone()
75 },
76 IndexCatalogIdentity {
77 physical_key: String::new(),
78 ..valid.clone()
79 },
80 IndexCatalogIdentity {
81 physical_key: "invalid\0key".into(),
82 ..valid.clone()
83 },
84 IndexCatalogIdentity {
85 identity: CatalogObjectIdentity {
86 object_id: [0; 16],
87 ..valid.identity
88 },
89 ..valid.clone()
90 },
91 IndexCatalogIdentity {
92 identity: CatalogObjectIdentity {
93 oid: 0,
94 ..valid.identity
95 },
96 ..valid.clone()
97 },
98 IndexCatalogIdentity {
99 identity: CatalogObjectIdentity {
100 oid: i64::from(u32::MAX) + 1,
101 ..valid.identity
102 },
103 ..valid.clone()
104 },
105 ] {
106 assert!(malformed.validate([2; 16]).is_err());
107 }
108 }
109}