java.lang.Object
com.darkcollective.relix.processor.eval.OperandEvaluator

public final class OperandEvaluator extends Object
Evaluates an Operand expression against a Row, producing a runtime Value.

Handles all eight subtypes of the sealed Operand hierarchy: literals, attribute references, unary negation, binary arithmetic, function calls, and set literals (which cannot be evaluated as scalars and throw).

Arithmetic follows SQL NULL-propagation rules: if either operand is NULL the result is NULL. String addition concatenates two strings; all other arithmetic requires numeric operands.

Qualified attribute names (e.g. "Orders.amount") are resolved by stripping the relation prefix and looking up just the column name.

Function resolution proceeds in two stages:

  1. The FunctionCatalog — whichever function libraries are installed — is checked first.
  2. If not found there, the SymbolTable (when supplied) is searched for a user-defined function whose body is evaluated recursively with the call arguments bound to the function's parameters.

A catalogue holds a function's implementation as well as its form, so the evaluator neither knows nor cares which library supplied one: it dispatches on whether the function wants its arguments evaluated (StrictScalarFunction) or deferred (LazyScalarFunction), and a library's own function is evaluated exactly as a shipped one is.

Thread safety

Instances are stateless (apart from the immutable SymbolTable reference, the immutable catalogue, and the immutable ambient context) and therefore thread-safe.

  • Constructor Details

    • OperandEvaluator

      public OperandEvaluator()
      Constructs an evaluator without a symbol table, over the installed function libraries. User-defined functions resolve to EvaluationException.
    • OperandEvaluator

      public OperandEvaluator(SymbolTable symbolTable)
      Constructs an evaluator with the given symbol table for user-defined function resolution, over the installed function libraries and reading the system UTC clock.
      Parameters:
      symbolTable - the symbol table to search for user-defined functions; may be null (disables user-defined function support)
    • OperandEvaluator

      public OperandEvaluator(SymbolTable symbolTable, FunctionCatalog functions)
      Constructs an evaluator over an explicit catalogue, reading the system UTC clock.
      Parameters:
      symbolTable - the symbol table to search for user-defined functions; may be null (disables user-defined function support)
      functions - the functions available to calls; must not be null
    • OperandEvaluator

      public OperandEvaluator(SymbolTable symbolTable, FunctionCatalog functions, FunctionContext context)
      Constructs an evaluator over an explicit catalogue and ambient context.

      The context carries the clock the current-time functions read. Pinning it makes a run reproducible — the same script over the same data yields the same rows however much later it is replayed — and costs nothing, because one immutable catalogue serves every clock. See ExecutionContext.clock().

      Parameters:
      symbolTable - the symbol table to search for user-defined functions; may be null (disables user-defined function support)
      functions - the functions available to calls; must not be null
      context - the ambient state a function may read; must not be null
  • Method Details

    • contextFor

      public static FunctionContext contextFor(Clock clock)
      The ambient context the engine supplies: the given clock, and the engine's own total order over values.

      The order matters to any function that ranks its input — the MIN of a group has to be the first row of the corresponding sort, and it is not if the two use different comparators. Built here rather than left to FunctionContext.systemDefault() so that a value which arrived as ISO-8601 text from a schema-less source still compares against a typed one.

      Parameters:
      clock - the clock the current-time functions read; must not be null
      Returns:
      the engine's function context over clock
    • functions

      public FunctionCatalog functions()
      The functions this evaluator resolves calls against — the same catalogue an aggregate is looked up in, so a γ and a π in one query agree about a name.
      Returns:
      the catalogue; never null
    • functionContext

      public FunctionContext functionContext()
      The ambient state this evaluator hands to a function or an accumulator.
      Returns:
      the context; never null
    • evaluate

      public Value evaluate(Operand operand, Row row)
      Evaluates operand against the given row.
      Parameters:
      operand - the expression to evaluate; must not be null
      row - the current row providing attribute values; must not be null
      Returns:
      the resulting value; never null
      Throws:
      EvaluationException - if evaluation fails (unknown column, type mismatch, etc.)