#![allow(non_camel_case_types)]
use std::fmt;
use crate as pg_sys;
use crate::BuiltinOid;
use crate::Datum;
use pgrx_sql_entity_graph::metadata::{
ArgumentError, ReturnsError, ReturnsRef, SqlMappingRef, SqlTranslatable, TypeOrigin,
};
#[repr(transparent)]
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
#[derive(serde::Deserialize, serde::Serialize)]
pub struct Oid(pub(crate) u32);
impl Oid {
pub const INVALID: Oid = Oid(0);
#[deprecated(since = "0.11.2", note = "safely converts via SPI, use pg_sys::Oid::from(u32)")]
pub const unsafe fn from_u32_unchecked(id: u32) -> Oid {
Oid(id)
}
pub const fn from_u32(id: u32) -> Oid {
Oid(id)
}
pub const fn from_builtin(id: u32) -> Result<Oid, NotBuiltinOid> {
match BuiltinOid::from_u32(id) {
Ok(oid) => Ok(oid.value()),
Err(e) => Err(e),
}
}
pub const fn to_u32(self) -> u32 {
self.0
}
}
impl Default for Oid {
fn default() -> Oid {
Oid::INVALID
}
}
impl fmt::Debug for Oid {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.0, f)
}
}
impl fmt::Display for Oid {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.0, f)
}
}
impl From<u32> for Oid {
fn from(word: u32) -> Oid {
Oid(word)
}
}
impl From<Oid> for u32 {
fn from(oid: Oid) -> u32 {
oid.0
}
}
impl From<Oid> for crate::Datum {
fn from(oid: Oid) -> Self {
Datum::from(oid.0)
}
}
impl From<BuiltinOid> for Oid {
fn from(builtin: BuiltinOid) -> Oid {
builtin.value()
}
}
unsafe impl SqlTranslatable for Oid {
const TYPE_IDENT: &'static str = pgrx_sql_entity_graph::pgrx_resolved_type!(Oid);
const TYPE_ORIGIN: TypeOrigin = TypeOrigin::External;
const ARGUMENT_SQL: Result<SqlMappingRef, ArgumentError> = Ok(SqlMappingRef::literal("oid"));
const RETURN_SQL: Result<ReturnsRef, ReturnsError> =
Ok(ReturnsRef::One(SqlMappingRef::literal("oid")));
}
pub type PgBuiltInOids = BuiltinOid;
#[derive(Debug, Clone, Copy)]
pub enum NotBuiltinOid {
Invalid,
Ambiguous,
TooBig,
}
impl TryFrom<u32> for BuiltinOid {
type Error = NotBuiltinOid;
fn try_from(uint: u32) -> Result<BuiltinOid, NotBuiltinOid> {
BuiltinOid::from_u32(uint)
}
}
impl TryFrom<Oid> for BuiltinOid {
type Error = NotBuiltinOid;
fn try_from(oid: Oid) -> Result<BuiltinOid, NotBuiltinOid> {
BuiltinOid::from_u32(oid.0)
}
}
impl TryFrom<crate::Datum> for BuiltinOid {
type Error = NotBuiltinOid;
fn try_from(datum: crate::Datum) -> Result<BuiltinOid, NotBuiltinOid> {
let uint = u32::try_from(datum.value()).map_err(|_| NotBuiltinOid::TooBig)?;
BuiltinOid::from_u32(uint)
}
}
impl BuiltinOid {
pub const fn value(self) -> pg_sys::Oid {
Oid(self as u32)
}
pub fn oid(self) -> PgOid {
PgOid::from(self)
}
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum PgOid {
Invalid,
Custom(Oid),
BuiltIn(BuiltinOid),
}
impl PgOid {
pub const fn from_untagged(oid: Oid) -> PgOid {
match BuiltinOid::from_u32(oid.0) {
Ok(builtin) => PgOid::BuiltIn(builtin),
Err(NotBuiltinOid::Invalid) => PgOid::Invalid,
Err(NotBuiltinOid::Ambiguous) => PgOid::Custom(oid),
_ => unsafe { core::hint::unreachable_unchecked() },
}
}
}
impl From<BuiltinOid> for PgOid {
fn from(builtin: BuiltinOid) -> PgOid {
PgOid::BuiltIn(builtin)
}
}
impl From<Oid> for PgOid {
fn from(oid: Oid) -> PgOid {
PgOid::from_untagged(oid)
}
}
impl PgOid {
#[inline]
pub const fn value(self) -> pg_sys::Oid {
match self {
PgOid::Invalid => pg_sys::InvalidOid,
PgOid::Custom(custom) => custom,
PgOid::BuiltIn(builtin) => builtin.value(),
}
}
}