Skip to main content

uqa_sql/catalog/
domain.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7use crate::ast::{ColumnType, CreateDomain};
8use serde::{Deserialize, Serialize};
9use uqa_core::RelationIdentity;
10
11pub fn domain_object_oid(object_id: &[u8; 16]) -> u32 {
12    u32::try_from(super::oids::stable_object_oid("domain", object_id))
13        .expect("catalog OIDs fit in u32")
14}
15
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct StoredDomain {
18    pub object_id: [u8; 16],
19    pub oid: u32,
20    pub identity: RelationIdentity,
21    pub owner: String,
22    pub definition: CreateDomain,
23}
24
25impl StoredDomain {
26    pub fn column_type(&self) -> ColumnType {
27        ColumnType::Domain {
28            schema: self.identity.schema.clone(),
29            name: self.identity.name.clone(),
30            oid: self.oid,
31            base: Box::new(self.definition.base.clone()),
32        }
33    }
34}
35
36/// Definition lookup for domain inheritance and constraint binding.
37pub trait DomainCatalog {
38    fn domain_by_oid(&self, oid: u32) -> Option<StoredDomain>;
39}
40
41pub fn domain_default_expression(
42    catalog: &dyn DomainCatalog,
43    ty: &crate::ColumnType,
44) -> Option<crate::ast::Expr> {
45    let crate::ColumnType::Domain { oid, base, .. } = ty else {
46        return None;
47    };
48    catalog
49        .domain_by_oid(*oid)
50        .and_then(|domain| domain.definition.default)
51        .or_else(|| domain_default_expression(catalog, base))
52}