blob: 92c5e6226c7df211316e80acb788751e45fcc9ba [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.checkerframework.checker.nullness.qual.Nullable;
import java.util.EventListener;
import java.util.EventObject;
/**
* RelOptListener defines an interface for listening to events which occur
* during the optimization process.
*/
public interface RelOptListener extends EventListener {
//~ Methods ----------------------------------------------------------------
/**
* Notifies this listener that a relational expression has been registered
* with a particular equivalence class after an equivalence has been either
* detected or asserted. Equivalence classes may be either logical (all
* expressions which yield the same result set) or physical (all expressions
* which yield the same result set with a particular calling convention).
*
* @param event details about the event
*/
void relEquivalenceFound(RelEquivalenceEvent event);
/**
* Notifies this listener that an optimizer rule is being applied to a
* particular relational expression. This rule is called twice; once before
* the rule is invoked, and once after. Note that the rel attribute of the
* event is always the old expression.
*
* @param event details about the event
*/
void ruleAttempted(RuleAttemptedEvent event);
/**
* Notifies this listener that an optimizer rule has been successfully
* applied to a particular relational expression, resulting in a new
* equivalent expression (relEquivalenceFound will also be called unless the
* new expression is identical to an existing one). This rule is called
* twice; once before registration of the new rel, and once after. Note that
* the rel attribute of the event is always the new expression; to get the
* old expression, use event.getRuleCall().rels[0].
*
* @param event details about the event
*/
void ruleProductionSucceeded(RuleProductionEvent event);
/**
* Notifies this listener that a relational expression is no longer of
* interest to the planner.
*
* @param event details about the event
*/
void relDiscarded(RelDiscardedEvent event);
/**
* Notifies this listener that a relational expression has been chosen as
* part of the final implementation of the query plan. After the plan is
* complete, this is called one more time with null for the rel.
*
* @param event details about the event
*/
void relChosen(RelChosenEvent event);
//~ Inner Classes ----------------------------------------------------------
/**
* Event class for abstract event dealing with a relational expression. The
* source of an event is typically the RelOptPlanner which initiated it.
*/
abstract class RelEvent extends EventObject {
private final @Nullable RelNode rel;
protected RelEvent(Object eventSource, @Nullable RelNode rel) {
super(eventSource);
this.rel = rel;
}
public @Nullable RelNode getRel() {
return rel;
}
}
/** Event indicating that a relational expression has been chosen. */
class RelChosenEvent extends RelEvent {
public RelChosenEvent(Object eventSource, @Nullable RelNode rel) {
super(eventSource, rel);
}
}
/** Event indicating that a relational expression has been found to
* be equivalent to an equivalence class. */
class RelEquivalenceEvent extends RelEvent {
private final Object equivalenceClass;
private final boolean isPhysical;
public RelEquivalenceEvent(
Object eventSource,
RelNode rel,
Object equivalenceClass,
boolean isPhysical) {
super(eventSource, rel);
this.equivalenceClass = equivalenceClass;
this.isPhysical = isPhysical;
}
public Object getEquivalenceClass() {
return equivalenceClass;
}
public boolean isPhysical() {
return isPhysical;
}
}
/** Event indicating that a relational expression has been discarded. */
class RelDiscardedEvent extends RelEvent {
public RelDiscardedEvent(Object eventSource, RelNode rel) {
super(eventSource, rel);
}
}
/** Event indicating that a planner rule has fired. */
abstract class RuleEvent extends RelEvent {
private final RelOptRuleCall ruleCall;
protected RuleEvent(
Object eventSource,
RelNode rel,
RelOptRuleCall ruleCall) {
super(eventSource, rel);
this.ruleCall = ruleCall;
}
public RelOptRuleCall getRuleCall() {
return ruleCall;
}
}
/** Event indicating that a planner rule has been attempted. */
class RuleAttemptedEvent extends RuleEvent {
private final boolean before;
public RuleAttemptedEvent(
Object eventSource,
RelNode rel,
RelOptRuleCall ruleCall,
boolean before) {
super(eventSource, rel, ruleCall);
this.before = before;
}
public boolean isBefore() {
return before;
}
}
/** Event indicating that a planner rule has produced a result. */
class RuleProductionEvent extends RuleAttemptedEvent {
public RuleProductionEvent(
Object eventSource,
RelNode rel,
RelOptRuleCall ruleCall,
boolean before) {
super(eventSource, rel, ruleCall, before);
}
}
}