pub struct RawArray { /* private fields */ }
Expand description
An aligned, dereferenceable NonNull<ArrayType>
with low-level accessors.
It offers safe accessors to the fields of pg_sys::ArrayType and mostly-safe accessors
to the “dynamic fields” of the defined Postgres varlena array, but only requires validity
of ArrayType itself and the dimensions slice (always valid if ndim == 0
).
This means the NonNull pointers that are returned may not be valid to read.
Validating the correctness of the entire array requires a bit more effort.
It is not Copy or Clone to make it slightly harder to misuse versus *mut ArrayType.
However, &mut self
accessors do not give lifetimes to returned NonNull<[T]>
!
Instead, these are raw pointers, and &mut RawArray
only makes &RawArray
safer.
The reason RawArray works almost entirely with raw pointers is that
it is not currently valid to go from &mut ArrayType
to *mut ArrayType
,
take an offset beyond ArrayType’s fields, and then create a new slice there
and read from that. The result is currently undefined behavior,
though with emphasis on “undefined”: it may become defined in the future of Rust.
At the current moment, however, it is best to exercise an abundance of caution.
§On sizes and subscripts
Postgres uses C’s int
(c_int
in Rust) for sizes, and Rust uses usize.
Thus various functions of RawArray return c_int
values, but you must convert to usize.
On 32-bit or 64-bit machines with 32-bit c_int
s, you may losslessly upgrade as usize
,
except with negative indices, which Postgres asserts against creating.
PGX currently only intentionally supports 64-bit machines,
and while support for ILP32 or I64LP128 C data models may become possible,
PGX will not support 16-bit machines in any practical case, even though Rust does.
Implementations§
Source§impl RawArray
impl RawArray
Sourcepub unsafe fn from_ptr(ptr: NonNull<ArrayType>) -> RawArray
pub unsafe fn from_ptr(ptr: NonNull<ArrayType>) -> RawArray
Returns a handle to the raw array header.
§Safety
When calling this method, you have to ensure that all of the following is true:
- The pointer must be properly aligned.
- It must be “dereferenceable” in the sense defined in the std documentation.
- The pointer must point to an initialized instance of pg_sys::ArrayType.
- The
ndim
field must be a correct value, or 0, sodims
is aligned and readable, or no data is actually read at all. - This is a unique, “owning pointer” for the varlena, so it won’t be aliased while held, and it points to data in the Postgres ArrayType format.
It should be noted that despite all these requirements, RawArray has no lifetime, nor produces slices with such, so it can still be racy and unsafe!
Sourcepub unsafe fn from_array<T: FromDatum>(arr: Array<'_, T>) -> Option<RawArray>
pub unsafe fn from_array<T: FromDatum>(arr: Array<'_, T>) -> Option<RawArray>
§Safety
Array must have been made from an ArrayType pointer, or a null value, as-if RawArray::from_ptr.
Sourcepub fn dims(&self) -> &[c_int] ⓘ
pub fn dims(&self) -> &[c_int] ⓘ
A slice of the dimensions.
Oxidized form of ARR_DIMS(ArrayType*). The length will be within 0..=pg_sys::MAXDIM.
Safe to use because validity of this slice was asserted on construction.
Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
The flattened length of the array over every single element. Includes all items, even the ones that might be null.
Sourcepub fn nulls(&mut self) -> Option<NonNull<[u8]>>
pub fn nulls(&mut self) -> Option<NonNull<[u8]>>
Oxidized form of ARR_NULLBITMAP(ArrayType*)
If this returns None, the array cannot have nulls. If this returns Some, it points to the bitslice that marks nulls in this array.
Note that unlike the is_null: bool
that appears elsewhere, here a 0 bit is null,
or possibly out of bounds for the final byte of the bitslice.
Note that if this is None, that does not mean it’s always okay to read! If len is 0, then this slice will be valid for 0 bytes.
Sourcepub fn nulls_bitslice(&mut self) -> Option<NonNull<BitSlice<u8>>>
pub fn nulls_bitslice(&mut self) -> Option<NonNull<BitSlice<u8>>>
The bitvec equivalent of RawArray::nulls.
If this returns None
, the array cannot have nulls.
If this returns Some
, it points to the bitslice that marks nulls in this array.
Note that unlike the is_null: bool
that appears elsewhere, here a 0 bit is null.
Unlike RawArray::nulls, this slice is bit-exact in length, so there are no caveats for safely-used BitSlices.
Sourcepub unsafe fn any_nulls(&self) -> bool
pub unsafe fn any_nulls(&self) -> bool
Checks the array for any NULL values by assuming it is a proper varlena array,
§Safety
- This requires every index is valid to read or correctly marked as null.
Sourcepub fn data<T>(&mut self) -> NonNull<[T]>
pub fn data<T>(&mut self) -> NonNull<[T]>
Oxidized form of ARR_DATA_PTR(ArrayType*)
§Safety
While this function is safe to call, using the slice may risk undefined behavior.
The raw slice is not guaranteed to be legible at any given index as T,
e.g. it may be an “SQL null” if so indicated in the null bitmap.
As a result, it is dangerous to reborrow this as &[T]
or &mut [T]
unless the type considers all bitpatterns to be valid values.
That is the primary reason this returns NonNull<[T]>
. If it returned &mut [T]
,
then for many possible types that can be undefined behavior,
as it would assert each particular index was a valid T
.
A Rust borrow, including of a slice, will always be
- non-null
- aligned
- validly initialized, except in the case of MaybeUninit types It is reasonable to assume data Postgres exposes logically to SQL is initialized, but it may be incorrect to assume data Postgres has marked “null” otherwise follows Rust-level initialization requirements.
As Postgres handles alignment requirements in its own particular ways, it is up to you to validate that each index is aligned correctly. The first element should be correctly aligned to the type, but that is not certain. Successive indices are even less likely to match the data type you want unless Postgres also uses an identical layout.
This returns a slice to make it somewhat harder to fail to read it correctly. However, it should be noted that a len 0 slice may not be read via raw pointers.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for RawArray
impl RefUnwindSafe for RawArray
impl !Send for RawArray
impl !Sync for RawArray
impl Unpin for RawArray
impl UnwindSafe for RawArray
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
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§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.Source§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.Source§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.Source§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.Source§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.Source§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.Source§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.Source§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.Source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§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 moreSource§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 moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self
, then passes self.as_ref()
into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self
, then passes self.as_mut()
into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self
, then passes self.deref()
into the pipe function.Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B>
of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B>
of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R>
view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R>
view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target
of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target
of a value. Read moreSource§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.Source§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.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow()
only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut()
only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref()
only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut()
only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref()
only in debug builds, and is erased in release
builds.