All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hazelcast.org.apache.calcite.rel.metadata.RelMetadataQuery Maven / Gradle / Ivy

There is a newer version: 5.5.0
Show newest version
/*
 * 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 com.hazelcast.org.apache.calcite.rel.metadata;

import com.hazelcast.org.apache.calcite.plan.RelOptCost;
import com.hazelcast.org.apache.calcite.plan.RelOptPredicateList;
import com.hazelcast.org.apache.calcite.plan.RelOptTable;
import com.hazelcast.org.apache.calcite.plan.volcano.VolcanoPlanner;
import com.hazelcast.org.apache.calcite.rel.RelCollation;
import com.hazelcast.org.apache.calcite.rel.RelDistribution;
import com.hazelcast.org.apache.calcite.rel.RelDistributions;
import com.hazelcast.org.apache.calcite.rel.RelNode;
import com.hazelcast.org.apache.calcite.rex.RexNode;
import com.hazelcast.org.apache.calcite.rex.RexTableInputRef.RelTableRef;
import com.hazelcast.org.apache.calcite.sql.SqlExplainLevel;
import com.hazelcast.org.apache.calcite.util.ImmutableBitSet;

import com.hazelcast.com.google.common.base.Supplier;
import com.hazelcast.com.google.common.base.Suppliers;
import com.hazelcast.com.google.common.collect.ImmutableList;
import com.hazelcast.com.google.common.collect.Iterables;
import com.hazelcast.com.google.common.collect.Multimap;

import com.hazelcast.org.checkerframework.checker.nullness.qual.Nullable;

import java.util.Collections;
import java.util.List;
import java.util.Set;

import static com.hazelcast.org.apache.calcite.linq4j.Nullness.castNonNull;

/**
 * RelMetadataQuery provides a strongly-typed facade on top of
 * {@link RelMetadataProvider} for the set of relational expression metadata
 * queries defined as standard within Calcite. The Javadoc on these methods
 * serves as their primary specification.
 *
 * 

To add a new standard query Xyz to this interface, follow * these steps: * *

    *
  1. Add a static method getXyz specification to this class. *
  2. Add unit tests to {@code com.hazelcast.org.apache.calcite.test.RelMetadataTest}. *
  3. Write a new provider class RelMdXyz in this package. Follow * the pattern from an existing class such as {@link RelMdColumnOrigins}, * overloading on all of the logical relational expressions to which the query * applies. *
  4. Add a {@code SOURCE} static member, similar to * {@link RelMdColumnOrigins#SOURCE}. *
  5. Register the {@code SOURCE} object in {@link DefaultRelMetadataProvider}. *
  6. Get unit tests working. *
* *

Because relational expression metadata is extensible, extension projects * can define similar facades in order to specify access to custom metadata. * Please do not add queries here (nor on {@link RelNode}) which lack meaning * outside of your extension. * *

Besides adding new metadata queries, extension projects may need to add * custom providers for the standard queries in order to handle additional * relational expressions (either logical or physical). In either case, the * process is the same: write a reflective provider and chain it on to an * instance of {@link DefaultRelMetadataProvider}, pre-pending it to the default * providers. Then supply that instance to the planner via the appropriate * plugin mechanism. */ public class RelMetadataQuery extends RelMetadataQueryBase { // An empty prototype. Only initialize on first use. private static final Supplier EMPTY = Suppliers.memoize(() -> new RelMetadataQuery(false)); private BuiltInMetadata.Collation.Handler collationHandler; private BuiltInMetadata.ColumnOrigin.Handler columnOriginHandler; private BuiltInMetadata.ExpressionLineage.Handler expressionLineageHandler; private BuiltInMetadata.TableReferences.Handler tableReferencesHandler; private BuiltInMetadata.ColumnUniqueness.Handler columnUniquenessHandler; private BuiltInMetadata.CumulativeCost.Handler cumulativeCostHandler; private BuiltInMetadata.DistinctRowCount.Handler distinctRowCountHandler; private BuiltInMetadata.Distribution.Handler distributionHandler; private BuiltInMetadata.ExplainVisibility.Handler explainVisibilityHandler; private BuiltInMetadata.MaxRowCount.Handler maxRowCountHandler; private BuiltInMetadata.MinRowCount.Handler minRowCountHandler; private BuiltInMetadata.Memory.Handler memoryHandler; private BuiltInMetadata.NonCumulativeCost.Handler nonCumulativeCostHandler; private BuiltInMetadata.Parallelism.Handler parallelismHandler; private BuiltInMetadata.PercentageOriginalRows.Handler percentageOriginalRowsHandler; private BuiltInMetadata.PopulationSize.Handler populationSizeHandler; private BuiltInMetadata.Predicates.Handler predicatesHandler; private BuiltInMetadata.AllPredicates.Handler allPredicatesHandler; private BuiltInMetadata.NodeTypes.Handler nodeTypesHandler; private BuiltInMetadata.RowCount.Handler rowCountHandler; private BuiltInMetadata.Selectivity.Handler selectivityHandler; private BuiltInMetadata.Size.Handler sizeHandler; private BuiltInMetadata.UniqueKeys.Handler uniqueKeysHandler; private BuiltInMetadata.LowerBoundCost.Handler lowerBoundCostHandler; /** * Creates the instance with {@link JaninoRelMetadataProvider} instance * from {@link #THREAD_PROVIDERS} and {@link #EMPTY} as a prototype. */ protected RelMetadataQuery() { this(castNonNull(THREAD_PROVIDERS.get()), EMPTY.get()); } /** * Create a RelMetadataQuery with a given {@link MetadataHandlerProvider}. * @param provider The provider to use for construction. */ public RelMetadataQuery(MetadataHandlerProvider provider) { super(provider); this.collationHandler = provider.handler(BuiltInMetadata.Collation.Handler.class); this.columnOriginHandler = provider.handler(BuiltInMetadata.ColumnOrigin.Handler.class); this.expressionLineageHandler = provider.handler(BuiltInMetadata.ExpressionLineage.Handler.class); this.tableReferencesHandler = provider.handler(BuiltInMetadata.TableReferences.Handler.class); this.columnUniquenessHandler = provider.handler(BuiltInMetadata.ColumnUniqueness.Handler.class); this.cumulativeCostHandler = provider.handler(BuiltInMetadata.CumulativeCost.Handler.class); this.distinctRowCountHandler = provider.handler(BuiltInMetadata.DistinctRowCount.Handler.class); this.distributionHandler = provider.handler(BuiltInMetadata.Distribution.Handler.class); this.explainVisibilityHandler = provider.handler(BuiltInMetadata.ExplainVisibility.Handler.class); this.maxRowCountHandler = provider.handler(BuiltInMetadata.MaxRowCount.Handler.class); this.minRowCountHandler = provider.handler(BuiltInMetadata.MinRowCount.Handler.class); this.memoryHandler = provider.handler(BuiltInMetadata.Memory.Handler.class); this.nonCumulativeCostHandler = provider.handler(BuiltInMetadata.NonCumulativeCost.Handler.class); this.parallelismHandler = provider.handler(BuiltInMetadata.Parallelism.Handler.class); this.percentageOriginalRowsHandler = provider.handler(BuiltInMetadata.PercentageOriginalRows.Handler.class); this.populationSizeHandler = provider.handler(BuiltInMetadata.PopulationSize.Handler.class); this.predicatesHandler = provider.handler(BuiltInMetadata.Predicates.Handler.class); this.allPredicatesHandler = provider.handler(BuiltInMetadata.AllPredicates.Handler.class); this.nodeTypesHandler = provider.handler(BuiltInMetadata.NodeTypes.Handler.class); this.rowCountHandler = provider.handler(BuiltInMetadata.RowCount.Handler.class); this.selectivityHandler = provider.handler(BuiltInMetadata.Selectivity.Handler.class); this.sizeHandler = provider.handler(BuiltInMetadata.Size.Handler.class); this.uniqueKeysHandler = provider.handler(BuiltInMetadata.UniqueKeys.Handler.class); this.lowerBoundCostHandler = provider.handler(BuiltInMetadata.LowerBoundCost.Handler.class); } /** Creates and initializes the instance that will serve as a prototype for * all other instances in the Janino case. */ @SuppressWarnings("deprecation") private RelMetadataQuery(@SuppressWarnings("unused") boolean dummy) { super(null); this.collationHandler = initialHandler(BuiltInMetadata.Collation.Handler.class); this.columnOriginHandler = initialHandler(BuiltInMetadata.ColumnOrigin.Handler.class); this.expressionLineageHandler = initialHandler(BuiltInMetadata.ExpressionLineage.Handler.class); this.tableReferencesHandler = initialHandler(BuiltInMetadata.TableReferences.Handler.class); this.columnUniquenessHandler = initialHandler(BuiltInMetadata.ColumnUniqueness.Handler.class); this.cumulativeCostHandler = initialHandler(BuiltInMetadata.CumulativeCost.Handler.class); this.distinctRowCountHandler = initialHandler(BuiltInMetadata.DistinctRowCount.Handler.class); this.distributionHandler = initialHandler(BuiltInMetadata.Distribution.Handler.class); this.explainVisibilityHandler = initialHandler(BuiltInMetadata.ExplainVisibility.Handler.class); this.maxRowCountHandler = initialHandler(BuiltInMetadata.MaxRowCount.Handler.class); this.minRowCountHandler = initialHandler(BuiltInMetadata.MinRowCount.Handler.class); this.memoryHandler = initialHandler(BuiltInMetadata.Memory.Handler.class); this.nonCumulativeCostHandler = initialHandler(BuiltInMetadata.NonCumulativeCost.Handler.class); this.parallelismHandler = initialHandler(BuiltInMetadata.Parallelism.Handler.class); this.percentageOriginalRowsHandler = initialHandler(BuiltInMetadata.PercentageOriginalRows.Handler.class); this.populationSizeHandler = initialHandler(BuiltInMetadata.PopulationSize.Handler.class); this.predicatesHandler = initialHandler(BuiltInMetadata.Predicates.Handler.class); this.allPredicatesHandler = initialHandler(BuiltInMetadata.AllPredicates.Handler.class); this.nodeTypesHandler = initialHandler(BuiltInMetadata.NodeTypes.Handler.class); this.rowCountHandler = initialHandler(BuiltInMetadata.RowCount.Handler.class); this.selectivityHandler = initialHandler(BuiltInMetadata.Selectivity.Handler.class); this.sizeHandler = initialHandler(BuiltInMetadata.Size.Handler.class); this.uniqueKeysHandler = initialHandler(BuiltInMetadata.UniqueKeys.Handler.class); this.lowerBoundCostHandler = initialHandler(BuiltInMetadata.LowerBoundCost.Handler.class); } private RelMetadataQuery( MetadataHandlerProvider metadataHandlerProvider, RelMetadataQuery prototype) { super(metadataHandlerProvider); this.collationHandler = prototype.collationHandler; this.columnOriginHandler = prototype.columnOriginHandler; this.expressionLineageHandler = prototype.expressionLineageHandler; this.tableReferencesHandler = prototype.tableReferencesHandler; this.columnUniquenessHandler = prototype.columnUniquenessHandler; this.cumulativeCostHandler = prototype.cumulativeCostHandler; this.distinctRowCountHandler = prototype.distinctRowCountHandler; this.distributionHandler = prototype.distributionHandler; this.explainVisibilityHandler = prototype.explainVisibilityHandler; this.maxRowCountHandler = prototype.maxRowCountHandler; this.minRowCountHandler = prototype.minRowCountHandler; this.memoryHandler = prototype.memoryHandler; this.nonCumulativeCostHandler = prototype.nonCumulativeCostHandler; this.parallelismHandler = prototype.parallelismHandler; this.percentageOriginalRowsHandler = prototype.percentageOriginalRowsHandler; this.populationSizeHandler = prototype.populationSizeHandler; this.predicatesHandler = prototype.predicatesHandler; this.allPredicatesHandler = prototype.allPredicatesHandler; this.nodeTypesHandler = prototype.nodeTypesHandler; this.rowCountHandler = prototype.rowCountHandler; this.selectivityHandler = prototype.selectivityHandler; this.sizeHandler = prototype.sizeHandler; this.uniqueKeysHandler = prototype.uniqueKeysHandler; this.lowerBoundCostHandler = prototype.lowerBoundCostHandler; } //~ Methods ---------------------------------------------------------------- /** * Returns an instance of RelMetadataQuery. It ensures that cycles do not * occur while computing metadata. */ public static RelMetadataQuery instance() { return new RelMetadataQuery(); } /** * Returns the * {@link BuiltInMetadata.NodeTypes#getNodeTypes()} * statistic. * * @param rel the relational expression */ public @Nullable Multimap, RelNode> getNodeTypes(RelNode rel) { for (;;) { try { return nodeTypesHandler.getNodeTypes(rel, this); } catch (MetadataHandlerProvider.NoHandler e) { nodeTypesHandler = revise(BuiltInMetadata.NodeTypes.Handler.class); } catch (CyclicMetadataException e) { return null; } } } /** * Returns the * {@link BuiltInMetadata.RowCount#getRowCount()} * statistic. * * @param rel the relational expression * @return estimated row count, or null if no reliable estimate can be * determined */ public /* @Nullable: CALCITE-4263 */ Double getRowCount(RelNode rel) { for (;;) { try { Double result = rowCountHandler.getRowCount(rel, this); return RelMdUtil.validateResult(castNonNull(result)); } catch (MetadataHandlerProvider.NoHandler e) { rowCountHandler = revise(BuiltInMetadata.RowCount.Handler.class); } } } /** * Returns the * {@link BuiltInMetadata.MaxRowCount#getMaxRowCount()} * statistic. * * @param rel the relational expression * @return max row count */ public @Nullable Double getMaxRowCount(RelNode rel) { for (;;) { try { return maxRowCountHandler.getMaxRowCount(rel, this); } catch (MetadataHandlerProvider.NoHandler e) { maxRowCountHandler = revise(BuiltInMetadata.MaxRowCount.Handler.class); } } } /** * Returns the * {@link BuiltInMetadata.MinRowCount#getMinRowCount()} * statistic. * * @param rel the relational expression * @return max row count */ public @Nullable Double getMinRowCount(RelNode rel) { for (;;) { try { return minRowCountHandler.getMinRowCount(rel, this); } catch (MetadataHandlerProvider.NoHandler e) { minRowCountHandler = revise(BuiltInMetadata.MinRowCount.Handler.class); } } } /** * Returns the * {@link BuiltInMetadata.CumulativeCost#getCumulativeCost()} * statistic. * * @param rel the relational expression * @return estimated cost, or null if no reliable estimate can be determined */ public @Nullable RelOptCost getCumulativeCost(RelNode rel) { for (;;) { try { return cumulativeCostHandler.getCumulativeCost(rel, this); } catch (MetadataHandlerProvider.NoHandler e) { cumulativeCostHandler = revise(BuiltInMetadata.CumulativeCost.Handler.class); } } } /** * Returns the * {@link BuiltInMetadata.NonCumulativeCost#getNonCumulativeCost()} * statistic. * * @param rel the relational expression * @return estimated cost, or null if no reliable estimate can be determined */ public @Nullable RelOptCost getNonCumulativeCost(RelNode rel) { for (;;) { try { return nonCumulativeCostHandler.getNonCumulativeCost(rel, this); } catch (MetadataHandlerProvider.NoHandler e) { nonCumulativeCostHandler = revise(BuiltInMetadata.NonCumulativeCost.Handler.class); } } } /** * Returns the * {@link BuiltInMetadata.PercentageOriginalRows#getPercentageOriginalRows()} * statistic. * * @param rel the relational expression * @return estimated percentage (between 0.0 and 1.0), or null if no * reliable estimate can be determined */ public @Nullable Double getPercentageOriginalRows(RelNode rel) { for (;;) { try { Double result = percentageOriginalRowsHandler.getPercentageOriginalRows(rel, this); return RelMdUtil.validatePercentage(result); } catch (MetadataHandlerProvider.NoHandler e) { percentageOriginalRowsHandler = revise(BuiltInMetadata.PercentageOriginalRows.Handler.class); } } } /** * Returns the * {@link BuiltInMetadata.ColumnOrigin#getColumnOrigins(int)} * statistic. * * @param rel the relational expression * @param column 0-based ordinal for output column of interest * @return set of origin columns, or null if this information cannot be * determined (whereas empty set indicates Handler.classinitely no origin columns at * all) */ public @Nullable Set getColumnOrigins(RelNode rel, int column) { for (;;) { try { return columnOriginHandler.getColumnOrigins(rel, this, column); } catch (MetadataHandlerProvider.NoHandler e) { columnOriginHandler = revise(BuiltInMetadata.ColumnOrigin.Handler.class); } } } /** * Determines the origin of a column. * * @see #getColumnOrigins(com.hazelcast.org.apache.calcite.rel.RelNode, int) * * @param rel the RelNode of the column * @param column the offset of the column whose origin we are trying to * determine * * @return the origin of a column */ public @Nullable RelColumnOrigin getColumnOrigin(RelNode rel, int column) { final Set origins = getColumnOrigins(rel, column); if (origins == null || origins.size() != 1) { return null; } final RelColumnOrigin origin = Iterables.getOnlyElement(origins); return origin; } /** * Determines the origin of a column. */ public @Nullable Set getExpressionLineage(RelNode rel, RexNode expression) { for (;;) { try { return expressionLineageHandler.getExpressionLineage(rel, this, expression); } catch (MetadataHandlerProvider.NoHandler e) { expressionLineageHandler = revise(BuiltInMetadata.ExpressionLineage.Handler.class); } } } /** * Determines the tables used by a plan. */ public @Nullable Set getTableReferences(RelNode rel) { for (;;) { try { return tableReferencesHandler.getTableReferences(rel, this); } catch (MetadataHandlerProvider.NoHandler e) { tableReferencesHandler = revise(BuiltInMetadata.TableReferences.Handler.class); } } } /** * Determines the origin of a {@link RelNode}, provided it maps to a single * table, optionally with filtering and projection. * * @param rel the RelNode * * @return the table, if the RelNode is a simple table; otherwise null */ public @Nullable RelOptTable getTableOrigin(RelNode rel) { // Determine the simple origin of the first column in the // RelNode. If it's simple, then that means that the underlying // table is also simple, even if the column itself is derived. if (rel.getRowType().getFieldCount() == 0) { return null; } final Set colOrigins = getColumnOrigins(rel, 0); if (colOrigins == null || colOrigins.size() == 0) { return null; } return colOrigins.iterator().next().getOriginTable(); } /** * Returns the * {@link BuiltInMetadata.Selectivity#getSelectivity(RexNode)} * statistic. * * @param rel the relational expression * @param predicate predicate whose selectivity is to be estimated against * {@code rel}'s output * @return estimated selectivity (between 0.0 and 1.0), or null if no * reliable estimate can be determined */ public @Nullable Double getSelectivity(RelNode rel, @Nullable RexNode predicate) { for (;;) { try { Double result = selectivityHandler.getSelectivity(rel, this, predicate); return RelMdUtil.validatePercentage(result); } catch (MetadataHandlerProvider.NoHandler e) { selectivityHandler = revise(BuiltInMetadata.Selectivity.Handler.class); } } } /** * Returns the * {@link BuiltInMetadata.UniqueKeys#getUniqueKeys(boolean)} * statistic. * * @param rel the relational expression * @return set of keys, or null if this information cannot be determined * (whereas empty set indicates Handler.classinitely no keys at all) */ public @Nullable Set getUniqueKeys(RelNode rel) { return getUniqueKeys(rel, false); } /** * Returns the * {@link BuiltInMetadata.UniqueKeys#getUniqueKeys(boolean)} * statistic. * * @param rel the relational expression * @param ignoreNulls if true, ignore null values when determining * whether the keys are unique * * @return set of keys, or null if this information cannot be determined * (whereas empty set indicates definitely no keys at all) */ public @Nullable Set getUniqueKeys(RelNode rel, boolean ignoreNulls) { for (;;) { try { return uniqueKeysHandler.getUniqueKeys(rel, this, ignoreNulls); } catch (MetadataHandlerProvider.NoHandler e) { uniqueKeysHandler = revise(BuiltInMetadata.UniqueKeys.Handler.class); } } } /** * Returns whether the rows of a given relational expression are distinct, * optionally ignoring NULL values. * *

This is derived by applying the * {@link BuiltInMetadata.ColumnUniqueness#areColumnsUnique(com.hazelcast.org.apache.calcite.util.ImmutableBitSet, boolean)} * statistic over all columns. If * {@link BuiltInMetadata.MaxRowCount#getMaxRowCount()} * is less than or equal to one, we shortcut the process and declare the rows * unique. * * @param rel the relational expression * @param ignoreNulls if true, ignore null values when determining column * uniqueness * * @return whether the rows are unique, or * null if not enough information is available to make that determination */ public @Nullable Boolean areRowsUnique(RelNode rel, boolean ignoreNulls) { Double maxRowCount = this.getMaxRowCount(rel); if (maxRowCount != null && maxRowCount <= 1D) { return true; } final ImmutableBitSet columns = ImmutableBitSet.range(rel.getRowType().getFieldCount()); return areColumnsUnique(rel, columns, ignoreNulls); } /** * Returns whether the rows of a given relational expression are distinct. * *

Derived by calling {@link #areRowsUnique(RelNode, boolean)}. * * @param rel the relational expression * * @return whether the rows are unique, or * null if not enough information is available to make that determination */ public @Nullable Boolean areRowsUnique(RelNode rel) { return areRowsUnique(rel, false); } /** * Returns the * {@link BuiltInMetadata.ColumnUniqueness#areColumnsUnique(ImmutableBitSet, boolean)} * statistic. * * @param rel the relational expression * @param columns column mask representing the subset of columns for which * uniqueness will be determined * * @return true or false depending on whether the columns are unique, or * null if not enough information is available to make that determination */ public @Nullable Boolean areColumnsUnique(RelNode rel, ImmutableBitSet columns) { return areColumnsUnique(rel, columns, false); } /** * Returns the * {@link BuiltInMetadata.ColumnUniqueness#areColumnsUnique(ImmutableBitSet, boolean)} * statistic. * * @param rel the relational expression * @param columns column mask representing the subset of columns for which * uniqueness will be determined * @param ignoreNulls if true, ignore null values when determining column * uniqueness * @return true or false depending on whether the columns are unique, or * null if not enough information is available to make that determination */ public @Nullable Boolean areColumnsUnique(RelNode rel, ImmutableBitSet columns, boolean ignoreNulls) { for (;;) { try { return columnUniquenessHandler.areColumnsUnique(rel, this, columns, ignoreNulls); } catch (MetadataHandlerProvider.NoHandler e) { columnUniquenessHandler = revise(BuiltInMetadata.ColumnUniqueness.Handler.class); } } } /** * Returns the * {@link BuiltInMetadata.Collation#collations()} * statistic. * * @param rel the relational expression * @return List of sorted column combinations, or * null if not enough information is available to make that determination */ public @Nullable ImmutableList collations(RelNode rel) { for (;;) { try { return collationHandler.collations(rel, this); } catch (MetadataHandlerProvider.NoHandler e) { collationHandler = revise(BuiltInMetadata.Collation.Handler.class); } } } /** * Returns the * {@link BuiltInMetadata.Distribution#distribution()} * statistic. * * @param rel the relational expression * @return List of sorted column combinations, or * null if not enough information is available to make that determination */ public RelDistribution distribution(RelNode rel) { for (;;) { try { RelDistribution distribution = distributionHandler.distribution(rel, this); //noinspection ConstantConditions if (distribution == null) { return RelDistributions.ANY; } return distribution; } catch (MetadataHandlerProvider.NoHandler e) { distributionHandler = revise(BuiltInMetadata.Distribution.Handler.class); } } } /** * Returns the * {@link BuiltInMetadata.PopulationSize#getPopulationSize(ImmutableBitSet)} * statistic. * * @param rel the relational expression * @param groupKey column mask representing the subset of columns for which * the row count will be determined * @return distinct row count for the given groupKey, or null if no reliable * estimate can be determined * */ public @Nullable Double getPopulationSize(RelNode rel, ImmutableBitSet groupKey) { for (;;) { try { Double result = populationSizeHandler.getPopulationSize(rel, this, groupKey); return RelMdUtil.validateResult(result); } catch (MetadataHandlerProvider.NoHandler e) { populationSizeHandler = revise(BuiltInMetadata.PopulationSize.Handler.class); } } } /** * Returns the * {@link BuiltInMetadata.Size#averageRowSize()} * statistic. * * @param rel the relational expression * @return average size of a row, in bytes, or null if not known */ public @Nullable Double getAverageRowSize(RelNode rel) { for (;;) { try { return sizeHandler.averageRowSize(rel, this); } catch (MetadataHandlerProvider.NoHandler e) { sizeHandler = revise(BuiltInMetadata.Size.Handler.class); } } } /** * Returns the * {@link BuiltInMetadata.Size#averageColumnSizes()} * statistic. * * @param rel the relational expression * @return a list containing, for each column, the average size of a column * value, in bytes. Each value or the entire list may be null if the * metadata is not available */ public @Nullable List<@Nullable Double> getAverageColumnSizes(RelNode rel) { for (;;) { try { return sizeHandler.averageColumnSizes(rel, this); } catch (MetadataHandlerProvider.NoHandler e) { sizeHandler = revise(BuiltInMetadata.Size.Handler.class); } } } /** As {@link #getAverageColumnSizes(com.hazelcast.org.apache.calcite.rel.RelNode)} but * never returns a null list, only ever a list of nulls. */ public List<@Nullable Double> getAverageColumnSizesNotNull(RelNode rel) { final @Nullable List<@Nullable Double> averageColumnSizes = getAverageColumnSizes(rel); return averageColumnSizes == null ? Collections.nCopies(rel.getRowType().getFieldCount(), null) : averageColumnSizes; } /** * Returns the * {@link BuiltInMetadata.Parallelism#isPhaseTransition()} * statistic. * * @param rel the relational expression * @return whether each physical operator implementing this relational * expression belongs to a different process than its inputs, or null if not * known */ public @Nullable Boolean isPhaseTransition(RelNode rel) { for (;;) { try { return parallelismHandler.isPhaseTransition(rel, this); } catch (MetadataHandlerProvider.NoHandler e) { parallelismHandler = revise(BuiltInMetadata.Parallelism.Handler.class); } } } /** * Returns the * {@link BuiltInMetadata.Parallelism#splitCount()} * statistic. * * @param rel the relational expression * @return the number of distinct splits of the data, or null if not known */ public @Nullable Integer splitCount(RelNode rel) { for (;;) { try { return parallelismHandler.splitCount(rel, this); } catch (MetadataHandlerProvider.NoHandler e) { parallelismHandler = revise(BuiltInMetadata.Parallelism.Handler.class); } } } /** * Returns the * {@link BuiltInMetadata.Memory#memory()} * statistic. * * @param rel the relational expression * @return the expected amount of memory, in bytes, required by a physical * operator implementing this relational expression, across all splits, * or null if not known */ public @Nullable Double memory(RelNode rel) { for (;;) { try { return memoryHandler.memory(rel, this); } catch (MetadataHandlerProvider.NoHandler e) { memoryHandler = revise(BuiltInMetadata.Memory.Handler.class); } } } /** * Returns the * {@link BuiltInMetadata.Memory#cumulativeMemoryWithinPhase()} * statistic. * * @param rel the relational expression * @return the cumulative amount of memory, in bytes, required by the * physical operator implementing this relational expression, and all other * operators within the same phase, across all splits, or null if not known */ public @Nullable Double cumulativeMemoryWithinPhase(RelNode rel) { for (;;) { try { return memoryHandler.cumulativeMemoryWithinPhase(rel, this); } catch (MetadataHandlerProvider.NoHandler e) { memoryHandler = revise(BuiltInMetadata.Memory.Handler.class); } } } /** * Returns the * {@link BuiltInMetadata.Memory#cumulativeMemoryWithinPhaseSplit()} * statistic. * * @param rel the relational expression * @return the expected cumulative amount of memory, in bytes, required by * the physical operator implementing this relational expression, and all * operators within the same phase, within each split, or null if not known */ public @Nullable Double cumulativeMemoryWithinPhaseSplit(RelNode rel) { for (;;) { try { return memoryHandler.cumulativeMemoryWithinPhaseSplit(rel, this); } catch (MetadataHandlerProvider.NoHandler e) { memoryHandler = revise(BuiltInMetadata.Memory.Handler.class); } } } /** * Returns the * {@link BuiltInMetadata.DistinctRowCount#getDistinctRowCount(ImmutableBitSet, RexNode)} * statistic. * * @param rel the relational expression * @param groupKey column mask representing group by columns * @param predicate pre-filtered predicates * @return distinct row count for groupKey, filtered by predicate, or null * if no reliable estimate can be determined */ public @Nullable Double getDistinctRowCount( RelNode rel, ImmutableBitSet groupKey, @Nullable RexNode predicate) { for (;;) { try { Double result = distinctRowCountHandler.getDistinctRowCount(rel, this, groupKey, predicate); return RelMdUtil.validateResult(result); } catch (MetadataHandlerProvider.NoHandler e) { distinctRowCountHandler = revise(BuiltInMetadata.DistinctRowCount.Handler.class); } } } /** * Returns the * {@link BuiltInMetadata.Predicates#getPredicates()} * statistic. * * @param rel the relational expression * @return Predicates that can be pulled above this RelNode */ public RelOptPredicateList getPulledUpPredicates(RelNode rel) { for (;;) { try { RelOptPredicateList result = predicatesHandler.getPredicates(rel, this); return result != null ? result : RelOptPredicateList.EMPTY; } catch (MetadataHandlerProvider.NoHandler e) { predicatesHandler = revise(BuiltInMetadata.Predicates.Handler.class); } } } /** * Returns the * {@link BuiltInMetadata.AllPredicates#getAllPredicates()} * statistic. * * @param rel the relational expression * @return All predicates within and below this RelNode */ public @Nullable RelOptPredicateList getAllPredicates(RelNode rel) { for (;;) { try { return allPredicatesHandler.getAllPredicates(rel, this); } catch (MetadataHandlerProvider.NoHandler e) { allPredicatesHandler = revise(BuiltInMetadata.AllPredicates.Handler.class); } } } /** * Returns the * {@link BuiltInMetadata.ExplainVisibility#isVisibleInExplain(SqlExplainLevel)} * statistic. * * @param rel the relational expression * @param explainLevel level of detail * @return true for visible, false for invisible; if no metadata is available, * defaults to true */ public Boolean isVisibleInExplain(RelNode rel, SqlExplainLevel explainLevel) { for (;;) { try { Boolean b = explainVisibilityHandler.isVisibleInExplain(rel, this, explainLevel); return b == null || b; } catch (MetadataHandlerProvider.NoHandler e) { explainVisibilityHandler = revise(BuiltInMetadata.ExplainVisibility.Handler.class); } } } /** * Returns the * {@link BuiltInMetadata.Distribution#distribution()} * statistic. * * @param rel the relational expression * * @return description of how the rows in the relational expression are * physically distributed */ public @Nullable RelDistribution getDistribution(RelNode rel) { for (;;) { try { return distributionHandler.distribution(rel, this); } catch (MetadataHandlerProvider.NoHandler e) { distributionHandler = revise(BuiltInMetadata.Distribution.Handler.class); } } } /** * Returns the lower bound cost of a RelNode. */ public @Nullable RelOptCost getLowerBoundCost(RelNode rel, VolcanoPlanner planner) { for (;;) { try { return lowerBoundCostHandler.getLowerBoundCost(rel, this, planner); } catch (MetadataHandlerProvider.NoHandler e) { lowerBoundCostHandler = revise(BuiltInMetadata.LowerBoundCost.Handler.class); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy