[−][src]Struct pgx::pgbox::PgBox
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()
. 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 pgx::*; #[pg_guard] pub fn do_something() -> pg_sys::ItemPointer { // postgres-allocate an ItemPointerData structure let mut tid = 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 pgx::*; #[pg_guard] pub fn do_something() { // postgres-allocate an ItemPointerData structure let mut tid = 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 pgx::*; #[pg_guard] pub fn do_something() { // open a relation and project it as a pg_sys::Relation let relid: pg_sys::Oid = 42; let lockmode = pg_sys::AccessShareLock as i32; let relation = PgBox::from_pg(unsafe { 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 }
Safety
TODO:
- Interatctions with Rust's panic!() macro
- Interactions with Poastgres' error!() macro
- Boxing a null pointer -- it works ::from_pg(), ::into_pg(), and ::to_pg(), but will panic!() on all other uses
Implementations
impl<T> PgBox<T>
[src]
pub fn alloc() -> PgBox<T>
[src]
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 pgx::{PgBox, pg_sys}; let ctid = PgBox::<pg_sys::ItemPointerData>::alloc();
pub fn alloc0() -> PgBox<T>
[src]
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 pgx::{PgBox, pg_sys}; let ctid = PgBox::<pg_sys::ItemPointerData>::alloc0();
pub fn alloc_in_context(memory_context: PgMemoryContexts) -> PgBox<T>
[src]
Allocate enough memory for the type'd struct, within the specified Postgres MemoryContext.
The allocated memory is uninitalized.
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 pgx::{PgBox, pg_sys, PgMemoryContexts}; let ctid = PgBox::<pg_sys::ItemPointerData>::alloc_in_context(PgMemoryContexts::TopTransactionContext);
pub fn alloc0_in_context(memory_context: PgMemoryContexts) -> PgBox<T>
[src]
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 pgx::{PgBox, pg_sys, PgMemoryContexts}; let ctid = PgBox::<pg_sys::ItemPointerData>::alloc0_in_context(PgMemoryContexts::TopTransactionContext);
pub fn alloc_node(tag: PgNode) -> PgBox<T>
[src]
Allocate a struct that can be cast to Postgres' Node
This function automatically fills the struct with zeros and sets
the type_
field to the specified PgNode
pub fn null() -> PgBox<T>
[src]
Box nothing
pub fn from_pg(ptr: *mut T) -> PgBox<T>
[src]
Box a pointer that came from Postgres.
When this PgBox<T>
is dropped, the boxed memory is not freed. Since Postgres
allocated it, Postgres is responsible for freeing it.
pub fn from_rust(ptr: *mut T) -> PgBox<T>
[src]
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()
pub fn is_null(&self) -> bool
[src]
Are we boxing a NULL?
pub fn as_ptr(&self) -> *mut T
[src]
Return the boxed pointer, so that it can be passed back into a Postgres function
pub fn into_pg(self) -> *mut T
[src]
Useful for returning the boxed pointer back to Postgres (as a return value, for example).
The boxed pointer is not free'd by Rust
pub fn with<F: FnOnce(&mut PgBox<T>)>(ptr: *mut T, func: F)
[src]
Execute a closure with a mutable, PgBox
'd form of the specified ptr
Trait Implementations
impl<T: Debug> Debug for PgBox<T>
[src]
impl<T> Deref for PgBox<T>
[src]
impl<T> DerefMut for PgBox<T>
[src]
impl<T: Debug> Display for PgBox<T>
[src]
impl<T> FromDatum for PgBox<T>
[src]
for user types
unsafe fn from_datum(datum: Datum, is_null: bool, _: Oid) -> Option<PgBox<T>>
[src]
unsafe fn from_datum_in_memory_context(
memory_context: PgMemoryContexts,
datum: usize,
is_null: bool,
_typoid: u32
) -> Option<Self> where
Self: Sized,
[src]
memory_context: PgMemoryContexts,
datum: usize,
is_null: bool,
_typoid: u32
) -> Option<Self> where
Self: Sized,
impl<T> IntoDatum for PgBox<T>
[src]
for user types
Auto Trait Implementations
impl<T> RefUnwindSafe for PgBox<T> where
T: RefUnwindSafe,
T: RefUnwindSafe,
impl<T> !Send for PgBox<T>
impl<T> !Sync for PgBox<T>
impl<T> Unpin for PgBox<T>
impl<T> UnwindSafe for PgBox<T> where
T: RefUnwindSafe,
T: RefUnwindSafe,
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> Same<T> for T
type Output = T
Should always be Self
impl<T> ToString for T where
T: Display + ?Sized,
[src]
T: Display + ?Sized,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<V, T> VZip<V> for T where
V: MultiLane<T>,
V: MultiLane<T>,