use rupg_common::{Error, Result, SqlState};
use rupg_types::Value;
use crate::{Call, bad_value};
const RECOVERY_COLUMNS: usize = 9;
pub(crate) fn none(_: &Call<'_>, _: &[Value]) -> Result<Vec<Vec<Value>>> {
Ok(Vec::new())
}
const PLPGSQL: (&str, &str, &str, &str) =
("plpgsql", "1.0", "$system", "PL/pgSQL procedural language");
pub(crate) fn extensions(_: &Call<'_>, _: &[Value]) -> Result<Vec<Vec<Value>>> {
let (name, version, location, comment) = PLPGSQL;
Ok(vec![vec![
Value::text(name),
Value::text(version),
Value::text(location),
Value::text(comment),
]])
}
pub(crate) fn extension_versions(_: &Call<'_>, _: &[Value]) -> Result<Vec<Vec<Value>>> {
let (name, version, location, comment) = PLPGSQL;
Ok(vec![vec![
Value::text(name),
Value::text(version),
Value::Bool(true),
Value::Bool(true),
Value::Bool(false),
Value::text("pg_catalog"),
Value::Null,
Value::text(location),
Value::text(comment),
]])
}
const CONFIG_NAMES: [&str; 23] = [
"BINDIR",
"DOCDIR",
"HTMLDIR",
"INCLUDEDIR",
"PKGINCLUDEDIR",
"INCLUDEDIR-SERVER",
"LIBDIR",
"PKGLIBDIR",
"LOCALEDIR",
"MANDIR",
"SHAREDIR",
"SYSCONFDIR",
"PGXS",
"CONFIGURE",
"CC",
"CPPFLAGS",
"CFLAGS",
"CFLAGS_SL",
"LDFLAGS",
"LDFLAGS_EX",
"LDFLAGS_SL",
"LIBS",
"VERSION",
];
pub(crate) fn config(call: &Call<'_>, _: &[Value]) -> Result<Vec<Vec<Value>>> {
let version = call.session.setting("server_version").unwrap_or_default();
Ok(CONFIG_NAMES
.iter()
.map(|&name| {
let setting = match name {
"VERSION" => format!("PostgreSQL {version}"),
_ => "not recorded".to_owned(),
};
vec![Value::text(name), Value::text(setting)]
})
.collect())
}
pub(crate) fn recovery(_: &Call<'_>, _: &[Value]) -> Result<Vec<Vec<Value>>> {
Ok(vec![vec![Value::Null; RECOVERY_COLUMNS]])
}
pub(crate) fn shmem_numa(_: &Call<'_>, _: &[Value]) -> Result<Vec<Vec<Value>>> {
Err(Error::new(
SqlState::INTERNAL_ERROR,
"libnuma initialization failed or NUMA is not supported on this platform",
))
}
pub(crate) fn mcv_list_items(_: &Call<'_>, _: &[Value]) -> Result<Vec<Vec<Value>>> {
Err(Error::internal("pg_mcv_list_items got a value, but no pg_mcv_list value can exist"))
}
fn no_publication(name: &str) -> Error {
Error::new(SqlState::UNDEFINED_OBJECT, format!("publication \"{name}\" does not exist"))
}
pub(crate) fn publication_tables(_: &Call<'_>, args: &[Value]) -> Result<Vec<Vec<Value>>> {
let names: Vec<Option<&Value>> = match args {
[Value::Array(array)] => array.values.iter().map(Option::as_ref).collect(),
_ => args.iter().map(Some).collect(),
};
match names.first() {
None => Ok(Vec::new()),
Some(Some(Value::Text(name))) => Err(no_publication(name)),
Some(Some(_)) => Err(bad_value()),
Some(None) => Err(Error::new(
SqlState::NULL_VALUE_NOT_ALLOWED,
"null array element not allowed in this context",
)),
}
}
pub(crate) fn publication_tables_of(_: &Call<'_>, _: &[Value]) -> Result<Vec<Vec<Value>>> {
Ok(Vec::new())
}
pub(crate) fn publication_sequences(_: &Call<'_>, args: &[Value]) -> Result<Vec<Vec<Value>>> {
let Some(Value::Text(name)) = args.first() else { return Err(bad_value()) };
Err(no_publication(name))
}