#[repr(transparent)]pub struct PgBox<T, AllocatedBy: WhoAllocated = AllocatedByPostgres> { /* private fields */ }Expand description
Similar to Rust’s Box<T> type, PgBox<T> also represents heap-allocated memory.
However, it represents a heap-allocated pointer that was allocated by Postgres’s memory
allocation functions (palloc, etc). Think of PgBox<T> as a wrapper around an otherwise
opaque Postgres type that is projected as a concrete Rust type.
Depending on its usage, it’ll interoperate correctly with Rust’s Drop semantics, such that the
backing Postgres-allocated memory is pfree()'d when the PgBox<T> is dropped, but it is
possible to effectively return management of the memory back to Postgres (to free on Transaction
end, for example) by calling ::into_pg() or ``::into_pg_boxed()`. This is especially useful
for returning values back to Postgres.
Examples
This example allocates a simple Postgres structure, modifies it, and returns it back to Postgres:
use pgrx::prelude::*;
pub fn do_something() -> pg_sys::ItemPointer {
// postgres-allocate an ItemPointerData structure
let mut tid = unsafe { PgBox::<pg_sys::ItemPointerData>::alloc() };
// set its position to 42
tid.ip_posid = 42;
// return it to Postgres
tid.into_pg()
}A similar example, but instead the PgBox<T>’s backing memory gets freed when the box is
dropped:
use pgrx::prelude::*;
pub fn do_something() {
// postgres-allocate an ItemPointerData structure
let mut tid = unsafe { PgBox::<pg_sys::ItemPointerData>::alloc() };
// set its position to 42
tid.ip_posid = 42;
// tid gets dropped here and as such, gets immediately pfree()'d
}Alternatively, perhaps you want to work with a pointer Postgres gave you as if it were a Rust type, but it can’t be freed on Drop since you don’t own it – Postgres does:
use pgrx::prelude::*;
pub fn do_something() {
// open a relation and project it as a pg_sys::Relation
let relid: pg_sys::Oid = example_rel_oid(42);
let lockmode = pg_sys::AccessShareLock as i32;
let relation = unsafe { PgBox::from_pg(pg_sys::relation_open(relid, lockmode)) };
// do something with/to 'relation'
// ...
// pass the relation back to Postgres
unsafe { pg_sys::relation_close(relation.as_ptr(), lockmode); }
// While the `PgBox` instance gets dropped, the backing Postgres-allocated pointer is
// **not** freed since it came "::from_pg()". We don't own the underlying memory so
// we can't free it
}Implementations§
source§impl<T> PgBox<T, AllocatedByPostgres>
impl<T> PgBox<T, AllocatedByPostgres>
sourcepub unsafe fn from_pg(ptr: *mut T) -> PgBox<T, AllocatedByPostgres>
pub unsafe fn from_pg(ptr: *mut T) -> PgBox<T, AllocatedByPostgres>
Box a pointer that comes from Postgres.
When this PgBox<T> is dropped, the boxed memory is not freed. Since Postgres
allocated it, Postgres is responsible for freeing it.
source§impl<T, AllocatedBy: WhoAllocated> PgBox<T, AllocatedBy>
impl<T, AllocatedBy: WhoAllocated> PgBox<T, AllocatedBy>
sourcepub unsafe fn from_rust(ptr: *mut T) -> PgBox<T, AllocatedByRust>
pub unsafe fn from_rust(ptr: *mut T) -> PgBox<T, AllocatedByRust>
Box a pointer that was allocated within Rust
When this PgBox<T> is dropped, the boxed memory is freed. Since Rust
allocated it, Rust is responsible for freeing it.
If you need to give the boxed pointer to Postgres, call .into_pg()
sourcepub unsafe fn alloc() -> PgBox<T, AllocatedByRust>
pub unsafe fn alloc() -> PgBox<T, AllocatedByRust>
Allocate enough memory for the type’d struct, within Postgres’ CurrentMemoryContext The
allocated memory is uninitialized.
When this object is dropped the backing memory will be pfree’d,
unless it is instead turned into_pg(), at which point it will be freeded
when its owning MemoryContext is deleted by Postgres (likely transaction end).
Examples
use pgrx::{PgBox, pg_sys};
let ctid = unsafe { PgBox::<pg_sys::ItemPointerData>::alloc() };Safety
This function is unsafe as we cannot ensure that the MemoryContext used to allocate will live as long as Rust’s borrow checker expects it to.
It is also unsafe because the allocated T will be uninitialized and that may or may not
be a valid state for T.
sourcepub unsafe fn alloc0() -> PgBox<T, AllocatedByRust>
pub unsafe fn alloc0() -> PgBox<T, AllocatedByRust>
Allocate enough memory for the type’d struct, within Postgres’ CurrentMemoryContext The
allocated memory is zero-filled.
When this object is dropped the backing memory will be pfree’d,
unless it is instead turned into_pg(), at which point it will be freeded
when its owning MemoryContext is deleted by Postgres (likely transaction end).
Examples
use pgrx::{PgBox, pg_sys};
let ctid = unsafe { PgBox::<pg_sys::ItemPointerData>::alloc0() };Safety
This function is unsafe as we cannot ensure that the MemoryContext used to allocate will live as long as Rust’s borrow checker expects it to.
It is also unsafe because the allocated T’s memory will be zerod and that may or may not
be a valid state for T.
sourcepub unsafe fn alloc_in_context(
memory_context: PgMemoryContexts
) -> PgBox<T, AllocatedByRust>
pub unsafe fn alloc_in_context( memory_context: PgMemoryContexts ) -> PgBox<T, AllocatedByRust>
Allocate enough memory for the type’d struct, within the specified Postgres MemoryContext. The allocated memory is uninitialized.
When this object is dropped the backing memory will be pfree’d,
unless it is instead turned into_pg(), at which point it will be freeded
when its owning MemoryContext is deleted by Postgres (likely transaction end).
Examples
use pgrx::{PgBox, pg_sys, PgMemoryContexts};
let ctid = unsafe { PgBox::<pg_sys::ItemPointerData>::alloc_in_context(PgMemoryContexts::TopTransactionContext) };Safety
This function is unsafe as we cannot ensure that the MemoryContext used to allocate will live as long as Rust’s borrow checker expects it to.
It is also unsafe because the allocated T will be uninitialized and that may or may not
be a valid state for T.
sourcepub unsafe fn alloc0_in_context(
memory_context: PgMemoryContexts
) -> PgBox<T, AllocatedByRust>
pub unsafe fn alloc0_in_context( memory_context: PgMemoryContexts ) -> PgBox<T, AllocatedByRust>
Allocate enough memory for the type’d struct, within the specified Postgres MemoryContext. The allocated memory is zero-filled.
When this object is dropped the backing memory will be pfree’d,
unless it is instead turned into_pg(), at which point it will be freeded
when its owning MemoryContext is deleted by Postgres (likely transaction end).
Examples
use pgrx::{PgBox, pg_sys, PgMemoryContexts};
let ctid = unsafe { PgBox::<pg_sys::ItemPointerData>::alloc0_in_context(PgMemoryContexts::TopTransactionContext) };Safety
This function is unsafe as we cannot ensure that the MemoryContext used to allocate will live as long as Rust’s borrow checker expects it to.
It is also unsafe because the allocated T’s memory will be zeroed and that may or may not
be a valid state for T.
sourcepub unsafe fn alloc_node(node_tag: NodeTag) -> PgBox<T, AllocatedByRust>where
T: PgNode,
pub unsafe fn alloc_node(node_tag: NodeTag) -> PgBox<T, AllocatedByRust>where T: PgNode,
Allocate a Postgres pg_sys::Node subtype, using palloc in the CurrentMemoryContext.
The allocated node will have it’s type_ field set to the node_tag argument, and will
otherwise be initialized with all zeros
Examples
use pgrx::{PgBox, pg_sys};
let create_trigger_statement = unsafe { PgBox::<pg_sys::CreateTrigStmt>::alloc_node(pg_sys::NodeTag_T_CreateTrigStmt) };Safety
This function is unsafe as we cannot ensure that the MemoryContext used to allocate will live as long as Rust’s borrow checker expects it to.
It is also the caller’s responsibility to ensure the node_tag is the correct value for
the pg_sys::PgNode type T: pg_sys::PgNode being used here.
sourcepub fn as_ptr(&self) -> *mut T
pub fn as_ptr(&self) -> *mut T
Return the boxed pointer, so that it can be passed back into a Postgres function
sourcepub fn into_pg(self) -> *mut T
pub fn into_pg(self) -> *mut T
Useful for returning the boxed pointer back to Postgres (as a return value, for example).
The boxed pointer is not free’d by Rust
sourcepub fn into_pg_boxed(self) -> PgBox<T, AllocatedByPostgres>
pub fn into_pg_boxed(self) -> PgBox<T, AllocatedByPostgres>
Useful for returning the boxed pointer back to Postgres (as a return value, for example).
The boxed pointer is not free’d by Rust
Trait Implementations§
source§impl<T, AllocatedBy: WhoAllocated> AsRef<T> for PgBox<T, AllocatedBy>
impl<T, AllocatedBy: WhoAllocated> AsRef<T> for PgBox<T, AllocatedBy>
source§impl<T> Clone for PgBox<T, AllocatedByPostgres>where
T: Copy,
impl<T> Clone for PgBox<T, AllocatedByPostgres>where T: Copy,
source§fn clone(&self) -> Self
fn clone(&self) -> Self
Copies the wrapped T into PgMemoryContexts::CurrentMemoryContext.
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moresource§impl<T, AllocatedBy: WhoAllocated> Deref for PgBox<T, AllocatedBy>
impl<T, AllocatedBy: WhoAllocated> Deref for PgBox<T, AllocatedBy>
source§impl<T, AllocatedBy: WhoAllocated> DerefMut for PgBox<T, AllocatedBy>
impl<T, AllocatedBy: WhoAllocated> DerefMut for PgBox<T, AllocatedBy>
source§impl<T, AllocatedBy: WhoAllocated> Drop for PgBox<T, AllocatedBy>
impl<T, AllocatedBy: WhoAllocated> Drop for PgBox<T, AllocatedBy>
source§impl<T> FromDatum for PgBox<T, AllocatedByPostgres>
impl<T> FromDatum for PgBox<T, AllocatedByPostgres>
for user types
source§unsafe fn from_polymorphic_datum(
datum: Datum,
is_null: bool,
_: Oid
) -> Option<Self>
unsafe fn from_polymorphic_datum( datum: Datum, is_null: bool, _: Oid ) -> Option<Self>
from_datum for instantiating polymorphic types
which require preserving the dynamic type metadata. Read moresource§unsafe fn from_datum_in_memory_context(
memory_context: PgMemoryContexts,
datum: Datum,
is_null: bool,
_typoid: Oid
) -> Option<Self>where
Self: Sized,
unsafe fn from_datum_in_memory_context( memory_context: PgMemoryContexts, datum: Datum, is_null: bool, _typoid: Oid ) -> Option<Self>where Self: Sized,
FromDatum::from_datum(...) from within that context. Read moresource§const GET_TYPOID: bool = false
const GET_TYPOID: bool = false
from_datum?source§unsafe fn from_datum(datum: Datum, is_null: bool) -> Option<Self>where
Self: Sized,
unsafe fn from_datum(datum: Datum, is_null: bool) -> Option<Self>where Self: Sized,
source§unsafe fn try_from_datum(
datum: Datum,
is_null: bool,
type_oid: Oid
) -> Result<Option<Self>, TryFromDatumError>where
Self: Sized + IntoDatum,
unsafe fn try_from_datum( datum: Datum, is_null: bool, type_oid: Oid ) -> Result<Option<Self>, TryFromDatumError>where Self: Sized + IntoDatum,
try_from_datum is a convenience wrapper around FromDatum::from_datum that returns a
a Result around an Option, as a Datum can be null. It’s intended to be used in
situations where the caller needs to know whether the type conversion succeeded or failed. Read moresource§unsafe fn try_from_datum_in_memory_context(
memory_context: PgMemoryContexts,
datum: Datum,
is_null: bool,
type_oid: Oid
) -> Result<Option<Self>, TryFromDatumError>where
Self: Sized + IntoDatum,
unsafe fn try_from_datum_in_memory_context( memory_context: PgMemoryContexts, datum: Datum, is_null: bool, type_oid: Oid ) -> Result<Option<Self>, TryFromDatumError>where Self: Sized + IntoDatum,
try_from_datum that switches to the given context to convert from Datumsource§impl<T, AllocatedBy: WhoAllocated> IntoDatum for PgBox<T, AllocatedBy>
impl<T, AllocatedBy: WhoAllocated> IntoDatum for PgBox<T, AllocatedBy>
for user types
source§impl<T, AllocatedBy: WhoAllocated> PartialEq<PgBox<T, AllocatedBy>> for PgBox<T, AllocatedBy>where
T: PartialEq,
impl<T, AllocatedBy: WhoAllocated> PartialEq<PgBox<T, AllocatedBy>> for PgBox<T, AllocatedBy>where T: PartialEq,
source§impl<T: SqlTranslatable> SqlTranslatable for PgBox<T, AllocatedByPostgres>
impl<T: SqlTranslatable> SqlTranslatable for PgBox<T, AllocatedByPostgres>
fn argument_sql() -> Result<SqlMapping, ArgumentError>
fn return_sql() -> Result<Returns, ReturnsError>
fn type_name() -> &'static str
fn variadic() -> bool
fn optional() -> bool
fn entity() -> FunctionMetadataTypeEntity
source§impl<T: SqlTranslatable> SqlTranslatable for PgBox<T, AllocatedByRust>
impl<T: SqlTranslatable> SqlTranslatable for PgBox<T, AllocatedByRust>
fn argument_sql() -> Result<SqlMapping, ArgumentError>
fn return_sql() -> Result<Returns, ReturnsError>
fn type_name() -> &'static str
fn variadic() -> bool
fn optional() -> bool
fn entity() -> FunctionMetadataTypeEntity
impl<T, AllocatedBy: WhoAllocated> Eq for PgBox<T, AllocatedBy>where T: Eq,
Auto Trait Implementations§
impl<T, AllocatedBy> RefUnwindSafe for PgBox<T, AllocatedBy>where AllocatedBy: RefUnwindSafe, T: RefUnwindSafe,
impl<T, AllocatedBy = AllocatedByPostgres> !Send for PgBox<T, AllocatedBy>
impl<T, AllocatedBy = AllocatedByPostgres> !Sync for PgBox<T, AllocatedBy>
impl<T, AllocatedBy> Unpin for PgBox<T, AllocatedBy>where AllocatedBy: Unpin,
impl<T, AllocatedBy> UnwindSafe for PgBox<T, AllocatedBy>where AllocatedBy: UnwindSafe, T: RefUnwindSafe,
Blanket Implementations§
source§impl<A, T> AsBits<T> for Awhere
A: AsRef<[T]>,
T: BitStore,
impl<A, T> AsBits<T> for Awhere A: AsRef<[T]>, T: BitStore,
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<Q, K> Equivalent<K> for Qwhere
Q: Eq + ?Sized,
K: Borrow<Q> + ?Sized,
impl<Q, K> Equivalent<K> for Qwhere Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,
source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.source§impl<T> FmtForward for T
impl<T> FmtForward for T
source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where Self: Binary,
self to use its Binary implementation when Debug-formatted.source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where Self: Display,
self to use its Display implementation when
Debug-formatted.source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where Self: Octal,
self to use its Octal implementation when Debug-formatted.source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere T: ?Sized,
source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere Self: Sized,
source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere R: 'a,
self and passes that borrow into the pipe function. Read moresource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere R: 'a,
self and passes that borrow into the pipe function. Read moresource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere
Self: Borrow<B>,
B: 'a + ?Sized,
R: 'a,
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere Self: Borrow<B>, B: 'a + ?Sized, R: 'a,
source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R
) -> Rwhere
Self: BorrowMut<B>,
B: 'a + ?Sized,
R: 'a,
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R ) -> Rwhere Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,
source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere
Self: AsRef<U>,
U: 'a + ?Sized,
R: 'a,
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere Self: AsRef<U>, U: 'a + ?Sized, R: 'a,
self, then passes self.as_ref() into the pipe function.source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere
Self: AsMut<U>,
U: 'a + ?Sized,
R: 'a,
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere Self: AsMut<U>, U: 'a + ?Sized, R: 'a,
self, then passes self.as_mut() into the pipe
function.source§impl<T> Tap for T
impl<T> Tap for T
source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere Self: Borrow<B>, B: ?Sized,
Borrow<B> of a value. Read moresource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere Self: BorrowMut<B>, B: ?Sized,
BorrowMut<B> of a value. Read moresource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere Self: AsRef<R>, R: ?Sized,
AsRef<R> view of a value. Read moresource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere Self: AsMut<R>, R: ?Sized,
AsMut<R> view of a value. Read moresource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere
Self: Deref<Target = T>,
T: ?Sized,
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere Self: Deref<Target = T>, T: ?Sized,
Deref::Target of a value. Read moresource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere
Self: DerefMut<Target = T> + Deref,
T: ?Sized,
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere Self: DerefMut<Target = T> + Deref, T: ?Sized,
Deref::Target of a value. Read moresource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere Self: Borrow<B>, B: ?Sized,
.tap_borrow() only in debug builds, and is erased in release
builds.source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere Self: BorrowMut<B>, B: ?Sized,
.tap_borrow_mut() only in debug builds, and is erased in release
builds.source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere Self: AsRef<R>, R: ?Sized,
.tap_ref() only in debug builds, and is erased in release
builds.source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere Self: AsMut<R>, R: ?Sized,
.tap_ref_mut() only in debug builds, and is erased in release
builds.