Skip to main content

NullOrder

Enum NullOrder 

Source
#[non_exhaustive]
pub enum NullOrder { First, Last, }
Expand description

Where the nulls of an order space sort: below every value or above every value, as SQL’s NULLS FIRST and NULLS LAST.

A space takes a policy when it is made, like its target and context, and every term of it agrees. This is the policy as a value, for a target chosen while the program runs: scheme.target(OrderTarget::I32).nulls(NullOrder::Last). On a marker target the policy is a marker too, First or Last, each standing for one of these through NullPolicy: scheme.target(I32).nulls(Last). Without one, a null has no order term, as before. With one, every null in the space, typed or plain, encodes to the space’s sentinel: the lowest code the target’s width holds (all 0x00) for First, the highest (all 0xFF) for Last. Only a fixed-width target takes a policy.

For an integer or uuid target the policy costs one value: the target’s maximum, whose code the nulls-last sentinel already is, is refused with NormalizeError::Reserved. Under nulls-first every code moves up by one, so zero, the minimum and the nil uuid stay encodable and the maximum is again the one refused. A column that places nulls cannot hold its type’s maximum. Float, date, timestamp and decimal codes never reach either extreme, so those targets shift nothing and refuse nothing.

Each policy is its own set of domain labels, and the salt binds the label, so a term of a space that places nulls never compares with a term of a plain space of the same target.

§What a placed null reveals

In any order index whose stored terms compare with each other, the nulls are visible as the tied group at one end, and in a sparse domain as the group that differs from every value at the top of the encoding. That is never more than the SQL NULL it replaces, which needs no inference to read.

§Examples

use vitaminc_ore::{domain, order_with_nulls, Int, NormalizeError, NullOrder, OrderTarget, Physical};
use vitaminc_protected::Controlled;

let null = order_with_nulls(OrderTarget::U16, NullOrder::First, None, Physical::Null)?;
assert_eq!(null.domain(), domain::UINT16_NULLS_FIRST);
assert_eq!(null.bytes().risky_ref(), &[0x00, 0x00]);

// Zero moves up by one, so it stays above the null.
let zero = order_with_nulls(OrderTarget::U16, NullOrder::First, None, Physical::Int(Int::U16(0)))?;
assert_eq!(zero.bytes().risky_ref(), &[0x00, 0x01]);

// The maximum is the one value refused.
let max = Physical::Int(Int::U16(u16::MAX));
assert_eq!(
    order_with_nulls(OrderTarget::U16, NullOrder::First, None, max).err(),
    Some(NormalizeError::Reserved)
);

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

First

Nulls sort below every value, as NULLS FIRST.

§

Last

Nulls sort above every value, as NULLS LAST.

Trait Implementations§

Source§

impl Clone for NullOrder

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

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

Performs copy-assignment from source. Read more
Source§

impl Copy for NullOrder

Source§

impl Debug for NullOrder

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for NullOrder

Source§

impl Hash for NullOrder

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for NullOrder

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for NullOrder

Auto Trait Implementations§

Blanket Implementations§

Source§

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

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

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

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

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

Source§

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

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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 T
where 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.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<S, T, P> Supports<Nulls<T, P>> for S
where S: Supports<T> + ?Sized, T: FixedWidth, P: NullPolicy,

Source§

fn supports(target: Nulls<T, P>) -> bool

Whether the scheme takes terms of target. For a marker, true (the impl exists); for an OrderTarget, the scheme’s list.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

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
Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

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

Source§

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.