| /* |
| * 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); |
| } |
| } |
| } |