Struct pgx::array::RawArray

source ·
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_ints, 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§

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, so dims 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!

Safety

Array must have been made from an ArrayType pointer, or a null value, as-if RawArray::from_ptr.

Returns the inner raw pointer to the ArrayType.

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.

The flattened length of the array over every single element. Includes all items, even the ones that might be null.

Accessor for ArrayType’s elemtype.

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.

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.

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.

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§

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more
Converts self into T using Into<T>. Read more
Causes self to use its Binary implementation when Debug-formatted.
Causes self to use its Display implementation when Debug-formatted. Read more
Causes self to use its LowerExp implementation when Debug-formatted. Read more
Causes self to use its LowerHex implementation when Debug-formatted. Read more
Causes self to use its Octal implementation when Debug-formatted.
Causes self to use its Pointer implementation when Debug-formatted. Read more
Causes self to use its UpperExp implementation when Debug-formatted. Read more
Causes self to use its UpperHex implementation when Debug-formatted. Read more
Formats each item in a sequence. Read more

Returns the argument unchanged.

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Instruments this type with the current Span, returning an Instrumented wrapper. Read more

Calls U::from(self).

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

Pipes by value. This is generally the method you want to use. Read more
Borrows self and passes that borrow into the pipe function. Read more
Mutably borrows self and passes that borrow into the pipe function. Read more
Borrows self, then passes self.borrow() into the pipe function. Read more
Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
Borrows self, then passes self.as_ref() into the pipe function.
Mutably borrows self, then passes self.as_mut() into the pipe function. Read more
Borrows self, then passes self.deref() into the pipe function.
Mutably borrows self, then passes self.deref_mut() into the pipe function. Read more
Immutable access to a value. Read more
Mutable access to a value. Read more
Immutable access to the Borrow<B> of a value. Read more
Mutable access to the BorrowMut<B> of a value. Read more
Immutable access to the AsRef<R> view of a value. Read more
Mutable access to the AsMut<R> view of a value. Read more
Immutable access to the Deref::Target of a value. Read more
Mutable access to the Deref::Target of a value. Read more
Calls .tap() only in debug builds, and is erased in release builds.
Calls .tap_mut() only in debug builds, and is erased in release builds. Read more
Calls .tap_borrow() only in debug builds, and is erased in release builds. Read more
Calls .tap_borrow_mut() only in debug builds, and is erased in release builds. Read more
Calls .tap_ref() only in debug builds, and is erased in release builds. Read more
Calls .tap_ref_mut() only in debug builds, and is erased in release builds. Read more
Calls .tap_deref() only in debug builds, and is erased in release builds. Read more
Calls .tap_deref_mut() only in debug builds, and is erased in release builds. Read more
Attempts to convert self into T using TryInto<T>. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more