[][src]Struct pgx::pgbox::PgBox

pub struct PgBox<T> { /* fields omitted */ }

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]

type Target = T

The resulting type after dereferencing.

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

impl<T> IntoDatum for PgBox<T>[src]

for user types

Auto Trait Implementations

impl<T> RefUnwindSafe for PgBox<T> where
    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

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Sealed<T> for T where
    T: ?Sized

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.