java.lang.Object
com.darkcollective.relix.processor.provenance.internal.ProvenanceEvaluator

public final class ProvenanceEvaluator extends Object
Evaluates a logical RelNode tree as a K-relation, threading a chosen Semiring through the positive-algebra operators This is the bridge from the engine's ordinary Stream<Row> evaluation to the annotated model.

What is threaded, and what is opaque

Provenance v1 covers positive relational algebra only: this evaluator recurses through, and threads annotations across, selection (σ), projection (π), rename (ρ), product (×), inner/natural join (⋈/⨝), and union (∪) — combining derivations with the semiring's ⊕/⊗ exactly as AnnotatedRelation's operators define. Transitive closure (CLOSURE/RCLOSURE) is also threaded — as a semiring-weighted closure: iterating the closure with the chosen semiring unifies reachability (boolean), path-counting (ℕ), and shortest path (tropical) into one mechanism — see weightedClosure(com.darkcollective.relix.ast.ClosureNode, com.darkcollective.relix.provenance.Semiring<K>, com.darkcollective.relix.processor.internal.ExecutionContext, com.darkcollective.relix.processor.eval.OperandEvaluator, com.darkcollective.relix.processor.eval.PredicateEvaluator, com.darkcollective.relix.processor.provenance.internal.BaseAnnotator<K>). Every other node — a base relation, or a non-positive operator such as γ, τ, δ, a difference, an outer join, or a general fixpoint — is treated as an opaque base relation: its subtree is evaluated by the ordinary engine and lifted, so every one of its output tuples is annotated with the semiring's one(). Provenance therefore flows through the positive operators above the nearest non-positive boundary, and that boundary's output is read as a fresh source — the honest reading of the positive-RA theory, and the behaviour that lets provenance run over any query.

Above the federation boundary

Annotation tracking is in-engine and never pushed to a source. The threaded operators are handled here directly; only the opaque subtrees reach the planner (where pushdown is harmless, since the whole subtree is read as a base relation). The optimizer is not involved.

Cost

A K-relation is canonical (materialised) by construction, so unlike the default streaming path this evaluator buffers each relation. Provenance is an explicitly requested, heavier mode; the default path pays nothing.

Thread safety

Stateless and therefore thread-safe; the relations it returns are immutable.

  • Constructor Details

    • ProvenanceEvaluator

      public ProvenanceEvaluator()
  • Method Details

    • evaluate

      public <K> AnnotatedRelation<K> evaluate(RelNode node, Semiring<K> semiring, ExecutionContext ctx)
      Evaluates node as a K-relation over semiring.
      Type Parameters:
      K - the semiring annotation type
      Parameters:
      node - the logical relational algebra tree to evaluate; must not be null
      semiring - the annotation semiring; must not be null
      ctx - the shared execution context (connector, schemas, symbols); must not be null
      Returns:
      the canonical annotated relation
      Throws:
      EvaluationException - if a node's schema is unavailable or a data-level error occurs
    • evaluate

      public <K> AnnotatedRelation<K> evaluate(RelNode node, Semiring<K> semiring, ExecutionContext ctx, BaseAnnotator<K> baseAnnotator)
      Evaluates node as a K-relation over semiring, using baseAnnotator to annotate each base-tuple occurrence — for a caller that has one already. The three-argument overload builds the one the semiring asks for, which is what an ordinary caller wants.
      Type Parameters:
      K - the semiring annotation type
      Parameters:
      node - the logical relational algebra tree to evaluate; must not be null
      semiring - the annotation semiring; must not be null
      ctx - the shared execution context; must not be null
      baseAnnotator - annotates each base-tuple occurrence; must not be null
      Returns:
      the canonical annotated relation
      Throws:
      EvaluationException - if a node's schema is unavailable or a data-level error occurs