Class MatchableSortExpression
- java.lang.Object
-
- com.apple.foundationdb.record.query.plan.temp.expressions.MatchableSortExpression
-
- All Implemented Interfaces:
Bindable
,Correlated<RelationalExpression>
,InternalPlannerGraphRewritable
,RelationalExpressionWithChildren
,RelationalExpression
@API(EXPERIMENTAL) public class MatchableSortExpression extends Object implements RelationalExpressionWithChildren, InternalPlannerGraphRewritable
A relational planner expression that represents an unimplemented sort on the records produced by its inner relational planner expression. TODO BEGIN This class is somewhat flawed. There is a cousin of this classLogicalSortExpression
which serves a similar purpose conceptually but is still technically quite different.LogicalSortExpression
serves as the logical precursor to a physical implementation of a sort (which we do not (yet) have). So in order for the planner to produce an executable plan, that sort expression has to be optimized away by e.g.RemoveSortRule
. This class is different in a way that it an only be used as an expression to be matched against. In other words this class is only ever allowed to appear in a match candidate on the expression side. The reason why that is comes down to the simple question of how to express the thing(s) to sort on in general and what to do with nested repeated value in particular. What should we be able to express when we express order? One thing we definitely want to sort by is a scalar value that can be computed from the record or an index key that flows into the operator. On the contrary we should not be able to sort by something likefield("a", FanOut)
as it really does not make sense in this context. What does make sense is to say that you want the stream to be ordered byfield("a", FanOut)
, but you actually are expressing a requirement on data computed on a record before it even flows into the sort, i.e. it cannot be computed (conceptually) in this operator. The nested repeated fielda
needs to come from either a physical version of anExplodeExpression
(which we don't have (yet)) or from an index access as index keys can be constructed in this way. The expressiveness that is fundamentally lacking here is to model what data flows, how it flows and what operations have been applied to it since it was generated. There are other places where exactly this is a problem as well. Specifically, for the sort expression, however, this problem manifests itself as: (1) Either the sort is expressed by usingKeyExpression
s. In that case, expressing a nested repeated value in the sort expression itself does not make sense. Again, we should model such a case as a sort over an value that has been pre-produced by a cardinality-changing operator such as a physical variant of explode or by explicitly referring to and modelling the index keys that can flow along with the fetched record. Note that this of course has far-reaching implications for optimizations that attempt to defer the fetch of a record. Essentially, we would like to sayindex:
i.e. we want to sort by the index key. We do not want to model that plan likefield(a, FanOut)
plan:Sort(IndexScan(index), a [5, 10]), indexkey.a)
plan:
where the sort expression (even only if conceptually) extracts theSort(IndexScan(index), a [5, 10]), record.field("a", FanOut))
a
s from the base records as the base record at that moment already may contain duplicates of the base record due to using that index in the underlying scan. (2) Alternatively, we can express the sort by using explicit index scan-provided values. You simply cannot sort by anything that does not come from an index or a primary scan (the latter cannot really sort by anything that's repeated due to the key being a primary key). That works for the current landscape as there is no physical sort (yet) and it overcomes the problem explained above in a way that we can express to sort by anything the index scan (or primary scan) produces as opposed to something that can be computed on-the-fly based upon the base record. This also removes the requirement of the base record to be fetched and present at the the time the sort happens (conceptually) and allows for deferred-fetch optimizations. As a direct result of this we now have two different logical sort expressions. One,LogicalSortExpression
which expresses order by usingKeyExpression
s and which has the problems layed out in (1), and a this oneMatchableSortExpression
which expresses order by explicitly naming the constituent parts of an index. In the future, we should strive to unify these two classes to one logical sort expression. For now, we have a logical sort expression (LogicalSortExpression
) on the query side and a matchable sort expression (MatchableSortExpression
) on the match candidate side. TODO END When it comes to matching this class does not (yet) subsume aLogicalSortExpression
although it probably should be able to just for orthogonality of how rules can be applied and the search space for transformations and matching is explored. As an expression of this class never transforms into a physical sort (even if we had one, this expression would not be transformed into a a physical operator). In a sense this expression expresses a property of the flowing data stream (which ultimately comes from an ordered scan). This property is picked up byAdjustMatchRule
meaning that this operator can match "in-between" expressions on the query expression side (homomorphic matching) by improving the existing match memo by adorning it using the correct order-by property.
-
-
Nested Class Summary
-
Nested classes/interfaces inherited from interface com.apple.foundationdb.record.query.plan.temp.Correlated
Correlated.BoundEquivalence
-
Nested classes/interfaces inherited from interface com.apple.foundationdb.record.query.plan.temp.RelationalExpression
RelationalExpression.CombineFunction<R,S>, RelationalExpression.CombinePredicate
-
-
Constructor Summary
Constructors Constructor Description MatchableSortExpression(List<CorrelationIdentifier> sortParameterIds, boolean isReverse, Quantifier inner)
Overloaded constructor.MatchableSortExpression(List<CorrelationIdentifier> sortParameterIds, boolean isReverse, RelationalExpression innerExpression)
Overloaded constructor.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description Optional<MatchInfo>
adjustMatch(RelationalExpression expression, PartialMatch partialMatch)
Override that is called byAdjustMatchRule
to improve an already existingPartialMatch
.boolean
equals(Object other)
boolean
equalsWithoutChildren(RelationalExpression otherExpression, AliasMap equivalencesMap)
Set<CorrelationIdentifier>
getCorrelatedToWithoutChildren()
List<? extends Quantifier>
getQuantifiers()
Return an iterator of references to the children of this planner expression.int
getRelationalChildCount()
List<CorrelationIdentifier>
getSortParameterIds()
int
hashCode()
int
hashCodeWithoutChildren()
boolean
isReverse()
MatchableSortExpression
rebase(AliasMap translationMap)
Rebases this and all other objects this objects is composed of using a given translation map.MatchableSortExpression
rebaseWithRebasedQuantifiers(AliasMap translationMap, List<Quantifier> rebasedQuantifiers)
PlannerGraph
rewriteInternalPlannerGraph(List<? extends PlannerGraph> childGraphs)
Method to rewrite the planner graph.-
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, toString, wait, wait, wait
-
Methods inherited from interface com.apple.foundationdb.record.query.plan.temp.RelationalExpression
acceptPropertyVisitor, bindIdentities, bindTo, canCorrelate, compensate, enumerateUnboundCorrelatedTo, exactlySubsumedBy, findMatches, getResultValues, hasIncompatibleBoundQuantifiers, hasUnboundQuantifiers, match, match, semanticEquals, semanticEquals, semanticHashCode, show, subsumedBy
-
Methods inherited from interface com.apple.foundationdb.record.query.plan.temp.expressions.RelationalExpressionWithChildren
getCorrelatedTo
-
-
-
-
Constructor Detail
-
MatchableSortExpression
public MatchableSortExpression(@Nonnull List<CorrelationIdentifier> sortParameterIds, boolean isReverse, @Nonnull RelationalExpression innerExpression)
Overloaded constructor. Creates a newMatchableSortExpression
- Parameters:
sortParameterIds
- a list of parameter ids defining the orderisReverse
- an indicator whether this expression should conceptually flow data according tosortParameterIds
ascending (forward) or descending (backward or reverse).innerExpression
- expression dag that produces the stream this expression sorts
-
MatchableSortExpression
public MatchableSortExpression(@Nonnull List<CorrelationIdentifier> sortParameterIds, boolean isReverse, @Nonnull Quantifier inner)
Overloaded constructor. Creates a newMatchableSortExpression
- Parameters:
sortParameterIds
- a list of parameter ids defining the orderisReverse
- an indicator whether this expression should conceptually flow data according tosortParameterIds
ascending (forward) or descending (backward or reverse).inner
- quantifier ranging over an expression dag that produces the stream this expression sorts
-
-
Method Detail
-
getQuantifiers
@Nonnull public List<? extends Quantifier> getQuantifiers()
Description copied from interface:RelationalExpression
Return an iterator of references to the children of this planner expression. The iterators returned by different calls are guaranteed to be independent (i.e., advancing one will not advance another). However, they might point to the same object, as whenCollections.emptyIterator()
is returned. The returned iterator should be treated as an immutable object and may throw an exception ifIterator.remove()
is called. The iterator must return its elements in a consistent order.- Specified by:
getQuantifiers
in interfaceRelationalExpression
- Returns:
- an iterator of references to the children of this planner expression
-
getRelationalChildCount
public int getRelationalChildCount()
- Specified by:
getRelationalChildCount
in interfaceRelationalExpressionWithChildren
-
getSortParameterIds
@Nonnull public List<CorrelationIdentifier> getSortParameterIds()
-
isReverse
public boolean isReverse()
-
getCorrelatedToWithoutChildren
@Nonnull public Set<CorrelationIdentifier> getCorrelatedToWithoutChildren()
- Specified by:
getCorrelatedToWithoutChildren
in interfaceRelationalExpressionWithChildren
-
rebase
@Nonnull public MatchableSortExpression rebase(@Nonnull AliasMap translationMap)
Description copied from interface:Correlated
Rebases this and all other objects this objects is composed of using a given translation map.- Specified by:
rebase
in interfaceCorrelated<RelationalExpression>
- Specified by:
rebase
in interfaceRelationalExpressionWithChildren
- Parameters:
translationMap
- a map defining a translation fromCorrelationIdentifier
sids
toCorrelationIdentifier
sids'
. After the rebase, every correlation to anid
containedids
that is contained or referred to directly or indirectly bythis
must have been transformed to use the mapped counterpart ofid
id'
inids'
. IDs not contained in the translation map must remain unmodified by the rebase operation.- Returns:
- a new entity that has been rebased
-
rebaseWithRebasedQuantifiers
@Nonnull public MatchableSortExpression rebaseWithRebasedQuantifiers(@Nonnull AliasMap translationMap, @Nonnull List<Quantifier> rebasedQuantifiers)
- Specified by:
rebaseWithRebasedQuantifiers
in interfaceRelationalExpressionWithChildren
-
adjustMatch
@Nonnull public Optional<MatchInfo> adjustMatch(@Nonnull RelationalExpression expression, @Nonnull PartialMatch partialMatch)
Description copied from interface:RelationalExpression
Override that is called byAdjustMatchRule
to improve an already existingPartialMatch
.- Specified by:
adjustMatch
in interfaceRelationalExpression
- Parameters:
expression
- the query expressionpartialMatch
- the partial match already existing betweenexpression
andthis
- Returns:
Optional.empty()
if the match could not be adjusted, Optional.of(matchInfo) for a new adjusted match, otherwise.
-
equalsWithoutChildren
public boolean equalsWithoutChildren(@Nonnull RelationalExpression otherExpression, @Nonnull AliasMap equivalencesMap)
- Specified by:
equalsWithoutChildren
in interfaceRelationalExpression
-
hashCodeWithoutChildren
public int hashCodeWithoutChildren()
- Specified by:
hashCodeWithoutChildren
in interfaceRelationalExpression
-
rewriteInternalPlannerGraph
@Nonnull public PlannerGraph rewriteInternalPlannerGraph(@Nonnull List<? extends PlannerGraph> childGraphs)
Description copied from interface:InternalPlannerGraphRewritable
Method to rewrite the planner graph.- Specified by:
rewriteInternalPlannerGraph
in interfaceInternalPlannerGraphRewritable
- Parameters:
childGraphs
- planner graphs of children expression that already have been computed- Returns:
- a new planner graph that can combine the
childGraph
s in a meaningful way. Note that there is no obligation to use thechildGraph
s at all, this method can create a new independent planner graph completely from scratch.
-
-