Interface FilterPredicate

All Known Implementing Classes:
FilterPredicate.And, FilterPredicate.BinaryColumnPredicate, FilterPredicate.BinaryInPredicate, FilterPredicate.BooleanColumnPredicate, FilterPredicate.DateColumnPredicate, FilterPredicate.DateInPredicate, FilterPredicate.DecimalColumnPredicate, FilterPredicate.DecimalInPredicate, FilterPredicate.DoubleColumnPredicate, FilterPredicate.DoubleInPredicate, FilterPredicate.FloatColumnPredicate, FilterPredicate.FloatInPredicate, FilterPredicate.InstantColumnPredicate, FilterPredicate.InstantInPredicate, FilterPredicate.IntColumnPredicate, FilterPredicate.IntersectsPredicate, FilterPredicate.IntervalColumnPredicate, FilterPredicate.IntervalInPredicate, FilterPredicate.IntInPredicate, FilterPredicate.IsNotNullPredicate, FilterPredicate.IsNullPredicate, FilterPredicate.LocalDateTimeColumnPredicate, FilterPredicate.LocalDateTimeInPredicate, FilterPredicate.LongColumnPredicate, FilterPredicate.LongInPredicate, FilterPredicate.Not, FilterPredicate.Or, FilterPredicate.StringColumnPredicate, FilterPredicate.StringInPredicate, FilterPredicate.TimeColumnPredicate, FilterPredicate.TimeInPredicate, FilterPredicate.UUIDColumnPredicate, FilterPredicate.UUIDInPredicate

A predicate filtering the rows a reader returns.

A reader returns exactly the rows the predicate matches, except for intersects(String, double, double, double, double), which decides whole row groups. It also pushes the predicate down: row groups and pages whose statistics, dictionary or Bloom filter prove that no row can match are skipped without being decoded. A literal is a value the column's accessors return; the Query Controls reference lists the literals and operators each column type takes.

Usage examples:

// Simple comparison
FilterPredicate filter = FilterPredicate.gt("age", 21);

// Compound predicate
FilterPredicate filter = FilterPredicate.and(
    FilterPredicate.gtEq("salary", 50000L),
    FilterPredicate.lt("age", 65)
);

// Use with reader
try (ColumnReader reader = fileReader.buildColumnReader("salary").filter(filter).build()) {
    while (reader.nextBatch()) { ... }
}

Null handling

All comparison predicates (eq, notEq, lt, ltEq, gt, gtEq, in) follow SQL three-valued logic: comparing a null column value against any operand yields UNKNOWN, and rows whose predicate is UNKNOWN are not returned. In practice this means rows with a null in the tested column are never returned by a comparison predicate. Use isNull / isNotNull for explicit null checks, or or(...) to include null rows alongside a comparison — e.g. or(gt("age", 30), isNull("age")).

not(p) preserves this behavior: rows where p is UNKNOWN stay UNKNOWN under negation and are dropped. The SQL identity not(gt(x, v)) ≡ ltEq(x, v) holds on all rows, including null ones.

This matches the SQL semantics of WHERE predicates and differs from parquet-java's notEq, which treats null <> v as true and therefore includes null rows. To reproduce parquet-java's behavior in Hardwood, write the null-inclusion explicitly: or(notEq("x", v), isNull("x")).

Float and double comparisons

Predicates on float and double columns use the Float.compare(float, float) / Double.compare(double, double) total order, not IEEE 754 equality. Two consequences matter in practice:

  • -0.0 is strictly less than +0.0. eq(0.0) matches only +0.0 values; to match either zero, use in(column, 0.0, -0.0).
  • NaN sorts above every other value, and every NaN equals every other. eq(NaN) matches only NaN (whereas IEEE NaN == anything is always false). lt against any value, and ltEq against a number, never match NaN rows; gt and gtEq against a number, and ltEq and gtEq against NaN, include them.

in(column, float...) and in(column, double...) apply the same total order to each listed value. in(column, float...) takes a FLOAT or FLOAT16 column and in(column, double...) a DOUBLE column, as eq does.

Row-group and page pruning never drops a NaN row that a predicate matches. Statistics whose min or max is NaN are not used for pruning. A predicate that a NaN value satisfies — notEq, gt or gtEq against a number, or eq, ltEq or gtEq against NaN — prunes a FLOAT, DOUBLE or FLOAT16 column from its statistics only where the row group or page records a nan_count of zero.