uqa_sql/catalog/
constraints.rs1use uqa_core::RelationIdentity;
8
9#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
10pub struct ConstraintIdentity {
11 pub relation: RelationIdentity,
12 pub name: String,
13 pub object_id: Option<[u8; 16]>,
14}
15
16pub fn constraint_identities_match(left: &ConstraintIdentity, right: &ConstraintIdentity) -> bool {
17 match (left.object_id, right.object_id) {
18 (Some(left), Some(right)) => left == right,
19 _ => left == right,
20 }
21}
22
23pub fn find_live_constraint_identity<'a>(
25 live: &'a [ConstraintIdentity],
26 live_relations: &std::collections::BTreeSet<RelationIdentity>,
27 identity: &ConstraintIdentity,
28) -> Option<&'a ConstraintIdentity> {
29 live.iter()
30 .find(|current| *current == identity)
31 .or_else(|| {
32 live.iter().find(|current| {
33 current.relation == identity.relation
34 && constraint_identities_match(identity, current)
35 })
36 })
37 .or_else(|| {
38 if live_relations.contains(&identity.relation) {
39 return None;
40 }
41 live.iter()
42 .find(|current| constraint_identities_match(identity, current))
43 })
44}
45
46pub fn foreign_key_identity(
47 table: &str,
48 foreign_key: &crate::ast::ForeignKey,
49) -> Result<ConstraintIdentity, crate::SQLError> {
50 let relation = RelationIdentity::from_legacy_name(table).map_err(|error| {
51 crate::SQLError::Internal(format!(
52 "decode foreign-key relation identity '{table}': {error}"
53 ))
54 })?;
55 let name = foreign_key.name.clone().ok_or_else(|| {
56 crate::SQLError::Internal(format!(
57 "foreign key on '{table}' has no materialized constraint name"
58 ))
59 })?;
60 let object_id = foreign_key.object_id.ok_or_else(|| {
61 crate::SQLError::Internal(format!(
62 "foreign key '{name}' on '{table}' has no materialized object identity"
63 ))
64 })?;
65 Ok(ConstraintIdentity {
66 relation,
67 name,
68 object_id: Some(object_id),
69 })
70}
71
72#[cfg(test)]
73mod tests;