Skip to main content

uqa_sql/schema/namespaces/
creation.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! Resolve schema authorization before checking the invoking role's database privileges.
8use crate::catalog::roles::RoleReference;
9use crate::{
10    ast::SchemaAuthorization,
11    catalog::roles::{guards::RoleCatalogGuards, RoleReferenceNames},
12    SQLError,
13};
14pub struct SchemaCreationTarget {
15    pub name: String,
16    pub role_owner: RoleReference,
17}
18pub fn schema_creation_target(
19    names: &dyn RoleReferenceNames,
20    roles: &dyn RoleCatalogGuards,
21    current_user: &RoleReference,
22    name: Option<&str>,
23    authorization: Option<&SchemaAuthorization>,
24) -> Result<SchemaCreationTarget, SQLError> {
25    let role_owner = match authorization {
26        None | Some(SchemaAuthorization::CurrentUser) => current_user.clone(),
27        Some(SchemaAuthorization::SessionUser) => names.session_role(),
28        Some(SchemaAuthorization::Role(role)) => role.clone().into(),
29    };
30    let catalog = roles.role_definitions();
31    let owner = role_owner.bind(&catalog)?;
32    Ok(SchemaCreationTarget {
33        name: name.unwrap_or(&owner.name).to_string(),
34        role_owner: RoleReference::Bound(owner.into()),
35    })
36}
37pub fn validate_schema_creation_name(name: &str) -> Result<(), SQLError> {
38    if name.starts_with("pg_") {
39        return Err(SQLError::Diagnostic {
40            sqlstate: "42939".into(),
41            message: format!(r#"unacceptable schema name "{name}""#),
42            detail: Some(r#"The prefix "pg_" is reserved for system schemas."#.into()),
43            hint: None,
44        });
45    }
46    Ok(())
47}
48
49#[cfg(test)]
50mod tests;