public abstract class Expr extends AstBuilders
The readable spelling of AstBuilders — comparisons by name, n-ary connectives, and literals built from Java values rather than from their source spelling.

AstBuilders follows one rule: a factory takes the record's own components, in the record's own order. That rule is what keeps it honest, and it is also what makes a hand-written expression verbose — a comparison names an enum constant, and a number literal is a String because a NumberOperand stores the digits as written. This class is the layer that reads well at a call site, built entirely out of those same factories, so there is one set of nodes and no second authority:

// AstBuilders — the record's own shape
cmp(attr("id"), ComparisonOperator.EQUAL, num("42"))

// Expr — the same node
eq(attr("id"), num(42))

This is how a value is bound to a query

The question every embedder asks first is how to put a value into a query safely. The answer is that a value never becomes text at all:

// Never necessary, and this is the shape that invents an injection surface
// where the language never had one:
//     "σ id = " + orderId + " (Orders)"

// The value becomes a NumberOperand node, and nothing is parsed:
select(eq(attr("id"), num(orderId)), rel("Orders"))

That is why num(long), lit(Object) and the java.time overloads exist: a caller holds a long, an Instant or a BigDecimal, and formatting one into a string so a builder can parse it back is exactly the round trip this surface removes.

Extends AstBuilders, so one extends Expr — or one static import — reaches every factory as well as everything here.

See Also:
  • Constructor Details

    • Expr

      public Expr()
  • Method Details

    • num

      public static NumberOperand num(long value)
      A numeric literal from a Java integer value.
      Parameters:
      value - the value
      Returns:
      the operand
    • num

      public static NumberOperand num(double value)
      A numeric literal from a Java floating-point value.

      Rendered through BigDecimal.valueOf(double) with trailing zeros stripped, so the literal reads as the shortest decimal that round-trips rather than as the binary expansion — and 5.0 spells 5, since Double.toString keeps a trailing zero the value does not carry. Use num(BigDecimal) where the scale is itself meaningful.

      Parameters:
      value - the value
      Returns:
      the operand
    • num

      public static NumberOperand num(BigDecimal value)
      A numeric literal from an exact decimal value.
      Parameters:
      value - the value; must not be null
      Returns:
      the operand
    • date

      public static DateOperand date(LocalDate value)
      A date literal from a LocalDate.
      Parameters:
      value - the date; must not be null
      Returns:
      the operand
    • time

      public static TimeOperand time(LocalTime value)
      A time literal from a LocalTime.
      Parameters:
      value - the time; must not be null
      Returns:
      the operand
    • timestamp

      public static TimestampOperand timestamp(Instant value)
      A timestamp literal from an Instant.
      Parameters:
      value - the instant; must not be null
      Returns:
      the operand
    • duration

      public static DurationOperand duration(Duration value)
      A duration literal from a Duration.
      Parameters:
      value - the duration; must not be null
      Returns:
      the operand
    • lit

      public static Operand lit(Object value)
      The literal operand for a Java value, chosen by its runtime type.

      For binding a value whose type is only known at runtime — a parameter map, a UI field, a row read from somewhere else. When the type is known, the specific factory says more at the call site.

      null becomes a NullPredicate's business rather than an operand: there is no null literal in the operand hierarchy, so it is rejected here instead of silently becoming the string "null".

      Parameters:
      value - the Java value; must not be null
      Returns:
      the matching literal operand
      Throws:
      IllegalArgumentException - if value is null or has no literal form
    • eq

      public static ComparisonPredicate eq(Operand left, Operand right)
      left = right.
      Parameters:
      left - the left operand
      right - the right operand
      Returns:
      the predicate
    • ne

      public static ComparisonPredicate ne(Operand left, Operand right)
      left ≠ right.
      Parameters:
      left - the left operand
      right - the right operand
      Returns:
      the predicate
    • lt

      public static ComparisonPredicate lt(Operand left, Operand right)
      left < right.
      Parameters:
      left - the left operand
      right - the right operand
      Returns:
      the predicate
    • le

      public static ComparisonPredicate le(Operand left, Operand right)
      left ≤ right.
      Parameters:
      left - the left operand
      right - the right operand
      Returns:
      the predicate
    • gt

      public static ComparisonPredicate gt(Operand left, Operand right)
      left > right.
      Parameters:
      left - the left operand
      right - the right operand
      Returns:
      the predicate
    • ge

      public static ComparisonPredicate ge(Operand left, Operand right)
      left ≥ right.
      Parameters:
      left - the left operand
      right - the right operand
      Returns:
      the predicate
    • allOf

      public static Predicate allOf(Predicate... predicates)
      The conjunction of every given predicate, folded left so it nests the way a parsed a ∧ b ∧ c does.

      AstBuilders.and is strictly binary because AndPredicate is; this is the n-ary spelling a caller assembling a filter list needs.

      Parameters:
      predicates - at least one predicate
      Returns:
      the single predicate when one is given, else the left-folded conjunction
      Throws:
      IllegalArgumentException - if no predicate is given
    • allOf

      public static Predicate allOf(List<Predicate> predicates)
      The conjunction of every predicate in predicates, folded left.
      Parameters:
      predicates - at least one predicate
      Returns:
      the single predicate when one is given, else the left-folded conjunction
      Throws:
      IllegalArgumentException - if the list is empty
    • anyOf

      public static Predicate anyOf(Predicate... predicates)
      The disjunction of every given predicate, folded left.
      Parameters:
      predicates - at least one predicate
      Returns:
      the single predicate when one is given, else the left-folded disjunction
      Throws:
      IllegalArgumentException - if no predicate is given
    • anyOf

      public static Predicate anyOf(List<Predicate> predicates)
      The disjunction of every predicate in predicates, folded left.
      Parameters:
      predicates - at least one predicate
      Returns:
      the single predicate when one is given, else the left-folded disjunction
      Throws:
      IllegalArgumentException - if the list is empty
    • isNull

      public static NullPredicate isNull(Operand operand)
      operand IS NULL.
      Parameters:
      operand - the operand to test
      Returns:
      the predicate
    • isNotNull

      public static NullPredicate isNotNull(Operand operand)
      operand IS NOT NULL.
      Parameters:
      operand - the operand to test
      Returns:
      the predicate
    • in

      public static ElementOfPredicate in(Operand element, Operand... values)
      element ∈ {values…}, with the set literal built for you.
      Parameters:
      element - the operand tested for membership
      values - the set members
      Returns:
      the predicate
    • plus

      public static BinaryArithmeticExpression plus(Operand left, Operand right)
      left + right.
      Parameters:
      left - the left operand
      right - the right operand
      Returns:
      the expression
    • minus

      public static BinaryArithmeticExpression minus(Operand left, Operand right)
      left - right.
      Parameters:
      left - the left operand
      right - the right operand
      Returns:
      the expression
    • times

      public static BinaryArithmeticExpression times(Operand left, Operand right)
      left * right.
      Parameters:
      left - the left operand
      right - the right operand
      Returns:
      the expression
    • dividedBy

      public static BinaryArithmeticExpression dividedBy(Operand left, Operand right)
      left / right.
      Parameters:
      left - the left operand
      right - the right operand
      Returns:
      the expression