@API(value=EXPERIMENTAL) public class NestedContextExpression extends Object implements RelationalPlannerExpression
NestedContext
that
it holds. A NestedContextExpression
allows the planner to view various sub-parts of a PlannerExpression
inside of a nested record as unnested, thereby allowing most rules to be written without handling the complexities
of nested record types.
For example, suppose that we have a book record, which contains a nested author field of
author records and an index by_author
defined by the KeyExpression
:
field("author").nest("name")Consider the following planner expression with a predicate on the library records:
LogicalFilterExpression( field("author").nest("name").equalsValue("James Joyce"), IndexEntrySourceScanExpression("by_author", NO COMPARISONS))If we executed a rule (such as
FilterWithNestedToNestingContextRule
)
to convert this into a form relative to the NestedContext
for the non-repeated field author
, we
would obtain the following planner expression:
NestedContextExpression(SingleFieldNestingContext(field("author")), LogicalFilterExpression( field("name).equalsValue("James Joyce"), IndexEntrySourceScanExpression("by_author", NO COMPARISONS))where the
IndexEntrySourceScanExpression
now has a
KeyExpressionComparisons
based on the KeyExpression
field("name")Similarly, unnesting the latter expression would produce the former expression.
Constructor and Description |
---|
NestedContextExpression(NestedContext nestedContext,
ExpressionRef<RelationalPlannerExpression> inner) |
NestedContextExpression(NestedContext nestedContext,
RelationalPlannerExpression inner) |
Modifier and Type | Method and Description |
---|---|
ExpressionRef<RelationalPlannerExpression> |
asNestedWith(NestedContext nestedContext,
ExpressionRef<RelationalPlannerExpression> thisRef)
Produce an exactly equivalent version of the
PlannerExpression tree rooted at this
RelationalPlannerExpression as if all operations were nested inside the given NestedContext . |
ExpressionRef<RelationalPlannerExpression> |
asUnnestedWith(NestedContext nestedContext,
ExpressionRef<RelationalPlannerExpression> thisRef)
Produce an exactly equivalent version of the
PlannerExpression tree rooted at this
RelationalPlannerExpression with all operations placed inside the field given by the NestedContext . |
boolean |
equalsWithoutChildren(PlannerExpression otherExpression) |
NestedContext |
getNestedContext() |
Iterator<? extends ExpressionRef<? extends PlannerExpression>> |
getPlannerExpressionChildren()
Return an iterator of references to the children of this planner expression.
|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
fromRecordQuery
acceptPropertyVisitor, bindTo
public NestedContextExpression(@Nonnull NestedContext nestedContext, @Nonnull RelationalPlannerExpression inner)
public NestedContextExpression(@Nonnull NestedContext nestedContext, @Nonnull ExpressionRef<RelationalPlannerExpression> inner)
@Nonnull public NestedContext getNestedContext()
@Nullable public ExpressionRef<RelationalPlannerExpression> asNestedWith(@Nonnull NestedContext nestedContext, @Nonnull ExpressionRef<RelationalPlannerExpression> thisRef)
RelationalPlannerExpression
PlannerExpression
tree rooted at this
RelationalPlannerExpression
as if all operations were nested inside the given NestedContext
. That
is, transform all predicates, index scans, and other operations to the form that they would have if they were
nested within the field given by the parent field of the given nested context. If it is not possible to produce
such an expression, return null
.
With RelationalPlannerExpression.asUnnestedWith(NestedContext, ExpressionRef)
, this method should obey the contract that, for any
expression
and nestedContext
,
expression.asNestedWith(nestedContext, ref).asUnnestedWith(nestedContext, ref)
is either equal to
expression
(according to the equals()
comparison) or null
.
For example, if this expression is a filter on the predicate field("a").matches(field("b).equals(3))
,
with an inner FullUnorderedScanExpression
, and the nestedContext
is built around
field("a")
, then this method would return a reference containing a logical filter on the predicate
field("b").equals(3
) with an inner FullUnorderedScanExpression
.
The thisRef
parameter has two uses. For some implementations of asNestedWith()
, the expression
does not need to be changed, and so it is more efficient to return the containing reference than to build a
new one. Additionally, it is used to generate a reference of the appropriate type using the
ExpressionRef.getNewRefWith(PlannerExpression)
.
asNestedWith
in interface RelationalPlannerExpression
nestedContext
- a context describing the field to use for nestingthisRef
- the reference that contains this relational planner expression@Nullable public ExpressionRef<RelationalPlannerExpression> asUnnestedWith(@Nonnull NestedContext nestedContext, @Nonnull ExpressionRef<RelationalPlannerExpression> thisRef)
RelationalPlannerExpression
PlannerExpression
tree rooted at this
RelationalPlannerExpression
with all operations placed inside the field given by the NestedContext
.
That is, put all predicates, index scans, and other operations within the given nested field. If it is not possible
to produce such an expression, return null
.
With RelationalPlannerExpression.asNestedWith(NestedContext, ExpressionRef)
, this method should obey the contract that, for any
expression
and nestedContext
,
expression.asNestedWith(nestedContext, ref).asUnnestedWith(nestedContext, ref)
is either equal to
expression
(according to the equals()
comparison) or null
.
For example, if this expression is a logical filter on the predicate field("b).equals(3)
, with an inner
FullUnorderedScanExpression
, and the nestedContext
is built around field("a")
, then this
method would return a reference containing a logical filter on the predicate
field("a").matches(field("b").equals(3))
with an inner FullUnorderedScanExpression
.
The thisRef
parameter has two uses. For some implementations of asUnnestedWith()
, the expression
does not need to be changed, and so it is more efficient to return the containing reference than to build a
new one. Additionally, it is used to generate a reference of the appropriate type using the
ExpressionRef.getNewRefWith(PlannerExpression)
.
asUnnestedWith
in interface RelationalPlannerExpression
nestedContext
- a context describing the field to use for unnestingthisRef
- the reference that contains this expression@Nonnull public Iterator<? extends ExpressionRef<? extends PlannerExpression>> getPlannerExpressionChildren()
PlannerExpression
Collections.emptyIterator()
is returned. The returned iterator should
be treated as an immutable object and may throw an exception if Iterator.remove()
is called.
The iterator must return its elements in a consistent order.getPlannerExpressionChildren
in interface PlannerExpression
public boolean equalsWithoutChildren(@Nonnull PlannerExpression otherExpression)
equalsWithoutChildren
in interface PlannerExpression