Struct pgrx::tupdesc::PgTupleDesc

source ·
pub struct PgTupleDesc<'a> { /* private fields */ }
Expand description

This struct is passed around within the backend to describe the structure of tuples. For tuples coming from on-disk relations, the information is collected from the pg_attribute, pg_attrdef, and pg_constraint catalogs. Transient row types (such as the result of a join query) have anonymous TupleDesc structs that generally omit any constraint info; therefore the structure is designed to let the constraints be omitted efficiently.

Note that only user attributes, not system attributes, are mentioned in TupleDesc; with the exception that tdhasoid indicates if OID is present.

If the tupdesc is known to correspond to a named rowtype (such as a table’s rowtype) then tdtypeid identifies that type and tdtypmod is -1. Otherwise tdtypeid is RECORDOID, and tdtypmod can be either -1 for a fully anonymous row type, or a value >= 0 to allow the rowtype to be looked up in the typcache.c type cache.

Note that tdtypeid is never the OID of a domain over composite, even if we are dealing with values that are known (at some higher level) to be of a domain-over-composite type. This is because tdtypeid/tdtypmod need to match up with the type labeling of composite Datums, and those are never explicitly marked as being of a domain type, either.

Tuple descriptors that live in caches (relcache or typcache, at present) are reference-counted: they can be deleted when their reference count goes to zero. Tuple descriptors created by the executor need no reference counting, however: they are simply created in the appropriate memory context and go away when the context is freed. We set the tdrefcount field of such a descriptor to -1, while reference-counted descriptors always have tdrefcount >= 0.

PGRX’s safe wrapper takes care of properly freeing or decrementing reference counts

Implementations§

source§

impl<'a> PgTupleDesc<'a>

source

pub unsafe fn from_pg<'b>(ptr: TupleDesc) -> PgTupleDesc<'b>

Wrap a Postgres-provided pg_sys::TupleDescData. It is assumed the provided TupleDesc is reference counted by Postgres.

The wrapped TupleDesc will have its reference count decremented when this PgTupleDesc instance is dropped.

Safety

This method is unsafe as we cannot validate that the provided pg_sys::TupleDesc is valid or requires reference counting.

source

pub unsafe fn from_pg_unchecked<'b>(ptr: TupleDesc) -> PgTupleDesc<'b>

Wrap a Postgres-provided pg_sys::TupleDescData.

The wrapped TupleDesc will not have its reference count decremented when this PgTupleDesc instance is dropped.

Safety

This method is unsafe as we cannot validate that the provided pg_sys::TupleDesc is valid

source

pub unsafe fn from_pg_copy<'b>(ptr: TupleDesc) -> PgTupleDesc<'b>

Wrap a copy of a pg_sys::TupleDesc. This form is not reference counted and the copy is allocated in the CurrentMemoryContext

When this instance is dropped, the copied TupleDesc is pfree()’d

Safety

This method is unsafe as we cannot validate that the provided pg_sys::TupleDesc is valid or requires reference counting.

source

pub unsafe fn from_pg_is_copy<'b>(ptr: TupleDesc) -> PgTupleDesc<'b>

Similar to ::from_rust_copy(), but assumes the provided TupleDesc is already a copy.

When this instance is dropped, the TupleDesc is pfree()’d

Examples
use pgrx::{pg_sys, PgTupleDesc};
let typid = example_pg_type_oid(42); // a valid pg_type Oid
let typmod = 0; // its corresponding typemod value
let tupdesc = unsafe { PgTupleDesc::from_pg_is_copy(pg_sys::lookup_rowtype_tupdesc_copy(typid, typmod)) };

// assert the tuple descriptor has 12 attributes
assert_eq!(tupdesc.len(), 12);

// the wrapped tupdesc pointer is pfree'd
drop(tupdesc)
Safety

This method is unsafe as we cannot validate that the provided pg_sys::TupleDesc is valid or is actually a copy that requires a pfree() on Drop.

source

pub fn from_relation(parent: &PgRelation) -> PgTupleDesc<'_>

wrap the pg_sys::TupleDesc contained by the specified PgRelation

source

pub fn for_composite_type(name: &str) -> Option<PgTupleDesc<'a>>

Retrieve the tuple description of the shape of a defined composite type

use pgrx::{prelude::*, PgTupleDesc};

Spi::run("CREATE TYPE Dog AS (name text, age int);").unwrap();
let tuple_desc = PgTupleDesc::for_composite_type("Dog").unwrap();
let natts = tuple_desc.len();

unsafe {
    let mut is_null = (0..natts).map(|_| true).collect::<Vec<_>>();

    let heap_tuple_data =
        pg_sys::heap_form_tuple(tuple_desc.as_ptr(), std::ptr::null_mut(), is_null.as_mut_ptr());

    let heap_tuple = PgHeapTuple::from_heap_tuple(
        tuple_desc,
        heap_tuple_data,
    );
}
source

