uqa_sql/schema/
foreign_servers.rs1use crate::{
10 catalog::{
11 foreign_server::ForeignServerDefinition,
12 roles::{guards::RoleCatalogGuards, role_inherits, RoleReferenceNames},
13 },
14 SQLError, SQLNotice,
15};
16use std::collections::BTreeMap;
17
18pub fn creation_options(
20 options: &[(String, String)],
21) -> Result<BTreeMap<String, String>, SQLError> {
22 let mut result = BTreeMap::new();
23 for (name, value) in options {
24 if result.insert(name.clone(), value.clone()).is_some() {
25 return Err(SQLError::Routine {
26 sqlstate: "42710".into(),
27 message: format!("option \"{name}\" provided more than once"),
28 });
29 }
30 }
31 if let Some((name, _)) = options.iter().find(|(name, _)| name.contains('=')) {
32 return Err(SQLError::Routine {
33 sqlstate: "22023".into(),
34 message: format!("invalid option name \"{name}\": must not contain \"=\""),
35 });
36 }
37 Ok(result)
38}
39
40pub fn ensure_drop_authority(
42 server: &ForeignServerDefinition,
43 session: &dyn RoleReferenceNames,
44 catalog: &dyn RoleCatalogGuards,
45) -> Result<(), SQLError> {
46 let current = session.current_role();
47 let roles = catalog.role_definitions();
48 let memberships = catalog.role_memberships();
49 if role_inherits(&roles, &memberships, ¤t, &server.metadata.owner) {
50 return Ok(());
51 }
52 Err(SQLError::Routine {
53 sqlstate: "42501".into(),
54 message: format!("must be owner of foreign server {}", server.name),
55 })
56}
57
58pub fn missing_server(name: &str) -> SQLError {
59 SQLError::Routine {
60 sqlstate: "42704".into(),
61 message: format!("server \"{name}\" does not exist"),
62 }
63}
64
65pub fn missing_server_notice(name: &str) -> SQLNotice {
66 SQLNotice::notice(format!("server \"{name}\" does not exist, skipping"))
67}
68
69#[cfg(test)]
70mod tests;