Record Class EmptyRelationNode
- Record Components:
heading- the expression whose schema this empty relation has; must not be nulllocation- the source location of this node; never null
- All Implemented Interfaces:
RelNode
∅ that a provably-unsatisfiable query collapses to.
Introduced only by the optimizer's empty-relation propagation
(EMPTY-001/EMPTY-002), never by the parser: a contradictory
filter such as σ x > 5 ∧ x < 3 (Orders) admits no row whatever
Orders contains, so the whole sub-tree is replaced by this node and
neither scanned nor joined.
Why not EMPTY / DUM?
TruthRelationNode.empty(SourceLocation) is also row-less, but it is the
zero-column relation — the truth value false. Its own
Javadoc makes the distinction from the other side: R × EMPTY is empty
but keeps R's heading, so it is not EMPTY itself. Every
law this node exists to serve is heading-preserving — σ false (R) still
has R's columns, and a query that selects from it must still type-check —
so a row-less relation that carries a heading is a genuinely different thing from
the nullary literal, and gets its own node rather than a flag on that one.
The heading is carried, not computed
relix-ast has no dependency on the symbol layer, so this node cannot
hold a Schema directly. It holds the sub-expression it replaced, and
schema inference reports that expression's schema — which is exactly the
heading required, at every step of the propagation: replacing ∅ ⋈ X means
carrying the heading of the whole join, not of the empty side.
The heading is not a child
RelNode.children() is empty and RelNode.mapChildren(java.util.function.UnaryOperator<com.darkcollective.relix.ast.RelNode>) returns this, so
this is a leaf and the carried expression is inert: no pass
recurses into it, nothing rewrites it, and the executor never touches it. That is
deliberate in both directions. It is dead code — running any of it would be the
work this rule exists to avoid — and, more sharply, a rewrite that changed the
carried expression's schema would silently change this node's heading,
which would be a correctness bug rather than a missed optimisation.
-
Constructor Summary
ConstructorsConstructorDescriptionEmptyRelationNode(RelNode heading, SourceLocation location) Validates that both components are present. -
Method Summary
Modifier and TypeMethodDescription<R> Raccept(RelNodeVisitor<R> visitor) final booleanIndicates whether some other object is "equal to" this one.final inthashCode()Returns a hash code value for this object.heading()Returns the value of theheadingrecord component.location()Returns the value of thelocationrecord component.static EmptyRelationNodeCreates an empty relation withheading's schema, taking its source location from that expression so a diagnostic still points at the query text the rule collapsed.final StringtoString()Returns a string representation of this record class.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
-
EmptyRelationNode
Validates that both components are present.
-
-
Method Details
-
of
Creates an empty relation withheading's schema, taking its source location from that expression so a diagnostic still points at the query text the rule collapsed.- Parameters:
heading- the expression whose schema and location to adopt; must not be null- Returns:
- the empty relation; never null
-
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. All components in this record class are compared withObjects::equals(Object,Object). -
heading
Returns the value of theheadingrecord component.- Returns:
- the value of the
headingrecord component
-
location
Returns the value of thelocationrecord component.
-