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>
impl<'a> PgTupleDesc<'a>
sourcepub unsafe fn from_pg<'b>(ptr: TupleDesc) -> PgTupleDesc<'b>
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.
sourcepub unsafe fn from_pg_unchecked<'b>(ptr: TupleDesc) -> PgTupleDesc<'b>
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
sourcepub unsafe fn from_pg_copy<'b>(ptr: TupleDesc) -> PgTupleDesc<'b>
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.
sourcepub unsafe fn from_pg_is_copy<'b>(ptr: TupleDesc) -> PgTupleDesc<'b>
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.
sourcepub fn from_relation(parent: &PgRelation) -> PgTupleDesc<'_>
pub fn from_relation(parent: &PgRelation) -> PgTupleDesc<'_>
wrap the pg_sys::TupleDesc contained by the specified PgRelation
sourcepub fn for_composite_type(name: &str) -> Option<PgTupleDesc<'a>>
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,
);
}sourcepub fn for_composite_type_by_oid(typoid: Oid) -> Option<PgTupleDesc<'a>>
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.
sourcepub fn parent(&self) -> Option<&PgRelation>
pub fn parent(&self) -> Option<&PgRelation>
From which relation was this TupleDesc created, if any?
sourcepub fn get(&self, i: usize) -> Option<&FormData_pg_attribute>
pub fn get(&self, i: usize) -> Option<&FormData_pg_attribute>
Get a numbered attribute. Attribute numbers are zero-based
sourcepub fn iter(&self) -> TupleDescIterator<'_> ⓘ
pub fn iter(&self) -> TupleDescIterator<'_> ⓘ
Iterate over our attributes
sourcepub fn into_pg(self) -> *mut TupleDescData
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>>§
Trait Implementations§
source§impl<'a> Clone for PgTupleDesc<'a>
impl<'a> Clone for PgTupleDesc<'a>
source§impl<'a> Deref for PgTupleDesc<'a>
impl<'a> Deref for PgTupleDesc<'a>
§type Target = PgBox<TupleDescData, AllocatedByPostgres>
type Target = PgBox<TupleDescData, AllocatedByPostgres>
source§impl<'a> Drop for PgTupleDesc<'a>
impl<'a> Drop for PgTupleDesc<'a>
source§impl<'a> IntoIterator for PgTupleDesc<'a>
impl<'a> IntoIterator for PgTupleDesc<'a>
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> 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
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§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.§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.§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.§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.§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.§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.§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.§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.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where &'a Self: for<'a> IntoIterator,
§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere Self: Sized,
§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 more§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 more§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,
§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,
§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.§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.§impl<T> Tap for T
impl<T> Tap for T
§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 more§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 more§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 more§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 more§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 more§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 more§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.§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.§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.§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.§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.§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.