Skip to main content

uqa_sql/catalog/security/table_grants/
targets.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! Bind GRANT relation identities without collapsing missing-schema diagnostics.
8use super::ResolvedTableGrantTarget;
9use crate::{catalog::resolution::RelationResolution, SQLError};
10use uqa_core::RelationIdentity;
11pub trait TableGrantResolution {
12    fn resolve_visible_relation_kind(&self, name: &str) -> Result<RelationResolution, SQLError>;
13}
14pub fn bind_named_table_grants(
15    resolution: &dyn TableGrantResolution,
16    names: &[String],
17) -> Result<Vec<ResolvedTableGrantTarget>, SQLError> {
18    let mut resolved = Vec::with_capacity(names.len());
19    for requested in names {
20        let (name, kind) = match resolution.resolve_visible_relation_kind(requested)? {
21            RelationResolution::Found(name, kind) => (name, kind),
22            RelationResolution::MissingSchema(schema) => {
23                return Err(SQLError::Routine {
24                    sqlstate: "3F000".into(),
25                    message: format!("schema \"{schema}\" does not exist"),
26                })
27            }
28            RelationResolution::MissingRelation => {
29                return Err(SQLError::Routine {
30                    sqlstate: "42P01".into(),
31                    message: format!("relation \"{requested}\" does not exist"),
32                })
33            }
34        };
35        let relation = RelationIdentity::from_legacy_name(&name)
36            .map_err(|error| SQLError::Internal(format!("resolve table `{name}`: {error}")))?;
37        resolved.push(ResolvedTableGrantTarget {
38            requested: requested.clone(),
39            name,
40            relation,
41            kind,
42        });
43    }
44    Ok(resolved)
45}