Struct pgrx_pg_sys::submodules::datum::Datum
source · pub struct Datum(/* private fields */);
Expand description
Datum is an abstract value that is effectively a union of all scalar types
and all possible pointers in a Postgres context. That is, it is either
“pass-by-value” (if the value fits into the platform’s uintptr_t
) or
“pass-by-reference” (if it does not).
In Rust, it is best to treat this largely as a pointer while passing it around for code that doesn’t care about what the Datum “truly is”. If for some reason it is important to manipulate the address/value without “knowing the type” of the Datum, cast to a pointer and use pointer methods.
Only create Datums from non-pointers when you know you want to pass a value, as
it is erroneous for unsafe
code to dereference the address of “only a value” as a pointer.
It is still a “safe” operation to create such pointers: validity is asserted by dereferencing,
or by creating a safe reference such as &T or &mut T. Also be aware that the validity
of Datum’s Copy is premised on the same implicit issues with pointers being Copy:
while any &T
is live, other *mut T
must not be used to write to that &T
,
and &mut T
implies no other *mut T
even exists outside an &mut T
’s borrowing ancestry.
It is thus of dubious soundness for Rust code to receive *mut T
, create another *mut T
,
cast the first to &mut T
, and then later try to use the second *mut T
to write.
It is sound for Postgres itself to pass a copied pointer as a Datum to Rust code, then later
to mutate that data through its original pointer after Rust creates and releases a &mut T
.
For all intents and purposes, Postgres counts as unsafe
code that may be relying
on you communicating pointers correctly to it. Do not play games with your database.
Implementations§
source§impl Datum
impl Datum
sourcepub fn value(self) -> usize
pub fn value(self) -> usize
Assume the datum is a value and extract the bits from the memory address, interpreting them as an integer.
sourcepub fn cast_mut_ptr<T>(self) -> *mut T
pub fn cast_mut_ptr<T>(self) -> *mut T
Assume the datum is a pointer and cast it to point to T.
It is recommended to explicitly use datum.cast_mut_ptr::<T>()
.