uqa_sql/catalog/
relation_oids.rs1use serde::{Deserialize, Serialize};
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub enum RelationOidKind {
14 Table,
16 View,
18 ForeignTable,
20 Sequence,
22 CompositeType,
24}
25
26#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
28#[serde(deny_unknown_fields)]
29pub struct RelationCatalogOids {
30 pub relation: u32,
31 #[serde(default, skip_serializing_if = "Option::is_none")]
32 pub row_type: Option<u32>,
33 #[serde(default, skip_serializing_if = "Option::is_none")]
34 pub array_type: Option<u32>,
35 #[serde(default, skip_serializing_if = "Option::is_none")]
36 pub rule: Option<u32>,
37}
38
39impl RelationCatalogOids {
40 #[must_use]
42 pub fn legacy(kind: RelationOidKind, object_id: &[u8; 16]) -> Self {
43 let derive = |label| {
44 u32::try_from(super::oids::stable_object_oid(label, object_id))
45 .expect("derived catalog OIDs fit in u32")
46 };
47 Self {
48 relation: derive("relation"),
49 row_type: (kind != RelationOidKind::Sequence).then(|| derive("rowtype")),
50 array_type: None,
51 rule: (kind == RelationOidKind::View).then(|| derive("view-rule")),
52 }
53 }
54
55 #[must_use]
57 pub fn reltype(&self) -> u32 {
58 self.row_type.unwrap_or(0)
59 }
60
61 pub fn claimed(&self) -> impl Iterator<Item = u32> {
63 [
64 Some(self.relation),
65 self.row_type,
66 self.array_type,
67 self.rule,
68 ]
69 .into_iter()
70 .flatten()
71 }
72
73 #[must_use]
75 pub fn is_valid_for(&self, kind: RelationOidKind) -> bool {
76 let user = |oid: u32| oid >= super::oids::FIRST_NORMAL_OBJECT_ID;
77 let has_row_type = kind != RelationOidKind::Sequence;
78 user(self.relation)
79 && self.row_type.is_some() == has_row_type
80 && self.array_type.is_some() == has_row_type
81 && self.rule.is_some() == (kind == RelationOidKind::View)
82 && self.claimed().all(user)
83 }
84}
85
86#[cfg(test)]
87mod tests;