Record Class ClosureNode

java.lang.Object
java.lang.Record
com.darkcollective.relix.ast.ClosureNode
Record Components:
input - the edge relation; must not be null
fromColumn - the source-endpoint column; must not be blank
toColumn - the target-endpoint column; must not be blank
undirected - true reads the two endpoint columns as an undirected edge, so the relation is followed both ways from one edge set (a ↔ b); false reads a directed edge (a, b)
reflexive - true for R* (adds identity pairs), false for R⁺
boundSource - optional literal bound on the fromColumn endpoint (single-source); never null, possibly empty
boundTarget - optional literal bound on the toColumn endpoint (single-target); never null, possibly empty
location - the source location of this node; never null
All Implemented Interfaces:
RelNode

public record ClosureNode(RelNode input, String fromColumn, String toColumn, boolean undirected, boolean reflexive, Optional<Operand> boundSource, Optional<Operand> boundTarget, SourceLocation location) extends Record implements RelNode
Transitive closure (least fixpoint) of a binary relation — the recursive "reachability" operator.

The input() relation is read as a set of directed edges over two columns, fromColumn() and toColumn(). The operator emits the pairs (a, b) connected by one or more edges (its transitive closure R⁺); when reflexive() is set it also emits the identity pair (n, n) for every node, giving the reflexive-transitive closure R*. The output is a binary relation carrying just the two edge columns; any other input columns are dropped.

This is the groupwise reachability / ancestry / bill-of-materials operation that SQL expresses only with a WITH RECURSIVE CTE. Evaluation is an in-engine least-fixpoint iteration under set semantics, so a cyclic input graph terminates (a pair already derived is never re-added). The operator never pushes down to a source.

Surface syntax: CLOSURE from, to (Edges) (transitive) and RCLOSURE from, to (Edges) (reflexive-transitive).

Pushed endpoint bounds

boundSource() and boundTarget() are optional constant endpoint bounds folded in by the optimizer's SelectionIntoClosurePass (CLOSURE-001) when a selection above the closure fixes the source and/or target endpoint to a literal. They turn the all-pairs computation into single-source / single-target / single-pair reachability — the canonical magic-sets / sideways-information-passing rewrite. They are always Optional.empty() on a parsed tree (no surface syntax); they carry a literal Operand and never change the output schema, so schema inference is unaffected.

  • Constructor Details

    • ClosureNode

      public ClosureNode(RelNode input, String fromColumn, String toColumn, boolean undirected, boolean reflexive, Optional<Operand> boundSource, Optional<Operand> boundTarget, SourceLocation location)
      Creates an instance of a ClosureNode record class.
      Parameters:
      input - the value for the input record component
      fromColumn - the value for the fromColumn record component
      toColumn - the value for the toColumn record component
      undirected - the value for the undirected record component
      reflexive - the value for the reflexive record component
      boundSource - the value for the boundSource record component
      boundTarget - the value for the boundTarget record component
      location - the value for the location record component
    • ClosureNode

      public ClosureNode(RelNode input, String fromColumn, String toColumn, boolean reflexive, SourceLocation location)
      Constructor without endpoint bounds (the parsed form): both bounds empty.
      Parameters:
      input - the edge relation; must not be null
      fromColumn - the source-endpoint column; must not be blank
      toColumn - the target-endpoint column; must not be blank
      reflexive - true for R*, false for R⁺
      location - the source location of this node; never null
    • ClosureNode

      public ClosureNode(RelNode input, String fromColumn, String toColumn)
      Convenience constructor for tests: transitive (R⁺), SourceLocation.UNKNOWN.
    • ClosureNode

      public ClosureNode(RelNode input, String fromColumn, String toColumn, boolean reflexive)
      Convenience constructor for tests: SourceLocation.UNKNOWN.
  • Method Details

    • withBounds

      public ClosureNode withBounds(Optional<Operand> newSource, Optional<Operand> newTarget)
      Returns a copy of this closure with the given endpoint bounds, preserving all other fields.
      Parameters:
      newSource - the source-endpoint bound; must not be null
      newTarget - the target-endpoint bound; must not be null
      Returns:
      a bounded copy
    • accept

      public <R> R accept(RelNodeVisitor<R> visitor)
      Specified by:
      accept in interface RelNode
    • toString

      public final String toString()
      Returns a string representation of this record class. The representation contains the name of the class, followed by the name and value of each of the record components.
      Specified by:
      toString in class Record
      Returns:
      a string representation of this object
    • hashCode

      public final int hashCode()
      Returns a hash code value for this object. The value is derived from the hash code of each of the record components.
      Specified by:
      hashCode in class Record
      Returns:
      a hash code value for this object
    • equals

      public final boolean equals(Object o)
      Indicates whether some other object is "equal to" this one. The objects are equal if the other object is of the same class and if all the record components are equal. Reference components are compared with Objects::equals(Object,Object); primitive components are compared with '=='.
      Specified by:
      equals in class Record
      Parameters:
      o - the object with which to compare
      Returns:
      true if this object is the same as the o argument; false otherwise.
    • input

      public RelNode input()
      Returns the value of the input record component.
      Returns:
      the value of the input record component
    • fromColumn

      public String fromColumn()
      Returns the value of the fromColumn record component.
      Returns:
      the value of the fromColumn record component
    • toColumn

      public String toColumn()
      Returns the value of the toColumn record component.
      Returns:
      the value of the toColumn record component
    • undirected

      public boolean undirected()
      Returns the value of the undirected record component.
      Returns:
      the value of the undirected record component
    • reflexive

      public boolean reflexive()
      Returns the value of the reflexive record component.
      Returns:
      the value of the reflexive record component
    • boundSource

      public Optional<Operand> boundSource()
      Returns the value of the boundSource record component.
      Returns:
      the value of the boundSource record component
    • boundTarget

      public Optional<Operand> boundTarget()
      Returns the value of the boundTarget record component.
      Returns:
      the value of the boundTarget record component
    • location

      public SourceLocation location()
      Returns the value of the location record component.
      Specified by:
      location in interface RelNode
      Returns:
      the value of the location record component