Skip to main content

uqa_sql/expr/enums/physical/
state.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! Enum function caches belong either to one expression or to the session's type comparison support function.
8
9use std::collections::BTreeMap;
10use std::sync::atomic::{AtomicU32, Ordering};
11use std::sync::{Arc, Mutex, OnceLock};
12
13/// The type selected by one enum comparison call, with independent child calls for anonymous row fields.
14#[derive(Debug, Default)]
15pub struct EnumComparisonState {
16    type_oid: AtomicU32,
17    fields: OnceLock<Mutex<BTreeMap<usize, Arc<Self>>>>,
18}
19
20impl EnumComparisonState {
21    pub(super) fn cached_type(&self) -> Option<u32> {
22        match self.type_oid.load(Ordering::Relaxed) {
23            0 => None,
24            oid => Some(oid),
25        }
26    }
27
28    pub(super) fn remember_type(&self, oid: u32) -> u32 {
29        self.type_oid
30            .compare_exchange(0, oid, Ordering::Relaxed, Ordering::Relaxed)
31            .map_or_else(|existing| existing, |_| oid)
32    }
33
34    pub(in crate::expr) fn field(&self, index: usize) -> Arc<Self> {
35        Arc::clone(
36            self.fields
37                .get_or_init(Mutex::default)
38                .lock()
39                .unwrap_or_else(std::sync::PoisonError::into_inner)
40                .entry(index)
41                .or_default(),
42        )
43    }
44}
45
46/// One comparison-support cache per declared enum type, shared by arrays and records in one session. Transaction rollback and expression disposal do not reset it.
47#[derive(Debug, Default)]
48pub struct EnumTypeComparisonStates {
49    types: Mutex<BTreeMap<u32, Arc<EnumComparisonState>>>,
50}
51
52impl EnumTypeComparisonStates {
53    pub(in crate::expr) fn get(&self, type_oid: u32) -> Arc<EnumComparisonState> {
54        Arc::clone(
55            self.types
56                .lock()
57                .unwrap_or_else(std::sync::PoisonError::into_inner)
58                .entry(type_oid)
59                .or_default(),
60        )
61    }
62}