Expand description
Preflight validation of persisted partition expressions against an ALTER TABLE schema change.
Persisted partition bounds keep the types they were written with. A column whose type changes while a partition expression references it breaks the region on both paths that consume the bounds:
- On scan, the region coerces the bound literal and the new column type to a common comparison type while building the partition predicate. If no common type exists, or the bound cannot be cast to it (a classic example is a millisecond timestamp bound that overflows when the time index column is widened to nanoseconds), every scan of that region fails at that point.
- On write, the region routes rows through
MultiDimPartitionRule::find_region, which compares the persisted bound against row values directly (Value::cmp): a bound whose variant no longer matches the columnโs panics on ordered comparisons and misroutes silently on equality. Only a timestamp unit widening keeps the two comparable โTimestampcomparisons convert units before comparing โ so every other type change of a referenced column is rejected outright, and the widening keeps the scan check below.
Such an ALTER must be rejected before it is submitted to any region, otherwise already-altered regions keep failing while the rest of the table is untouched.
The partition crate depends on common-meta, so this crate cannot depend on
partition back and cannot reuse [partition::expr::PartitionExpr]. The Persisted*
types below mirror the JSON representation of partition::partition::PartitionBound and
partition::expr::PartitionExpr and must be kept in sync with partition/src/partition.rs
and partition/src/expr.rs; round-trip tests in partition run real serialized
expressions through this validator so drift fails in CI. The compatibility check itself
deliberately repeats the same conversion (value -> [ScalarValue]) and the same
comparison coercion the region performs when it builds the partition predicate
(ExprSimplifier::coerce / [comparison_coercion]): both sides are cast to the common
comparison type, and the persisted bound must be castable to that type with
[ScalarValue::cast_to]. A bound that would fail on scan is rejected here as well.
Structsยง
- Persisted
Partition ๐Expr - Mirrors
partition::expr::PartitionExpr.
Enumsยง
- Persisted
Op ๐ - Mirrors
partition::expr::RestrictedOp. - Persisted
Operand ๐ - Mirrors
partition::expr::Operand. - Persisted
Partition ๐Bound - Mirrors
partition::partition::PartitionBound.
Functionsยง
- changed_
column_ ๐types - Returns the columns whose data type differs between
old_schemaandnew_schema, mapped to (old type, new type). Columns only present in one of the schemas (added or dropped) are not included; dropping a column referenced by a partition expression is already rejected by the table metadata validation. - validate_
comparison ๐ - validate_
expr ๐ - validate_
operand ๐ - validate_
region_ partition_ bounds - Validates that the persisted partition bounds of every region are still representable
with the types of
changed_columns. Returns an error naming the first offending region without modifying anything. - value_
to_ ๐scalar_ value - Converts a persisted bound value to a [
ScalarValue], mirroringpartition::expr::Operand::try_as_logical_expr. ReturnsNonefor values that cannot appear in a persisted partition expression.