blob: 2cebbe64cd57873e596baab9cab1b9d0fb778318 [file] [log] [blame]
/*
// Licensed to Julian Hyde under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// Julian Hyde 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.eigenbase.relopt;
import java.util.*;
import java.util.logging.*;
import org.eigenbase.rel.*;
import org.eigenbase.trace.*;
import com.google.common.collect.ImmutableList;
/**
* A <code>RelOptRuleCall</code> is an invocation of a {@link RelOptRule} with a
* set of {@link RelNode relational expression}s as arguments.
*/
public abstract class RelOptRuleCall
{
//~ Static fields/initializers ---------------------------------------------
protected static final Logger tracer = EigenbaseTrace.getPlannerTracer();
/** Generator for {@link #id} values. */
static int nextId = 0;
//~ Instance fields --------------------------------------------------------
public final int id;
private final RelOptRuleOperand operand0;
private final Map<RelNode, List<RelNode>> nodeChildren;
public final RelOptRule rule;
public final RelNode [] rels;
private final RelOptPlanner planner;
private final List<RelNode> parents;
//~ Constructors -----------------------------------------------------------
/**
* Creates a RelOptRuleCall.
*
* @param planner Planner
* @param operand Root operand
* @param rels Array of relational expressions which matched each operand
* @param nodeChildren For each node which matched with <code>
* matchAnyChildren</code>=true, a list of the node's children
* @param parents list of parent RelNodes corresponding to the first
* relational expression in the array argument, if known; otherwise, null
*/
protected RelOptRuleCall(
RelOptPlanner planner,
RelOptRuleOperand operand,
RelNode [] rels,
Map<RelNode, List<RelNode>> nodeChildren,
List<RelNode> parents)
{
this.id = nextId++;
this.planner = planner;
this.operand0 = operand;
this.nodeChildren = nodeChildren;
this.rule = operand.getRule();
this.rels = rels;
this.parents = parents;
assert rels.length == rule.operands.size();
}
protected RelOptRuleCall(
RelOptPlanner planner,
RelOptRuleOperand operand,
RelNode[] rels,
Map<RelNode, List<RelNode>> nodeChildren)
{
this(planner, operand, rels, nodeChildren, null);
}
//~ Methods ----------------------------------------------------------------
/**
* Returns the root operand matched by this rule.
*
* @return root operand
*/
public RelOptRuleOperand getOperand0()
{
return operand0;
}
/**
* Returns the invoked planner rule.
*
* @return planner rule
*/
public RelOptRule getRule()
{
return rule;
}
/**
* Returns a list of matched relational expressions.
*
* @return matched relational expressions
*
* @deprecated Use {@link #getRelList()} or {@link #rel(int)}
*/
public RelNode [] getRels()
{
return rels;
}
/**
* Returns a list of matched relational expressions.
*
* @return matched relational expressions
* @see #rel(int)
*/
public List<RelNode> getRelList()
{
return ImmutableList.copyOf(rels);
}
/**
* Retrieves the {@code ordinal}th matched relational expression. This
* corresponds to the {@code ordinal}th operand of the rule.
*
* @param ordinal Ordinal
* @param <T> Type
* @return Relational expression
*/
public <T extends RelNode> T rel(int ordinal) {
//noinspection unchecked
return (T) rels[ordinal];
}
/**
* Returns the children of a given relational expression node matched in a
* rule.
*
* <p>If the operand which caused the match has {@link
* RelOptRuleOperand#matchAnyChildren}=false, the children will have their
* own operands and therefore be easily available in the array returned by
* the {@link #getRels} method, so this method returns null.
*
* <p>This method is for {@link RelOptRuleOperand#matchAnyChildren}=true,
* which is generally used when a node can have a variable number of
* children, and hence where the matched children are not retrievable by any
* other means.
*
* @param rel Relational expression
*
* @return Children of relational expression
*/
public List<RelNode> getChildRels(RelNode rel)
{
return nodeChildren.get(rel);
}
/**
* Returns the planner.
*
* @return planner
*/
public RelOptPlanner getPlanner()
{
return planner;
}
/**
* @return list of parents of the first relational expression
*/
public List<RelNode> getParents()
{
return parents;
}
/**
* Called by the rule whenever it finds a match. The implementation of this
* method will guarantee that the original relational expression (e.g.,
* <code>this.rels[0]</code>) has its traits propagated to the new
* relational expression (<code>rel</code>) and its unregistered children.
* Any trait not specifically set in the RelTraitSet returned by <code>
* rel.getTraits()</code> will be copied from <code>
* this.rels[0].getTraitSet()</code>.
*/
public abstract void transformTo(RelNode rel);
}
// End RelOptRuleCall.java