- Record Components:
input- the edge relation; must not be nullfromColumn- the source-endpoint column; must not be blanktoColumn- the target-endpoint column; must not be blankundirected-truereads the two endpoint columns as an undirected edge, so the relation is followed both ways from one edge set (a ↔ b);falsereads a directed edge (a, b)reflexive-trueforR*(adds identity pairs),falseforR⁺boundSource- optional literal bound on thefromColumnendpoint (single-source); never null, possibly emptyboundTarget- optional literal bound on thetoColumnendpoint (single-target); never null, possibly emptylocation- the source location of this node; never null
- All Implemented Interfaces:
RelNode
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 Summary
ConstructorsConstructorDescriptionClosureNode(RelNode input, String fromColumn, String toColumn) Convenience constructor for tests: transitive (R⁺),SourceLocation.UNKNOWN.ClosureNode(RelNode input, String fromColumn, String toColumn, boolean reflexive) Convenience constructor for tests:SourceLocation.UNKNOWN.ClosureNode(RelNode input, String fromColumn, String toColumn, boolean undirected, boolean reflexive, Optional<Operand> boundSource, Optional<Operand> boundTarget, SourceLocation location) Creates an instance of aClosureNoderecord class.ClosureNode(RelNode input, String fromColumn, String toColumn, boolean reflexive, SourceLocation location) Constructor without endpoint bounds (the parsed form): both bounds empty. -
Method Summary
Modifier and TypeMethodDescription<R> Raccept(RelNodeVisitor<R> visitor) Returns the value of theboundSourcerecord component.Returns the value of theboundTargetrecord component.final booleanIndicates whether some other object is "equal to" this one.Returns the value of thefromColumnrecord component.final inthashCode()Returns a hash code value for this object.input()Returns the value of theinputrecord component.location()Returns the value of thelocationrecord component.booleanReturns the value of thereflexiverecord component.toColumn()Returns the value of thetoColumnrecord component.final StringtoString()Returns a string representation of this record class.booleanReturns the value of theundirectedrecord component.withBounds(Optional<Operand> newSource, Optional<Operand> newTarget) Returns a copy of this closure with the given endpoint bounds, preserving all other fields.Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, waitMethods inherited from interface com.darkcollective.relix.ast.RelNode
children, mapChildren, materializationMode, prettyPrint
-
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 aClosureNoderecord class.- Parameters:
input- the value for theinputrecord componentfromColumn- the value for thefromColumnrecord componenttoColumn- the value for thetoColumnrecord componentundirected- the value for theundirectedrecord componentreflexive- the value for thereflexiverecord componentboundSource- the value for theboundSourcerecord componentboundTarget- the value for theboundTargetrecord componentlocation- the value for thelocationrecord 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 nullfromColumn- the source-endpoint column; must not be blanktoColumn- the target-endpoint column; must not be blankreflexive-trueforR*,falseforR⁺location- the source location of this node; never null
-
ClosureNode
Convenience constructor for tests: transitive (R⁺),SourceLocation.UNKNOWN. -
ClosureNode
Convenience constructor for tests:SourceLocation.UNKNOWN.
-
-
Method Details
-
withBounds
Returns a copy of this closure with the given endpoint bounds, preserving all other fields.- Parameters:
newSource- the source-endpoint bound; must not be nullnewTarget- the target-endpoint bound; must not be null- Returns:
- a bounded copy
-
accept
-
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. -
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. -
equals
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 withObjects::equals(Object,Object); primitive components are compared with '=='. -
input
Returns the value of theinputrecord component.- Returns:
- the value of the
inputrecord component
-
fromColumn
Returns the value of thefromColumnrecord component.- Returns:
- the value of the
fromColumnrecord component
-
toColumn
Returns the value of thetoColumnrecord component.- Returns:
- the value of the
toColumnrecord component
-
undirected
public boolean undirected()Returns the value of theundirectedrecord component.- Returns:
- the value of the
undirectedrecord component
-
reflexive
public boolean reflexive()Returns the value of thereflexiverecord component.- Returns:
- the value of the
reflexiverecord component
-
boundSource
Returns the value of theboundSourcerecord component.- Returns:
- the value of the
boundSourcerecord component
-
boundTarget
Returns the value of theboundTargetrecord component.- Returns:
- the value of the
boundTargetrecord component
-
location
Returns the value of thelocationrecord component.
-