Literal simplification can turn a well-typed nullable expression into a non-nullable expression.
| Expression | Root dtype | Optimized expression | Original dtype | Optimized dtype |
| --- | --- | --- | --- | --- |
| `and(root(), lit(false))` | `bool?` | `false` | `bool?` | `bool` |
| `or(root(), lit(true))` | `bool?` | `true` | `bool?` | `bool` |
| `and(root(), lit(Some(true)))` | `bool` | `root()` | `bool?` | `bool` |
| `or(root(), lit(Some(false)))` | `bool` | `root()` | `bool?` | `bool` |
| `zip_expr(lit(true), lit(1i32), root())` | `i32?` | `1i32` | `i32?` | `i32` |
| `zip_expr(lit(false), root(), lit(1i32))` | `i32?` | `1i32` | `i32?` | `i32` |
use rstest::rstest;
use vortex_array::dtype::DType;
use vortex_array::dtype::Nullability;
use vortex_array::dtype::PType;
use vortex_array::expr::Expression;
use vortex_array::expr::and;
use vortex_array::expr::lit;
use vortex_array::expr::or;
use vortex_array::expr::root;
use vortex_array::expr::zip_expr;
use vortex_array::scalar::Scalar;
use vortex_error::VortexResult;
#[rstest]
#[case::and_annihilator(and(root(), lit(false)), DType::Bool(Nullability::Nullable))]
#[case::or_annihilator(or(root(), lit(true)), DType::Bool(Nullability::Nullable))]
#[case::and_nullable_identity(
and(root(), lit(Scalar::from(Some(true)))),
DType::Bool(Nullability::NonNullable)
)]
#[case::or_nullable_identity(
or(root(), lit(Scalar::from(Some(false)))),
DType::Bool(Nullability::NonNullable)
)]
#[case::zip_true(
zip_expr(lit(true), lit(1i32), root()),
DType::Primitive(PType::I32, Nullability::Nullable)
)]
#[case::zip_false(
zip_expr(lit(false), root(), lit(1i32)),
DType::Primitive(PType::I32, Nullability::Nullable)
)]
fn literal_simplification_preserves_result_dtype(
#[case] expr: Expression,
#[case] scope: DType,
) -> VortexResult<()> {
let original = expr.bind(&scope)?;
let optimized = expr.optimize_recursive(&scope)?;
let rebound = optimized.bind(&scope)?;
eprintln!(
"{expr} -> {optimized}: {} -> {}",
original.dtype(),
rebound.dtype()
);
assert_eq!(rebound.dtype(), original.dtype());
Ok(())
}
What happened?
Literal simplification can turn a well-typed nullable expression into a non-nullable expression.
For example:
This is because:
Steps to reproduce
Environment
developat9e8abcafcaAdditional context
No response