/* * 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.eigenbase.rel; import java.util.*; import org.eigenbase.rel.metadata.*; import org.eigenbase.relopt.*; import org.eigenbase.reltype.*; import org.eigenbase.rex.*; /** * A <code>RelNode</code> is a relational expression. * * <p>A relational expression is not a scalar expression; see * {@link org.eigenbase.sql.SqlNode} and {@link RexNode}.</p> * * <p>If this type of relational expression has some particular planner rules, * it should implement the <em>public static</em> method * {@link AbstractRelNode#register}.</p> * * <p>When a relational expression comes to be implemented, the system allocates * a {@link org.eigenbase.relopt.RelImplementor} to manage the process. Every * implementable relational expression has a {@link RelTraitSet} describing its * physical attributes. The RelTraitSet always contains a {@link Convention} * describing how the expression passes data to its consuming * relational expression, but may contain other traits, including some applied * externally. Because traits can be applied externally, implementations of * RelNode should never assume the size or contents of their trait set (beyond * those traits configured by the RelNode itself).</p> * * <p>For each calling-convention, there is a corresponding sub-interface of * RelNode. For example, {@code net.hydromatic.optiq.rules.java.EnumerableRel} * has operations to manage the conversion to a graph of * {@code net.hydromatic.optiq.rules.java.EnumerableConvention} * calling-convention, and it interacts with a * {@code EnumerableRelImplementor}.</p> * * <p>A relational expression is only required to implement its * calling-convention's interface when it is actually implemented, that is, * converted into a plan/program. This means that relational expressions which * cannot be implemented, such as converters, are not required to implement * their convention's interface.</p> * * <p>Every relational expression must derive from {@link AbstractRelNode}. (Why * have the <code>RelNode</code> interface, then? We need a root interface, * because an interface can only derive from an interface.)</p> */ public interface RelNode extends RelOptNode, Cloneable { //~ Methods ---------------------------------------------------------------- /** * Returns a list of this relational expression's child expressions. * (These are scalar expressions, and so do not include the relational * inputs that are returned by {@link #getInputs}. * * <p>The caller should treat the list as unmodifiable; typical * implementations will return an immutable list. If there are no * child expressions, returns an empty list, not <code>null</code>. */ List<RexNode> getChildExps(); /** * Return the CallingConvention trait from this RelNode's {@link * #getTraitSet() trait set}. * * @return this RelNode's CallingConvention */ Convention getConvention(); /** * Sets the name of the variable which is to be implicitly set at runtime * each time a row is returned from this relational expression * * @param correlVariable Name of correlating variable */ void setCorrelVariable(String correlVariable); /** * Returns the name of the variable which is to be implicitly set at runtime * each time a row is returned from this relational expression; or null if * there is no variable. * * @return Name of correlating variable, or null */ String getCorrelVariable(); /** * Returns whether the same value will not come out twice. Default value is * <code>false</code>, derived classes should override. */ boolean isDistinct(); /** * Returns the <code>i</code><sup>th</sup> input relational expression. * * @param i Ordinal of input * @return <code>i</code><sup>th</sup> input */ RelNode getInput(int i); /** * Returns a variable with which to reference the current row of this * relational expression as a correlating variable. Creates a variable if * none exists. */ String getOrCreateCorrelVariable(); /** * Returns the sub-query this relational expression belongs to. A sub-query * determines the scope for correlating variables (see {@link * #setCorrelVariable(String)}). * * @return Sub-query */ RelOptQuery getQuery(); /** * Returns the type of the rows returned by this relational expression. */ RelDataType getRowType(); /** * Returns the type of the rows expected for an input. Defaults to {@link * #getRowType}. * * @param ordinalInParent input's 0-based ordinal with respect to this * parent rel * @return expected row type */ RelDataType getExpectedInputRowType(int ordinalInParent); /** * Returns an array of this relational expression's inputs. If there are no * inputs, returns an empty array, not <code>null</code>. */ List<RelNode> getInputs(); /** * Returns an estimate of the number of rows this relational expression will * return. * * <p>NOTE jvs 29-Mar-2006: Don't call this method directly. Instead, use * {@link RelMetadataQuery#getRowCount}, which gives plugins a chance to * override the rel's default ideas about row count. */ double getRows(); /** * Returns the names of variables which are set in this relational * expression but also used and therefore not available to parents of this * relational expression. * * <p>By default, returns the empty set. Derived classes may override this * method.</p> */ Set<String> getVariablesStopped(); /** * Collects variables known to be used by this expression or its * descendants. By default, no such information is available and must be * derived by analyzing sub-expressions, but some optimizer implementations * may insert special expressions which remember such information. * * @param variableSet receives variables used */ void collectVariablesUsed(Set<String> variableSet); /** * Collects variables set by this expression. * * @param variableSet receives variables known to be set by */ void collectVariablesSet(Set<String> variableSet); /** * Interacts with the {@link RelVisitor} in a {@link * org.eigenbase.util.Glossary#VISITOR_PATTERN visitor pattern} to traverse * the tree of relational expressions. */ void childrenAccept(RelVisitor visitor); /** * Returns the cost of this plan (not including children). The base * implementation throws an error; derived classes should override. * * <p>NOTE jvs 29-Mar-2006: Don't call this method directly. Instead, use * {@link RelMetadataQuery#getNonCumulativeCost}, which gives plugins a * chance to override the rel's default ideas about cost. */ RelOptCost computeSelfCost(RelOptPlanner planner); /** * Returns a metadata interface. * * @param metadataClass Metadata interface * @param <M> Type of metadata being requested * @return Metadata object that supplies the desired metadata (never null, * although if the information is not present the metadata object may * return null from all methods) */ <M extends Metadata> M metadata(Class<M> metadataClass); /** * Describes the inputs and attributes of this relational expression. * Each node should call {@code super.explain}, then call the * {@link RelWriterImpl#input(String, RelNode)} * and {@link RelWriterImpl#item(String, Object)} methods for each input * and attribute. * * @param pw Plan writer */ void explain(RelWriter pw); /** * Receives notification that this expression is about to be registered. The * implementation of this method must at least register all child * expressions. */ RelNode onRegister(RelOptPlanner planner); /** * Computes the digest, assigns it, and returns it. For planner use only. */ String recomputeDigest(); /** * Registers a correlation variable. * * @see #getVariablesStopped */ void registerCorrelVariable(String correlVariable); /** * Replaces the <code>ordinalInParent</code><sup>th</sup> input. You must * override this method if you override {@link #getInputs}. */ void replaceInput( int ordinalInParent, RelNode p); /** * If this relational expression represents an access to a table, returns * that table, otherwise returns null. */ RelOptTable getTable(); /** * Returns the name of this relational expression's class, sans package * name, for use in explain. For example, for a <code> * org.eigenbase.rel.ArrayRel.ArrayReader</code>, this method returns * "ArrayReader". */ String getRelTypeName(); /** * Returns whether this relational expression is valid. * * <p>If assertions are enabled, this method is typically called with <code> * fail</code> = <code>true</code>, as follows: * * <blockquote> * <pre>assert rel.isValid(true)</pre> * </blockquote> * * This signals that the method can throw an {@link AssertionError} if it is * not valid. * * @param fail Whether to fail if invalid * @return Whether relational expression is valid * @throws AssertionError if this relational expression is invalid and * fail=true and assertions are enabled */ boolean isValid(boolean fail); /** * Returns a description of the physical ordering (or orderings) of this * relational expression. Never null. */ List<RelCollation> getCollationList(); /** * Creates a copy of this relational expression, perhaps changing traits and * inputs. * * <p>Sub-classes with other important attributes are encouraged to create * variants of this method with more parameters.</p> * * @param traitSet Trait set * @param inputs Inputs * @return Copy of this relational expression, substituting traits and * inputs */ RelNode copy( RelTraitSet traitSet, List<RelNode> inputs); /** * Registers any special rules specific to this kind of relational * expression. * * <p>The planner calls this method this first time that it sees a * relational expression of this class. The derived class should call {@link * org.eigenbase.relopt.RelOptPlanner#addRule} for each rule, and then call * {@code super.register}.</p> */ void register(RelOptPlanner planner); /** * Returns whether the result of this relational expression is uniquely * identified by this columns with the given ordinals. * * <p>For example, if this relational expression is a TableAccessRel to * T(A, B, C, D) whose key is (A, B), then isKey([0, 1]) yields true, * and isKey([0]) and isKey([0, 2]) yields false.</p> * * @param columns Ordinals of key columns * @return Whether the given columns are a key or a superset of a key */ boolean isKey(BitSet columns); /** * Accepts a visit from a shuttle. * * @param shuttle Shuttle * @return A copy of this node incorporating changes made by the shuttle to * this node's children */ RelNode accept(RelShuttle shuttle); } // End RelNode.java