#[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
First
Nulls sort below every value, as NULLS FIRST.
Last
Nulls sort above every value, as NULLS LAST.