public class SubstitutionVisitor extends Object
The call new SubstitutionVisitor(target, query).go(replacement))
will return query with every occurrence of target replaced
by replacement.
The following example shows how SubstitutionVisitor can be used
for materialized view recognition.
Note that result uses the materialized view table mv and a
simplified condition b = 4.
Uses a bottom-up matching algorithm. Nodes do not need to be identical. At each level, returns the residue.
The inputs must only include the core relational operators:
LogicalTableScan,
LogicalFilter,
LogicalProject,
LogicalJoin,
LogicalUnion,
LogicalAggregate.
| Modifier and Type | Class and Description |
|---|---|
protected static class |
SubstitutionVisitor.AbstractUnifyRule
Abstract base class for implementing
SubstitutionVisitor.UnifyRule. |
private static class |
SubstitutionVisitor.AggregateOnProjectToAggregateUnifyRule
Implementation of
SubstitutionVisitor.UnifyRule that matches a
MutableAggregate on
a MutableProject query to an MutableAggregate target. |
private static class |
SubstitutionVisitor.AggregateToAggregateUnifyRule
Implementation of
SubstitutionVisitor.UnifyRule that matches a
LogicalAggregate to a
LogicalAggregate, provided
that they have the same child. |
private static class |
SubstitutionVisitor.AnyOperand
Operand to a
SubstitutionVisitor.UnifyRule that matches a relational expression of a
given type. |
static class |
SubstitutionVisitor.FilterOnProjectRule
Rule that converts a
LogicalFilter
on top of a LogicalProject into a
trivial filter (on a boolean column). |
private static class |
SubstitutionVisitor.FilterToFilterUnifyRule
Implementation of
SubstitutionVisitor.UnifyRule that matches a
MutableFilter. |
private static class |
SubstitutionVisitor.FilterToProjectUnifyRule
|
private static class |
SubstitutionVisitor.InternalOperand
Operand to a
SubstitutionVisitor.UnifyRule that matches a relational expression of a
given type. |
protected static class |
SubstitutionVisitor.MatchFailed
Exception thrown to exit a matcher.
|
protected static class |
SubstitutionVisitor.Operand
Operand to a
SubstitutionVisitor.UnifyRule. |
private static class |
SubstitutionVisitor.ProjectToFilterUnifyRule
|
private static class |
SubstitutionVisitor.ProjectToProjectUnifyRule
Implementation of
SubstitutionVisitor.UnifyRule that matches
LogicalProject. |
private static class |
SubstitutionVisitor.QueryOperand
Operand that assigns a particular relational expression to a variable.
|
(package private) static class |
SubstitutionVisitor.Replacement
Represents a replacement action: before → after.
|
private static class |
SubstitutionVisitor.ScanToProjectUnifyRule
Implementation of
SubstitutionVisitor.UnifyRule that matches
LogicalTableScan. |
private static class |
SubstitutionVisitor.SlotCounter
Visitor that counts how many
SubstitutionVisitor.QueryOperand and
SubstitutionVisitor.TargetOperand in an operand tree. |
private static class |
SubstitutionVisitor.TargetOperand
Operand that checks that a relational expression matches the corresponding
relational expression that was passed to a
SubstitutionVisitor.QueryOperand. |
private static class |
SubstitutionVisitor.TrivialRule
Implementation of
SubstitutionVisitor.UnifyRule that matches if the query is already
equal to the target. |
protected static class |
SubstitutionVisitor.UnifyResult
Result of an application of a
SubstitutionVisitor.UnifyRule indicating that the
rule successfully matched query against target and
generated a result that is equivalent to query and
contains target. |
protected static class |
SubstitutionVisitor.UnifyRule
Rule that attempts to match a query relational expression
against a target relational expression.
|
protected class |
SubstitutionVisitor.UnifyRuleCall
Arguments to an application of a
SubstitutionVisitor.UnifyRule. |
| Modifier and Type | Field and Description |
|---|---|
private RelOptCluster |
cluster |
private static boolean |
DEBUG |
protected static com.google.common.collect.ImmutableList<SubstitutionVisitor.UnifyRule> |
DEFAULT_RULES |
(package private) com.google.common.collect.Multimap<MutableRel,MutableRel> |
equivalents |
private static org.slf4j.Logger |
LOGGER |
private Holder |
query |
(package private) List<MutableRel> |
queryLeaves
Nodes in
query that have no children. |
protected RelBuilder |
relBuilder
Factory for a builder for relational expressions.
|
(package private) Map<MutableRel,MutableRel> |
replacementMap |
private Map<Pair<Class,Class>,List<SubstitutionVisitor.UnifyRule>> |
ruleMap |
private com.google.common.collect.ImmutableList<SubstitutionVisitor.UnifyRule> |
rules |
private RexSimplify |
simplify |
protected MutableRel[] |
slots
Workspace while rule is being matched.
|
private MutableRel |
target |
(package private) List<MutableRel> |
targetLeaves
Nodes in
target that have no children. |
| Constructor and Description |
|---|
SubstitutionVisitor(RelNode target_,
RelNode query_)
Creates a SubstitutionVisitor with the default rule set.
|
SubstitutionVisitor(RelNode target_,
RelNode query_,
com.google.common.collect.ImmutableList<SubstitutionVisitor.UnifyRule> rules)
Creates a SubstitutionVisitor with the default logical builder.
|
SubstitutionVisitor(RelNode target_,
RelNode query_,
com.google.common.collect.ImmutableList<SubstitutionVisitor.UnifyRule> rules,
RelBuilderFactory relBuilderFactory) |
| Modifier and Type | Method and Description |
|---|---|
private List<SubstitutionVisitor.UnifyRule> |
applicableRules(MutableRel query,
MutableRel target) |
private static List<AggregateCall> |
apply(Mapping mapping,
List<AggregateCall> aggCallList) |
private SubstitutionVisitor.UnifyResult |
apply(SubstitutionVisitor.UnifyRule rule,
MutableRel query,
MutableRel target) |
private static RexNode |
canonizeNode(RexBuilder rexBuilder,
RexNode condition)
Reorders some of the operands in this expression so structural comparison,
i.e., based on string representation, can be more precise.
|
static boolean |
equalType(String desc0,
MutableRel rel0,
String desc1,
MutableRel rel1,
Litmus litmus)
Returns whether two relational expressions have the same row-type.
|
protected static RexShuttle |
getRexShuttle(MutableProject target)
Builds a shuttle that stores a list of expressions, and can map incoming
expressions to references to them.
|
static SqlAggFunction |
getRollup(SqlAggFunction aggregation) |
private List<List<SubstitutionVisitor.Replacement>> |
go(MutableRel replacement)
Substitutes the query with replacement whenever possible but meanwhile
keeps track of all the substitutions and their original rel before
replacement, so that in later processing stage, the replacement can be
recovered individually to produce a list of all possible rels with
substitution in different places.
|
List<RelNode> |
go(RelNode replacement_)
Returns a list of all possible rels that result from substituting the
matched RelNode with the replacement RelNode within the query.
|
RelNode |
go0(RelNode replacement_) |
private static boolean |
isEquivalent(RexBuilder rexBuilder,
RexNode condition,
RexNode target) |
protected boolean |
isWeaker(MutableRel rel0,
MutableRel rel)
Returns if one rel is weaker than another.
|
private SubstitutionVisitor.UnifyResult |
matchRecurse(MutableRel target) |
static boolean |
mayBeSatisfiable(RexNode e)
Returns whether a boolean expression ever returns true.
|
private static boolean |
mightMatch(SubstitutionVisitor.UnifyRule rule,
Class queryClass,
Class targetClass) |
static MutableAggregate |
permute(MutableAggregate aggregate,
MutableRel input,
Mapping mapping) |
private static void |
redoReplacement(List<SubstitutionVisitor.Replacement> replacement) |
(package private) void |
register(MutableRel result,
MutableRel query) |
static SubstitutionVisitor.Replacement |
replace(MutableRel query,
MutableRel find,
MutableRel replace)
Within a relational expression
query, replaces occurrences of
find with replace. |
private static SubstitutionVisitor.Replacement |
replaceRecurse(MutableRel query,
MutableRel find,
MutableRel replace)
|
private static void |
reverseSubstitute(RelBuilder relBuilder,
Holder query,
List<List<SubstitutionVisitor.Replacement>> matches,
List<RelNode> sub,
int replaceCount,
int maxCount) |
static RexNode |
splitFilter(RexSimplify simplify,
RexNode condition,
RexNode target)
Maps a condition onto a target.
|
private static RexNode |
splitOr(RexBuilder rexBuilder,
RexNode condition,
RexNode target) |
private static void |
undoReplacement(List<SubstitutionVisitor.Replacement> replacement) |
static MutableRel |
unifyAggregates(MutableAggregate query,
MutableAggregate target) |
private static final boolean DEBUG
private static final org.slf4j.Logger LOGGER
protected static final com.google.common.collect.ImmutableList<SubstitutionVisitor.UnifyRule> DEFAULT_RULES
protected final RelBuilder relBuilder
private final com.google.common.collect.ImmutableList<SubstitutionVisitor.UnifyRule> rules
private final RelOptCluster cluster
private final RexSimplify simplify
private final Holder query
private final MutableRel target
final List<MutableRel> targetLeaves
target that have no children.final List<MutableRel> queryLeaves
query that have no children.final Map<MutableRel,MutableRel> replacementMap
final com.google.common.collect.Multimap<MutableRel,MutableRel> equivalents
protected final MutableRel[] slots
public SubstitutionVisitor(RelNode target_, RelNode query_)
public SubstitutionVisitor(RelNode target_, RelNode query_, com.google.common.collect.ImmutableList<SubstitutionVisitor.UnifyRule> rules)
public SubstitutionVisitor(RelNode target_, RelNode query_, com.google.common.collect.ImmutableList<SubstitutionVisitor.UnifyRule> rules, RelBuilderFactory relBuilderFactory)
void register(MutableRel result, MutableRel query)
public static RexNode splitFilter(RexSimplify simplify, RexNode condition, RexNode target)
If condition is stronger than target, returns the residue.
If it is equal to target, returns the expression that evaluates to
the constant true. If it is weaker than target, returns
null.
The terms satisfy the relation
condition = target AND residue
and residue must be as weak as possible.
Example #1: condition stronger than target
Note that residue x > 0 AND y = 2 would also satisfy the
relation condition = target AND residue but is stronger than
necessary, so we prefer y = 2.
Example #2: target weaker than condition (valid, but not currently implemented)
Example #3: condition and target are equivalent
Example #4: condition weaker than target
There are many other possible examples. It amounts to solving
whether condition AND NOT target can ever evaluate to
true, and therefore is a form of the NP-complete
Satisfiability
problem.
private static RexNode canonizeNode(RexBuilder rexBuilder, RexNode condition)
private static RexNode splitOr(RexBuilder rexBuilder, RexNode condition, RexNode target)
private static boolean isEquivalent(RexBuilder rexBuilder, RexNode condition, RexNode target)
public static boolean mayBeSatisfiable(RexNode e)
This method may give false positives. For instance, it will say
that x = 5 AND x > 10 is satisfiable, because at present it
cannot prove that it is not.
public List<RelNode> go(RelNode replacement_)
For example, the substitution result of A join B, while A and B are both a qualified match for replacement R, is R join B, R join R, A join R.
private List<List<SubstitutionVisitor.Replacement>> go(MutableRel replacement)
public static SubstitutionVisitor.Replacement replace(MutableRel query, MutableRel find, MutableRel replace)
query, replaces occurrences of
find with replace.
Assumes relational expressions (and their descendants) are not null. Does not handle cycles.
private static SubstitutionVisitor.Replacement replaceRecurse(MutableRel query, MutableRel find, MutableRel replace)
private static void undoReplacement(List<SubstitutionVisitor.Replacement> replacement)
private static void redoReplacement(List<SubstitutionVisitor.Replacement> replacement)
private static void reverseSubstitute(RelBuilder relBuilder, Holder query, List<List<SubstitutionVisitor.Replacement>> matches, List<RelNode> sub, int replaceCount, int maxCount)
private SubstitutionVisitor.UnifyResult matchRecurse(MutableRel target)
private SubstitutionVisitor.UnifyResult apply(SubstitutionVisitor.UnifyRule rule, MutableRel query, MutableRel target)
private List<SubstitutionVisitor.UnifyRule> applicableRules(MutableRel query, MutableRel target)
private static boolean mightMatch(SubstitutionVisitor.UnifyRule rule, Class queryClass, Class targetClass)
public static MutableAggregate permute(MutableAggregate aggregate, MutableRel input, Mapping mapping)
private static List<AggregateCall> apply(Mapping mapping, List<AggregateCall> aggCallList)
public static MutableRel unifyAggregates(MutableAggregate query, MutableAggregate target)
public static SqlAggFunction getRollup(SqlAggFunction aggregation)
protected static RexShuttle getRexShuttle(MutableProject target)
protected boolean isWeaker(MutableRel rel0, MutableRel rel)
public static boolean equalType(String desc0, MutableRel rel0, String desc1, MutableRel rel1, Litmus litmus)
Copyright © 2012–2018 The Apache Software Foundation. All rights reserved.