pub fn for_composite_type_by_oid(typoid: Oid) -> Option<PgTupleDesc<'a>>

Similar to PgTupleDesc::for_composite_type() but using the type’s pg_sys::Oid instead of its name.

source

pub fn parent(&self) -> Option<&PgRelation>

From which relation was this TupleDesc created, if any?

source

pub fn oid(&self) -> Oid

What is the pg_type oid of this TupleDesc?

source

pub fn typmod(&self) -> i32

What is the typemod of this TupleDesc?

source

pub fn len(&self) -> usize

How many attributes do we have?

source

pub fn is_empty(&self) -> bool

Do we have attributes?

source

pub fn get(&self, i: usize) -> Option<&FormData_pg_attribute>

Get a numbered attribute. Attribute numbers are zero-based

source

pub fn iter(&self) -> TupleDescIterator<'_>

Iterate over our attributes

source

pub fn into_pg(self) -> *mut TupleDescData

Convert this PgTupleDesc into a pointer for passing into Postgres. You are responsible for releasing or freeing the returned pg_sys::TupleDescData pointer.

Methods from Deref<Target = PgBox<TupleDescData>>§

source

pub fn is_null(&self) -> bool

Are we boxing a NULL?

source

pub fn as_ptr(&self) -> *mut T

Return the boxed pointer, so that it can be passed back into a Postgres function

Trait Implementations§

source§

impl<'a> Clone for PgTupleDesc<'a>

source§

fn clone(&self) -> Self

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a> Deref for PgTupleDesc<'a>

§

type Target = PgBox<TupleDescData, AllocatedByPostgres>

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl<'a> Drop for PgTupleDesc<'a>

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl<'a> IntoIterator for PgTupleDesc<'a>

§

type Item = FormData_pg_attribute

The type of the elements being iterated over.
§

type IntoIter = TupleDescDataIntoIterator<'a>

Which kind of iterator are we turning this into?
source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for PgTupleDesc<'a>

§

impl<'a> !Send for PgTupleDesc<'a>

§

impl<'a> !Sync for PgTupleDesc<'a>

§

impl<'a> Unpin for PgTupleDesc<'a>

§

impl<'a> UnwindSafe for PgTupleDesc<'a>

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> Pipe for Twhere T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

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,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

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,

Mutably borrows self, then passes self.as_mut() into the pipe function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R ) -> Rwhere Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
source§

impl<T> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithTypeIds for Twhere T: 'static + ?Sized,

source§

const ITEM_ID: Lazy<TypeId, fn() -> TypeId> =

source§

const OPTION_ID: Lazy<Option<TypeId>, fn() -> Option<TypeId>> =

source§

const VEC_ID: Lazy<Option<TypeId>, fn() -> Option<TypeId>> =

source§

const VEC_OPTION_ID: Lazy<Option<TypeId>, fn() -> Option<TypeId>> =

source§

const OPTION_VEC_ID: Lazy<Option<TypeId>, fn() -> Option<TypeId>> =

source§

const OPTION_VEC_OPTION_ID: Lazy<Option<TypeId>, fn() -> Option<TypeId>> =

source§

const ARRAY_ID: Lazy<Option<TypeId>, fn() -> Option<TypeId>> =

source§

const OPTION_ARRAY_ID: Lazy<Option<TypeId>, fn() -> Option<TypeId>> =

source§

const VARIADICARRAY_ID: Lazy<Option<TypeId>, fn() -> Option<TypeId>> =

source§

const OPTION_VARIADICARRAY_ID: Lazy<Option<TypeId>, fn() -> Option<TypeId>> =

source§

const VARLENA_ID: Lazy<Option<TypeId>, fn() -> Option<TypeId>> =

source§

const OPTION_VARLENA_ID: Lazy<Option<TypeId>, fn() -> Option<TypeId>> =

source§

fn register_with_refs(map: &mut HashSet<RustSqlMapping>, single_sql: String)where Self: 'static,

source§

fn register_sized_with_refs( _map: &mut HashSet<RustSqlMapping>, _single_sql: String )where Self: 'static,

source§

fn register_sized(_map: &mut HashSet<RustSqlMapping>, _single_sql: String)where Self: 'static,

source§

fn register_varlena_with_refs( _map: &mut HashSet<RustSqlMapping>, _single_sql: String )where Self: 'static,

source§

fn register_varlena(_map: &mut HashSet<RustSqlMapping>, _single_sql: String)where Self: 'static,

source§

fn register_array_with_refs( _map: &mut HashSet<RustSqlMapping>, _single_sql: String )where Self: 'static,

source§

fn register_array(_map: &mut HashSet<RustSqlMapping>, _single_sql: String)where Self: 'static,

source§

fn register(set: &mut HashSet<RustSqlMapping>, single_sql: String)where Self: 'static,