|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||
java.lang.Objectorg.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 RelMetadataProviders 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 RelOptRuleCalls 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)
RelOptPlannerRelTraitDef has already
been registered, does nothing.
addRelTraitDef in interface RelOptPlanneraddRelTraitDef in class AbstractRelOptPlannerCollection.add(E)public boolean addRule(RelOptRule rule)
RelOptPlannerConverterRule 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 RelOptPlannerchooseDelegate in class AbstractRelOptPlannerpublic 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 RelOptPlannermakeCost in class AbstractRelOptPlannerpublic RelOptCost makeHugeCost()
RelOptPlanner
makeHugeCost in interface RelOptPlannermakeHugeCost in class AbstractRelOptPlannerpublic RelOptCost makeInfiniteCost()
RelOptPlanner
makeInfiniteCost in interface RelOptPlannermakeInfiniteCost in class AbstractRelOptPlannerpublic RelOptCost makeTinyCost()
RelOptPlanner
makeTinyCost in interface RelOptPlannermakeTinyCost in class AbstractRelOptPlannerpublic RelOptCost makeZeroCost()
RelOptPlanner
makeZeroCost in interface RelOptPlannermakeZeroCost in class AbstractRelOptPlanner
public RelNode register(RelNode rel,
RelNode equivRel)
RelOptPlannerAfter 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 RelOptPlannerregisterSchema in class AbstractRelOptPlannerpublic JavaRelImplementor getJavaRelImplementor(RelNode rel)
RelOptPlanner
getJavaRelImplementor in interface RelOptPlannergetJavaRelImplementor in class AbstractRelOptPlannerpublic RelOptCost getCost(RelNode rel)
RelOptPlannerRelMetadataQuery.getCumulativeCost(org.eigenbase.rel.RelNode).
getCost in interface RelOptPlannergetCost in class AbstractRelOptPlannerrel - 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)
RelOptPlannerAn 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 RelOptPlannersetImportance in class AbstractRelOptPlannerrel - 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 expression
void 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 RelNodeset - set that rel belongs to, or null
private RelSubset registerSubset(RelSet set,
RelSubset subset)
public void addListener(RelOptListener newListener)
RelOptPlanner
addListener in interface RelOptPlanneraddListener in class AbstractRelOptPlannernewListener - new listener to be notified of eventspublic void registerMetadataProviders(ChainedRelMetadataProvider chain)
RelOptPlannerRelMetadataProviders 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 RelOptPlannerregisterMetadataProviders in class AbstractRelOptPlannerchain - receives planner's custom providers, if anypublic long getRelMetadataTimestamp(RelNode rel)
RelOptPlannerCachingRelMetadataProvider to decide whether cached metadata has
gone stale.
getRelMetadataTimestamp in interface RelOptPlannergetRelMetadataTimestamp in class AbstractRelOptPlannerrel - 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 | ||||||||