|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object org.eigenbase.relopt.AbstractRelOptPlanner org.eigenbase.relopt.volcano.VolcanoPlanner
public class VolcanoPlanner
VolcanoPlanner optimizes queries by transforming expressions selectively according to a dynamic programming algorithm.
Nested Class Summary | |
---|---|
private static class |
VolcanoPlanner.DeferringRuleCall
A rule call which defers its actions. |
Field Summary | |
---|---|
private List<RelOptRuleOperand> |
allOperands
List of all operands of all rules. |
(package private) List<RelSet> |
allSets
List of all sets. |
protected boolean |
ambitious
If true, the planner keeps applying rules as long as they continue to reduce the cost. |
protected static double |
CostImprovement
|
protected boolean |
impatient
If true, and if ambitious is true, the planner waits a finite
number of iterations for the cost to improve. |
(package private) RelOptListener |
listener
Listener for this planner, or null if none set. |
private Map<String,RelNode> |
mapDigestToRel
Canonical map from digest to the unique relational expression with that digest. |
private IdentityHashMap<RelNode,RelSubset> |
mapRel2Subset
Map each registered expression ( RelNode ) to its equivalence set
(RelSubset ). |
private int |
nextSetId
|
private String |
originalRootString
Dump of the root relational expression, as it was before any rules were applied. |
private int |
registerCount
Incremented every time a relational expression is registered or two sets are merged. |
private Set<RelOptSchema> |
registeredSchemas
List of all schemas which have been registered. |
(package private) Map<RelNode,Double> |
relImportances
The importance of relational expressions. |
protected RelSubset |
root
|
(package private) RuleQueue |
ruleQueue
Holds rule calls waiting to be fired. |
protected Set<RelOptRule> |
ruleSet
Set of all registered rules. |
private List<RelTraitDef> |
traitDefs
Holds the currently registered RelTraitDefs. |
Fields inherited from interface org.eigenbase.relopt.RelOptPlanner |
---|
tracer |
Constructor Summary | |
---|---|
VolcanoPlanner()
Creates a uninitialized VolcanoPlanner . |
Method Summary | |
---|---|
void |
addListener(RelOptListener newListener)
Adds a listener to this planner. |
boolean |
addRelTraitDef(RelTraitDef relTraitDef)
Registers a rel trait definition. |
boolean |
addRule(RelOptRule rule)
Registers a rule. |
boolean |
canConvert(RelTraitSet fromTraits,
RelTraitSet toTraits)
|
private RelSubset |
canonize(RelSubset subset)
If a subset has one or more equivalent subsets (owing to a set having merged with another), returns the subset which is the leader of the equivalence class. |
RelNode |
changeTraits(RelNode rel,
RelTraitSet toTraits)
Changes a relational expression to an equivalent one with a different set of traits. |
(package private) RelNode |
changeTraitsUsingConverters(RelNode rel,
RelTraitSet toTraits)
|
private RelNode |
changeTraitsUsingConverters(RelNode rel,
RelTraitSet toTraits,
boolean allowAbstractConverters)
|
(package private) void |
checkForSatisfiedConverters(RelSet set,
RelNode rel)
|
RelOptPlanner |
chooseDelegate()
Negotiates an appropriate planner to deal with distributed queries. |
private void |
clearImportanceBoost()
Clear all importance boosts. |
void |
dump(PrintWriter pw)
Dumps the internal state of this VolcanoPlanner to a writer. |
RelNode |
ensureRegistered(RelNode rel,
RelNode equivRel)
Registers a relational expression if it is not already registered. |
RelNode |
findBestExp()
Finds the most efficient expression to implement the query given via setRoot(RelNode) . |
(package private) void |
fireRules(RelNode rel,
boolean deferred)
Fires all rules matched by a relational expression. |
private boolean |
fixupInputs(RelNode rel)
|
RelOptRuleOperand[] |
getConversionOperands(CallingConvention toConvention)
|
RelOptCost |
getCost(RelNode rel)
Computes the cost of a RelNode. |
JavaRelImplementor |
getJavaRelImplementor(RelNode rel)
Retrieves an implementor appropriate for the context in which this planner was created. |
protected VolcanoPlannerPhaseRuleMappingInitializer |
getPhaseRuleMappingInitializer()
|
long |
getRelMetadataTimestamp(RelNode rel)
Gets a timestamp for a given rel's metadata. |
RelNode |
getRoot()
Returns the root node of this query. |
RelSet |
getSet(RelNode rel)
Finds an expression's equivalence set. |
RelSubset |
getSubset(RelNode rel)
Returns the subset that a relational expression belongs to. |
RelSubset |
getSubset(RelNode rel,
RelTraitSet traits)
|
RelSubset |
getSubset(RelNode rel,
RelTraitSet traits,
boolean createIfMissing)
|
private void |
injectImportanceBoost()
Finds RelSubsets in the plan that contain only rels of CallingConvention.NONE and boosts their importance by 25%. |
boolean |
isRegistered(RelNode rel)
Determines whether a relational expression has been registered. |
RelOptCost |
makeCost(double dRows,
double dCpu,
double dIo)
Creates a cost object. |
RelOptCost |
makeHugeCost()
Creates a cost object representing an enormous non-infinite cost. |
RelOptCost |
makeInfiniteCost()
Creates a cost object representing infinite cost. |
RelOptCost |
makeTinyCost()
Creates a cost object representing a small positive cost. |
RelOptCost |
makeZeroCost()
Creates a cost object representing zero cost. |
private void |
merge(RelSet set,
RelSet set2)
|
static String |
normalizePlan(String plan)
Normalizes references to subsets within the string representation of a plan. |
RelNode |
register(RelNode rel,
RelNode equivRel)
Registers a relational expression in the expression bank. |
void |
registerAbstractRelationalRules()
|
private RelSubset |
registerImpl(RelNode rel,
RelSet set)
Registers a new expression exp and queues up rule matches. |
void |
registerMetadataProviders(ChainedRelMetadataProvider chain)
Gives this planner a chance to register one or more RelMetadataProvider s in the chain which will be used to answer metadata
queries. |
void |
registerSchema(RelOptSchema schema)
Tells this planner that a schema exists. |
private RelSubset |
registerSubset(RelSet set,
RelSubset subset)
|
boolean |
removeRule(RelOptRule rule)
Removes a rule. |
(package private) void |
rename(RelNode rel)
Re-computes the digest of a RelNode . |
(package private) void |
reregister(RelSet set,
RelNode rel)
Registers a RelNode , which has already been registered, in a new
RelSet . |
void |
setImportance(RelNode rel,
double importance)
Sets the importance of a relational expression. |
private void |
setInitialImportance()
|
void |
setRoot(RelNode rel)
Sets the root node of this query. |
protected void |
validate()
Checks internal consistency. |
Methods inherited from class org.eigenbase.relopt.AbstractRelOptPlanner |
---|
checkCancel, fireRule, getListener, getRuleByDescription, isRuleExcluded, mapRuleDescription, notifyChosen, notifyDiscard, notifyEquivalence, notifyTransformation, setCancelFlag, setRuleDescExclusionFilter, unmapRuleDescription |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
protected static final double CostImprovement
protected RelSubset root
protected boolean ambitious
protected boolean impatient
ambitious
is true, the planner waits a finite
number of iterations for the cost to improve.
The number of iterations K is equal to the number of iterations
required to get the first finite plan. After the first finite plan, it
continues to fire rules to try to improve it. The planner sets a target
cost of the current best cost multiplied by CostImprovement
. If
it does not meet that cost target within K steps, it quits, and uses the
current best plan. If it meets the cost, it sets a new, lower target, and
has another K iterations to meet it. And so forth.
If false, the planner continues to fire rules until the rule queue is empty.
private final List<RelOptRuleOperand> allOperands
final List<RelSet> allSets
private final Map<String,RelNode> mapDigestToRel
digest
to the unique relational expression
with that digest.
private final IdentityHashMap<RelNode,RelSubset> mapRel2Subset
RelNode
) to its equivalence set
(RelSubset
).
We use an IdentityHashMap
to simplify the process of merging
RelSet
objects. Most RelNode
objects are identified by
their digest, which involves the set that their child relational
expressions belong to. If those children belong to the same set, we have
to be careful, otherwise it gets incestuous.
final Map<RelNode,Double> relImportances
The map contains only RelNodes whose importance has been overridden
using RelOptPlanner.setImportance(RelNode, double)
. Other
RelNodes are presumed to have 'normal' importance.
If a RelNode has 0 importance, all RelOptRuleCall
s using it
are ignored, and future RelOptRuleCalls are not queued up.
private final Set<RelOptSchema> registeredSchemas
final RuleQueue ruleQueue
private final List<RelTraitDef> traitDefs
protected final Set<RelOptRule> ruleSet
private int nextSetId
private int registerCount
RelOptListener listener
private String originalRootString
Constructor Detail |
---|
public VolcanoPlanner()
VolcanoPlanner
. To fully initialize
it, the caller must register the desired set of relations, rules, and
calling conventions.
Method Detail |
---|
protected VolcanoPlannerPhaseRuleMappingInitializer getPhaseRuleMappingInitializer()
public RelOptRuleOperand[] getConversionOperands(CallingConvention toConvention)
public boolean isRegistered(RelNode rel)
RelOptPlanner
rel
- expression to test
public void setRoot(RelNode rel)
RelOptPlanner
rel
- Relational expressionpublic RelNode getRoot()
RelOptPlanner
public RelSet getSet(RelNode rel)
rel
- Relational expression
public boolean addRelTraitDef(RelTraitDef relTraitDef)
RelOptPlanner
RelTraitDef
has already
been registered, does nothing.
addRelTraitDef
in interface RelOptPlanner
addRelTraitDef
in class AbstractRelOptPlanner
Collection.add(E)
public boolean addRule(RelOptRule rule)
RelOptPlanner
ConverterRule
and pass the ConverterRule to
all registered
RelTraitDef
instances.
Collection.add(E)
public boolean removeRule(RelOptRule rule)
RelOptPlanner
Collection.remove(Object)
public boolean canConvert(RelTraitSet fromTraits, RelTraitSet toTraits)
public RelNode changeTraits(RelNode rel, RelTraitSet toTraits)
RelOptPlanner
rel
- Relational expression, may or may not have been registeredtoTraits
- Trait set to convert relational expression to
public RelOptPlanner chooseDelegate()
RelOptPlanner
chooseDelegate
in interface RelOptPlanner
chooseDelegate
in class AbstractRelOptPlanner
public RelNode findBestExp()
setRoot(RelNode)
.
The algorithm executes repeatedly in a series of phases. In each phase
the exact rules that may be fired varies. The mapping of phases to rule
sets is maintained in the ruleQueue
.
In each phase, the planner sets the initial importance of the existing
RelSubSets (setInitialImportance()
). The planner then iterates
over the rule matches presented by the rule queue until:
Furthermore, after every 10 iterations without an implementable plan,
RelSubSets that contain only logical RelNodes are given an importance
boost via injectImportanceBoost()
. Once an implementable plan is
found, the artificially raised importances are cleared (clearImportanceBoost()
).
private void setInitialImportance()
private void injectImportanceBoost()
CallingConvention.NONE
and boosts their importance by 25%.
private void clearImportanceBoost()
public RelOptCost makeCost(double dRows, double dCpu, double dIo)
RelOptPlanner
makeCost
in interface RelOptPlanner
makeCost
in class AbstractRelOptPlanner
public RelOptCost makeHugeCost()
RelOptPlanner
makeHugeCost
in interface RelOptPlanner
makeHugeCost
in class AbstractRelOptPlanner
public RelOptCost makeInfiniteCost()
RelOptPlanner
makeInfiniteCost
in interface RelOptPlanner
makeInfiniteCost
in class AbstractRelOptPlanner
public RelOptCost makeTinyCost()
RelOptPlanner
makeTinyCost
in interface RelOptPlanner
makeTinyCost
in class AbstractRelOptPlanner
public RelOptCost makeZeroCost()
RelOptPlanner
makeZeroCost
in interface RelOptPlanner
makeZeroCost
in class AbstractRelOptPlanner
public RelNode register(RelNode rel, RelNode equivRel)
RelOptPlanner
After it has been registered, you may not modify it.
The expression must not already have been registered. If you are not
sure whether it has been registered, call RelOptPlanner.ensureRegistered(RelNode,RelNode)
.
rel
- Relational expression to register (must not already be
registered)equivRel
- Relational expression it is equivalent to (may be null)
public RelNode ensureRegistered(RelNode rel, RelNode equivRel)
RelOptPlanner
rel
- Relational expression to registerequivRel
- Relational expression it is equivalent to (may be null)
protected void validate()
public void registerAbstractRelationalRules()
public void registerSchema(RelOptSchema schema)
RelOptPlanner
registerSchema
in interface RelOptPlanner
registerSchema
in class AbstractRelOptPlanner
public JavaRelImplementor getJavaRelImplementor(RelNode rel)
RelOptPlanner
getJavaRelImplementor
in interface RelOptPlanner
getJavaRelImplementor
in class AbstractRelOptPlanner
public RelOptCost getCost(RelNode rel)
RelOptPlanner
RelMetadataQuery.getCumulativeCost(org.eigenbase.rel.RelNode)
.
getCost
in interface RelOptPlanner
getCost
in class AbstractRelOptPlanner
rel
- expression of interest
public RelSubset getSubset(RelNode rel)
rel
- Relational expression
public RelSubset getSubset(RelNode rel, RelTraitSet traits)
public RelSubset getSubset(RelNode rel, RelTraitSet traits, boolean createIfMissing)
private RelNode changeTraitsUsingConverters(RelNode rel, RelTraitSet toTraits, boolean allowAbstractConverters)
RelNode changeTraitsUsingConverters(RelNode rel, RelTraitSet toTraits)
void checkForSatisfiedConverters(RelSet set, RelNode rel)
public void setImportance(RelNode rel, double importance)
RelOptPlanner
An important use of this method is when a RelOptRule
has
created a relational expression which is indisputably better than the
original relational expression. The rule set the original relational
expression's importance to zero, to reduce the search space. Pending rule
calls are cancelled, and future rules will not fire.
setImportance
in interface RelOptPlanner
setImportance
in class AbstractRelOptPlanner
rel
- Relational expressionimportance
- Importancepublic void dump(PrintWriter pw)
pw
- Print writernormalizePlan(String)
void rename(RelNode rel)
RelNode
.
Since a relational expression's digest contains the identifiers of its children, this method needs to be called when the child has been renamed, for example if the child's set merges with another.
rel
- Relational expressionvoid reregister(RelSet set, RelNode rel)
RelNode
, which has already been registered, in a new
RelSet
.
set
- Setrel
- Relational expressionprivate RelSubset canonize(RelSubset subset)
subset
- Subset
void fireRules(RelNode rel, boolean deferred)
rel
- Relational expression which has just been created (or maybe
from the queue)deferred
- If true, each time a rule matches, just add an entry to
the queue.private boolean fixupInputs(RelNode rel)
private void merge(RelSet set, RelSet set2)
private RelSubset registerImpl(RelNode rel, RelSet set)
exp
and queues up rule matches.
If set
is not null, makes the expression part of that
equivalence set. If an identical expression is already registered, we
don't need to register this one and nor should we queue up rule matches.
rel
- relational expression to register. Must be either a RelSubset
, or an unregistered RelNode
set
- set that rel belongs to, or null
private RelSubset registerSubset(RelSet set, RelSubset subset)
public void addListener(RelOptListener newListener)
RelOptPlanner
addListener
in interface RelOptPlanner
addListener
in class AbstractRelOptPlanner
newListener
- new listener to be notified of eventspublic void registerMetadataProviders(ChainedRelMetadataProvider chain)
RelOptPlanner
RelMetadataProvider
s in the chain which will be used to answer metadata
queries. Planners which use their own relational expressions internally
to represent concepts such as equivalence classes will generally need to
supply corresponding metadata providers.
registerMetadataProviders
in interface RelOptPlanner
registerMetadataProviders
in class AbstractRelOptPlanner
chain
- receives planner's custom providers, if anypublic long getRelMetadataTimestamp(RelNode rel)
RelOptPlanner
CachingRelMetadataProvider
to decide whether cached metadata has
gone stale.
getRelMetadataTimestamp
in interface RelOptPlanner
getRelMetadataTimestamp
in class AbstractRelOptPlanner
rel
- rel of interest
public static String normalizePlan(String plan)
This is useful when writing tests: it helps to ensure that tests don't break when an extra rule is introduced that generates a new subset and causes subsequent subset numbers to be off by one.
For example,
FennelAggRel.FENNEL_EXEC(child=Subset#17.FENNEL_EXEC,groupCount=1, EXPR$1=COUNT())becomes
FennelSortRel.FENNEL_EXEC(child=Subset#2.FENNEL_EXEC, key=[0], discardDuplicates=false)
FennelCalcRel.FENNEL_EXEC( child=Subset#4.FENNEL_EXEC, expr#0..8={inputs}, expr#9=3456, DEPTNO=$t7, $f0=$t9)
MockTableImplRel.FENNEL_EXEC( table=[CATALOG, SALES, EMP])
FennelAggRel.FENNEL_EXEC(child=Subset#{0}.FENNEL_EXEC, groupCount=1, EXPR$1=COUNT())
FennelSortRel.FENNEL_EXEC(child=Subset#{1}.FENNEL_EXEC, key=[0], discardDuplicates=false)
FennelCalcRel.FENNEL_EXEC( child=Subset#{2}.FENNEL_EXEC,expr#0..8={inputs},expr#9=3456,DEPTNO=$t7, $f0=$t9)
MockTableImplRel.FENNEL_EXEC( table=[CATALOG, SALES, EMP])
plan
- Plan
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |