blob: 1ef793393238cfa3e90c7cae0725a2dab0d3632a [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.calcite.plan;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.metadata.CachingRelMetadataProvider;
import org.apache.calcite.rel.metadata.RelMetadataProvider;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.calcite.rex.RexExecutor;
import org.apache.calcite.util.CancelFlag;
import org.apache.calcite.util.trace.CalciteTrace;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.slf4j.Logger;
import java.util.List;
import java.util.regex.Pattern;
/**
* A <code>RelOptPlanner</code> is a query optimizer: it transforms a relational
* expression into a semantically equivalent relational expression, according to
* a given set of rules and a cost model.
*/
public interface RelOptPlanner {
//~ Static fields/initializers ---------------------------------------------
Logger LOGGER = CalciteTrace.getPlannerTracer();
//~ Methods ----------------------------------------------------------------
/**
* Sets the root node of this query.
*
* @param rel Relational expression
*/
void setRoot(RelNode rel);
/**
* Returns the root node of this query.
*
* @return Root node
*/
@Nullable RelNode getRoot();
/**
* Registers a rel trait definition. If the {@link RelTraitDef} has already
* been registered, does nothing.
*
* @return whether the RelTraitDef was added, as per
* {@link java.util.Collection#add}
*/
boolean addRelTraitDef(RelTraitDef relTraitDef);
/**
* Clear all the registered RelTraitDef.
*/
void clearRelTraitDefs();
/**
* Returns the list of active trait types.
*/
List<RelTraitDef> getRelTraitDefs();
/**
* Removes all internal state, including all registered rules,
* materialized views, and lattices.
*/
void clear();
/**
* Returns the list of all registered rules.
*/
List<RelOptRule> getRules();
/**
* Registers a rule.
*
* <p>If the rule has already been registered, does nothing.
* This method determines if the given rule is a
* {@link org.apache.calcite.rel.convert.ConverterRule} and pass the
* ConverterRule to all
* {@link #addRelTraitDef(RelTraitDef) registered} RelTraitDef
* instances.
*
* @return whether the rule was added, as per
* {@link java.util.Collection#add}
*/
boolean addRule(RelOptRule rule);
/**
* Removes a rule.
*
* @return true if the rule was present, as per
* {@link java.util.Collection#remove(Object)}
*/
boolean removeRule(RelOptRule rule);
/**
* Provides the Context created when this planner was constructed.
*
* @return Never null; either an externally defined context, or a dummy
* context that returns null for each requested interface
*/
Context getContext();
/**
* Sets the exclusion filter to use for this planner. Rules which match the
* given pattern will not be fired regardless of whether or when they are
* added to the planner.
*
* @param exclusionFilter pattern to match for exclusion; null to disable
* filtering
*/
void setRuleDescExclusionFilter(@Nullable Pattern exclusionFilter);
/**
* Does nothing.
*
* @deprecated Previously, this method installed the cancellation-checking
* flag for this planner, but is now deprecated. Now, you should add a
* {@link CancelFlag} to the {@link Context} passed to the constructor.
*
* @param cancelFlag flag which the planner should periodically check
*/
@Deprecated // to be removed before 2.0
void setCancelFlag(CancelFlag cancelFlag);
/**
* Changes a relational expression to an equivalent one with a different set
* of traits.
*
* @param rel Relational expression (may or may not have been registered; must
* not have the desired traits)
* @param toTraits Trait set to convert the relational expression to
* @return Relational expression with desired traits. Never null, but may be
* abstract
*/
RelNode changeTraits(RelNode rel, RelTraitSet toTraits);
/**
* Negotiates an appropriate planner to deal with distributed queries. The
* idea is that the schemas decide among themselves which has the most
* knowledge. Right now, the local planner retains control.
*/
RelOptPlanner chooseDelegate();
/**
* Defines a pair of relational expressions that are equivalent.
*
* <p>Typically {@code tableRel} is a
* {@link org.apache.calcite.rel.logical.LogicalTableScan} representing a
* table that is a materialized view and {@code queryRel} is the SQL
* expression that populates that view. The intention is that
* {@code tableRel} is cheaper to evaluate and therefore if the query being
* optimized uses (or can be rewritten to use) {@code queryRel} as a
* sub-expression then it can be optimized by using {@code tableRel}
* instead.</p>
*/
void addMaterialization(RelOptMaterialization materialization);
/**
* Returns the materializations that have been registered with the planner.
*/
List<RelOptMaterialization> getMaterializations();
/**
* Defines a lattice.
*
* <p>The lattice may have materializations; it is not necessary to call
* {@link #addMaterialization} for these; they are registered implicitly.
*/
void addLattice(RelOptLattice lattice);
/**
* Retrieves a lattice, given its star table.
*/
@Nullable RelOptLattice getLattice(RelOptTable table);
/**
* Finds the most efficient expression to implement this query.
*
* @throws CannotPlanException if cannot find a plan
*/
RelNode findBestExp();
/**
* Returns the factory that creates
* {@link org.apache.calcite.plan.RelOptCost}s.
*/
RelOptCostFactory getCostFactory();
/**
* Computes the cost of a RelNode. In most cases, this just dispatches to
* {@link RelMetadataQuery#getCumulativeCost}.
*
* @param rel Relational expression of interest
* @param mq Metadata query
* @return estimated cost
*/
@Nullable RelOptCost getCost(RelNode rel, RelMetadataQuery mq);
// CHECKSTYLE: IGNORE 2
/** @deprecated Use {@link #getCost(RelNode, RelMetadataQuery)}
* or, better, call {@link RelMetadataQuery#getCumulativeCost(RelNode)}. */
@Deprecated // to be removed before 2.0
@Nullable RelOptCost getCost(RelNode rel);
/**
* Registers a relational expression in the expression bank.
*
* <p>After it has been registered, you may not modify it.
*
* <p>The expression must not already have been registered. If you are not
* sure whether it has been registered, call
* {@link #ensureRegistered(RelNode, RelNode)}.
*
* @param rel Relational expression to register (must not already be
* registered)
* @param equivRel Relational expression it is equivalent to (may be null)
* @return the same expression, or an equivalent existing expression
*/
RelNode register(
RelNode rel,
@Nullable RelNode equivRel);
/**
* Registers a relational expression if it is not already registered.
*
* <p>If {@code equivRel} is specified, {@code rel} is placed in the same
* equivalence set. It is OK if {@code equivRel} has different traits;
* {@code rel} will end up in a different subset of the same set.
*
* <p>It is OK if {@code rel} is a subset.
*
* @param rel Relational expression to register
* @param equivRel Relational expression it is equivalent to (may be null)
* @return Registered relational expression
*/
RelNode ensureRegistered(RelNode rel, @Nullable RelNode equivRel);
/**
* Determines whether a relational expression has been registered.
*
* @param rel expression to test
* @return whether rel has been registered
*/
boolean isRegistered(RelNode rel);
/**
* Tells this planner that a schema exists. This is the schema's chance to
* tell the planner about all of the special transformation rules.
*/
void registerSchema(RelOptSchema schema);
/**
* Adds a listener to this planner.
*
* @param newListener new listener to be notified of events
*/
void addListener(RelOptListener newListener);
/**
* Gives this planner a chance to register one or more
* {@link RelMetadataProvider}s in the chain which will be used to answer
* metadata queries.
*
* <p>Planners which use their own relational expressions internally
* to represent concepts such as equivalence classes will generally need to
* supply corresponding metadata providers.</p>
*
* @param list receives planner's custom providers, if any
*/
@Deprecated // to be removed before 2.0
void registerMetadataProviders(List<RelMetadataProvider> list);
/**
* Gets a timestamp for a given rel's metadata. This timestamp is used by
* {@link CachingRelMetadataProvider} to decide whether cached metadata has
* gone stale.
*
* @param rel rel of interest
* @return timestamp of last change which might affect metadata derivation
*/
@Deprecated // to be removed before 2.0
long getRelMetadataTimestamp(RelNode rel);
/**
* Prunes a node from the planner.
*
* <p>When a node is pruned, the related pending rule
* calls are cancelled, and future rules will not fire.
* This can be used to reduce the search space. </p>
* @param rel the node to prune.
*/
void prune(RelNode rel);
/**
* Registers a class of RelNode. If this class of RelNode has been seen
* before, does nothing.
*
* @param node Relational expression
*/
void registerClass(RelNode node);
/**
* Creates an empty trait set. It contains all registered traits, and the
* default values of any traits that have them.
*
* <p>The empty trait set acts as the prototype (a kind of factory) for all
* subsequently created trait sets.</p>
*
* @return Empty trait set
*/
RelTraitSet emptyTraitSet();
/** Sets the object that can execute scalar expressions. */
void setExecutor(@Nullable RexExecutor executor);
/** Returns the executor used to evaluate constant expressions. */
@Nullable RexExecutor getExecutor();
/** Called when a relational expression is copied to a similar expression. */
void onCopy(RelNode rel, RelNode newRel);
// CHECKSTYLE: IGNORE 1
/** @deprecated Use {@link RexExecutor} */
@Deprecated // to be removed before 2.0
interface Executor extends RexExecutor {
}
/**
* Thrown by {@link org.apache.calcite.plan.RelOptPlanner#findBestExp()}.
*/
class CannotPlanException extends RuntimeException {
public CannotPlanException(String message) {
super(message);
}
}
}