You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by ch...@apache.org on 2022/08/09 07:26:08 UTC
[calcite] branch main updated: [CALCITE-4223] Metadata handlers for TableScan should see whether the RelOptTable implements the handler
This is an automated email from the ASF dual-hosted git repository.
chunwei pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/main by this push:
new 7e0057e8de [CALCITE-4223] Metadata handlers for TableScan should see whether the RelOptTable implements the handler
7e0057e8de is described below
commit 7e0057e8de93930f1b2952a1cbcee8ad7a6bfb4b
Author: chunwei.lcw <ch...@gmail.com>
AuthorDate: Wed May 18 09:41:29 2022 +0800
[CALCITE-4223] Metadata handlers for TableScan should see whether the RelOptTable implements the handler
---
.../calcite/rel/metadata/RelMdCollation.java | 5 ++
.../calcite/rel/metadata/RelMdColumnOrigins.java | 11 +++
.../rel/metadata/RelMdColumnUniqueness.java | 9 ++-
.../rel/metadata/RelMdDistinctRowCount.java | 11 +++
.../calcite/rel/metadata/RelMdDistribution.java | 5 ++
.../rel/metadata/RelMdExplainVisibility.java | 12 ++++
.../rel/metadata/RelMdExpressionLineage.java | 6 ++
.../calcite/rel/metadata/RelMdMaxRowCount.java | 7 +-
.../calcite/rel/metadata/RelMdMinRowCount.java | 7 +-
.../calcite/rel/metadata/RelMdNodeTypes.java | 5 ++
.../calcite/rel/metadata/RelMdParallelism.java | 5 ++
.../rel/metadata/RelMdPercentageOriginalRows.java | 10 +++
.../calcite/rel/metadata/RelMdPopulationSize.java | 11 +++
.../calcite/rel/metadata/RelMdPredicates.java | 7 +-
.../apache/calcite/rel/metadata/RelMdRowCount.java | 7 +-
.../calcite/rel/metadata/RelMdSelectivity.java | 11 +++
.../org/apache/calcite/rel/metadata/RelMdSize.java | 7 +-
.../calcite/rel/metadata/RelMdTableReferences.java | 5 ++
.../calcite/rel/metadata/RelMdUniqueKeys.java | 6 ++
.../org/apache/calcite/test/RelMetadataTest.java | 78 ++++++++++++++++++++++
.../GeneratedMetadata_ColumnOriginHandler.java | 2 +
.../GeneratedMetadata_DistinctRowCountHandler.java | 2 +
...GeneratedMetadata_ExplainVisibilityHandler.java | 4 +-
...atedMetadata_PercentageOriginalRowsHandler.java | 2 +
.../GeneratedMetadata_PopulationSizeHandler.java | 2 +
.../GeneratedMetadata_SelectivityHandler.java | 2 +
.../calcite/test/catalog/MockCatalogReader.java | 2 +-
27 files changed, 232 insertions(+), 9 deletions(-)
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdCollation.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdCollation.java
index e32ad62c51..537099d9c9 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdCollation.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdCollation.java
@@ -149,6 +149,11 @@ public class RelMdCollation
public @Nullable ImmutableList<RelCollation> collations(TableScan scan,
RelMetadataQuery mq) {
+ final BuiltInMetadata.Collation.Handler handler =
+ scan.getTable().unwrap(BuiltInMetadata.Collation.Handler.class);
+ if (handler != null) {
+ return handler.collations(scan, mq);
+ }
return copyOf(table(scan.getTable()));
}
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdColumnOrigins.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdColumnOrigins.java
index 02bb8919fd..dc30e6a20a 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdColumnOrigins.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdColumnOrigins.java
@@ -30,6 +30,7 @@ import org.apache.calcite.rel.core.Snapshot;
import org.apache.calcite.rel.core.Sort;
import org.apache.calcite.rel.core.TableFunctionScan;
import org.apache.calcite.rel.core.TableModify;
+import org.apache.calcite.rel.core.TableScan;
import org.apache.calcite.rex.RexInputRef;
import org.apache.calcite.rex.RexLocalRef;
import org.apache.calcite.rex.RexNode;
@@ -164,6 +165,16 @@ public class RelMdColumnOrigins
return createDerivedColumnOrigins(set);
}
+ public @Nullable Set<RelColumnOrigin> getColumnOrigins(TableScan scan,
+ RelMetadataQuery mq, int iOutputColumn) {
+ final BuiltInMetadata.ColumnOrigin.Handler handler =
+ scan.getTable().unwrap(BuiltInMetadata.ColumnOrigin.Handler.class);
+ if (handler != null) {
+ return handler.getColumnOrigins(scan, mq, iOutputColumn);
+ }
+ return getColumnOrigins((RelNode) scan, mq, iOutputColumn);
+ }
+
public @Nullable Set<RelColumnOrigin> getColumnOrigins(Filter rel,
RelMetadataQuery mq, int iOutputColumn) {
return mq.getColumnOrigins(rel.getInput(), iOutputColumn);
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdColumnUniqueness.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdColumnUniqueness.java
index aef93c3a55..50217699c3 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdColumnUniqueness.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdColumnUniqueness.java
@@ -78,9 +78,14 @@ public class RelMdColumnUniqueness
return BuiltInMetadata.ColumnUniqueness.DEF;
}
- public Boolean areColumnsUnique(TableScan rel, RelMetadataQuery mq,
+ public Boolean areColumnsUnique(TableScan scan, RelMetadataQuery mq,
ImmutableBitSet columns, boolean ignoreNulls) {
- return rel.getTable().isKey(columns);
+ final BuiltInMetadata.ColumnUniqueness.Handler handler =
+ scan.getTable().unwrap(BuiltInMetadata.ColumnUniqueness.Handler.class);
+ if (handler != null) {
+ return handler.areColumnsUnique(scan, mq, columns, ignoreNulls);
+ }
+ return scan.getTable().isKey(columns);
}
public @Nullable Boolean areColumnsUnique(Filter rel, RelMetadataQuery mq,
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdDistinctRowCount.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdDistinctRowCount.java
index d172f37f35..b5609acf40 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdDistinctRowCount.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdDistinctRowCount.java
@@ -26,6 +26,7 @@ import org.apache.calcite.rel.core.Join;
import org.apache.calcite.rel.core.Project;
import org.apache.calcite.rel.core.Sort;
import org.apache.calcite.rel.core.TableModify;
+import org.apache.calcite.rel.core.TableScan;
import org.apache.calcite.rel.core.Union;
import org.apache.calcite.rel.core.Values;
import org.apache.calcite.rex.RexBuilder;
@@ -85,6 +86,16 @@ public class RelMdDistinctRowCount
return null;
}
+ public @Nullable Double getDistinctRowCount(TableScan scan, RelMetadataQuery mq,
+ ImmutableBitSet groupKey, RexNode predicate) {
+ final BuiltInMetadata.DistinctRowCount.Handler handler =
+ scan.getTable().unwrap(BuiltInMetadata.DistinctRowCount.Handler.class);
+ if (handler != null) {
+ return handler.getDistinctRowCount(scan, mq, groupKey, predicate);
+ }
+ return getDistinctRowCount((RelNode) scan, mq, groupKey, predicate);
+ }
+
public @Nullable Double getDistinctRowCount(Union rel, RelMetadataQuery mq,
ImmutableBitSet groupKey, @Nullable RexNode predicate) {
double rowCount = 0.0;
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdDistribution.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdDistribution.java
index 5133dbb939..a0fdf630d6 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdDistribution.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdDistribution.java
@@ -91,6 +91,11 @@ public class RelMdDistribution
}
public @Nullable RelDistribution distribution(TableScan scan, RelMetadataQuery mq) {
+ final BuiltInMetadata.Distribution.Handler handler =
+ scan.getTable().unwrap(BuiltInMetadata.Distribution.Handler.class);
+ if (handler != null) {
+ return handler.distribution(scan, mq);
+ }
return table(scan.getTable());
}
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdExplainVisibility.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdExplainVisibility.java
index 1f5d8f5887..a06b2842a1 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdExplainVisibility.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdExplainVisibility.java
@@ -17,6 +17,7 @@
package org.apache.calcite.rel.metadata;
import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.TableScan;
import org.apache.calcite.sql.SqlExplainLevel;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -52,4 +53,15 @@ public class RelMdExplainVisibility
// no information available
return null;
}
+
+ public @Nullable Boolean isVisibleInExplain(TableScan scan, RelMetadataQuery mq,
+ SqlExplainLevel explainLevel) {
+ final BuiltInMetadata.ExplainVisibility.Handler handler =
+ scan.getTable().unwrap(BuiltInMetadata.ExplainVisibility.Handler.class);
+ if (handler != null) {
+ return handler.isVisibleInExplain(scan, mq, explainLevel);
+ }
+ // Fall back to the catch-all.
+ return isVisibleInExplain((RelNode) scan, mq, explainLevel);
+ }
}
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdExpressionLineage.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdExpressionLineage.java
index e21fcb5f31..05fc3e0fe4 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdExpressionLineage.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdExpressionLineage.java
@@ -119,6 +119,12 @@ public class RelMdExpressionLineage
*/
public @Nullable Set<RexNode> getExpressionLineage(TableScan rel,
RelMetadataQuery mq, RexNode outputExpression) {
+ final BuiltInMetadata.ExpressionLineage.Handler handler =
+ rel.getTable().unwrap(BuiltInMetadata.ExpressionLineage.Handler.class);
+ if (handler != null) {
+ return handler.getExpressionLineage(rel, mq, outputExpression);
+ }
+
final RexBuilder rexBuilder = rel.getCluster().getRexBuilder();
// Extract input fields referenced by expression
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMaxRowCount.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMaxRowCount.java
index a3c4b18afe..c8cec39f98 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMaxRowCount.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMaxRowCount.java
@@ -181,7 +181,12 @@ public class RelMdMaxRowCount
return left * right;
}
- public Double getMaxRowCount(TableScan rel, RelMetadataQuery mq) {
+ public @Nullable Double getMaxRowCount(TableScan rel, RelMetadataQuery mq) {
+ final BuiltInMetadata.MaxRowCount.Handler handler =
+ rel.getTable().unwrap(BuiltInMetadata.MaxRowCount.Handler.class);
+ if (handler != null) {
+ return handler.getMaxRowCount(rel, mq);
+ }
// For typical tables, there is no upper bound to the number of rows.
return Double.POSITIVE_INFINITY;
}
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMinRowCount.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMinRowCount.java
index 131fec5de2..1d392aad13 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMinRowCount.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMinRowCount.java
@@ -147,7 +147,12 @@ public class RelMdMinRowCount
return 0D;
}
- public Double getMinRowCount(TableScan rel, RelMetadataQuery mq) {
+ public @Nullable Double getMinRowCount(TableScan rel, RelMetadataQuery mq) {
+ final BuiltInMetadata.MinRowCount.Handler handler =
+ rel.getTable().unwrap(BuiltInMetadata.MinRowCount.Handler.class);
+ if (handler != null) {
+ return handler.getMinRowCount(rel, mq);
+ }
return 0D;
}
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdNodeTypes.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdNodeTypes.java
index a7d160fcf8..60aa05f9f2 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdNodeTypes.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdNodeTypes.java
@@ -125,6 +125,11 @@ public class RelMdNodeTypes
public @Nullable Multimap<Class<? extends RelNode>, RelNode> getNodeTypes(TableScan rel,
RelMetadataQuery mq) {
+ final BuiltInMetadata.NodeTypes.Handler handler =
+ rel.getTable().unwrap(BuiltInMetadata.NodeTypes.Handler.class);
+ if (handler != null) {
+ return handler.getNodeTypes(rel, mq);
+ }
return getNodeTypes(rel, TableScan.class, mq);
}
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdParallelism.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdParallelism.java
index 2bd1747049..ef08fff91b 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdParallelism.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdParallelism.java
@@ -58,6 +58,11 @@ public class RelMdParallelism
}
public Boolean isPhaseTransition(TableScan rel, RelMetadataQuery mq) {
+ final BuiltInMetadata.Parallelism.Handler handler =
+ rel.getTable().unwrap(BuiltInMetadata.Parallelism.Handler.class);
+ if (handler != null) {
+ return handler.isPhaseTransition(rel, mq);
+ }
return true;
}
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPercentageOriginalRows.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPercentageOriginalRows.java
index a25d2eebf2..e69cd5646d 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPercentageOriginalRows.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPercentageOriginalRows.java
@@ -21,6 +21,7 @@ import org.apache.calcite.plan.RelOptCost;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.Aggregate;
import org.apache.calcite.rel.core.Join;
+import org.apache.calcite.rel.core.TableScan;
import org.apache.calcite.rel.core.Union;
import com.google.common.collect.ImmutableList;
@@ -55,6 +56,15 @@ public class RelMdPercentageOriginalRows {
private RelMdPercentageOriginalRows() {}
+ public @Nullable Double getPercentageOriginalRows(TableScan scan, RelMetadataQuery mq) {
+ final BuiltInMetadata.PercentageOriginalRows.Handler handler =
+ scan.getTable().unwrap(BuiltInMetadata.PercentageOriginalRows.Handler.class);
+ if (handler != null) {
+ return handler.getPercentageOriginalRows(scan, mq);
+ }
+ // Fall back to the catch-all.
+ return getPercentageOriginalRows((RelNode) scan, mq);
+ }
public @Nullable Double getPercentageOriginalRows(Aggregate rel, RelMetadataQuery mq) {
// REVIEW jvs 28-Mar-2006: The assumption here seems to be that
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPopulationSize.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPopulationSize.java
index 779457fb59..963c3bac5f 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPopulationSize.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPopulationSize.java
@@ -24,6 +24,7 @@ import org.apache.calcite.rel.core.Join;
import org.apache.calcite.rel.core.Project;
import org.apache.calcite.rel.core.Sort;
import org.apache.calcite.rel.core.TableModify;
+import org.apache.calcite.rel.core.TableScan;
import org.apache.calcite.rel.core.Union;
import org.apache.calcite.rel.core.Values;
import org.apache.calcite.rex.RexNode;
@@ -54,6 +55,16 @@ public class RelMdPopulationSize
return BuiltInMetadata.PopulationSize.DEF;
}
+ public @Nullable Double getPopulationSize(TableScan scan, RelMetadataQuery mq,
+ ImmutableBitSet groupKey) {
+ final BuiltInMetadata.PopulationSize.Handler handler =
+ scan.getTable().unwrap(BuiltInMetadata.PopulationSize.Handler.class);
+ if (handler != null) {
+ return handler.getPopulationSize(scan, mq, groupKey);
+ }
+ return getPopulationSize((RelNode) scan, mq, groupKey);
+ }
+
public @Nullable Double getPopulationSize(Filter rel, RelMetadataQuery mq,
ImmutableBitSet groupKey) {
return mq.getPopulationSize(rel.getInput(), groupKey);
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java
index e194c82703..da71912046 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java
@@ -149,8 +149,13 @@ public class RelMdPredicates
/**
* Infers predicates for a table scan.
*/
- public RelOptPredicateList getPredicates(TableScan table,
+ public RelOptPredicateList getPredicates(TableScan scan,
RelMetadataQuery mq) {
+ final BuiltInMetadata.Predicates.Handler handler =
+ scan.getTable().unwrap(BuiltInMetadata.Predicates.Handler.class);
+ if (handler != null) {
+ return handler.getPredicates(scan, mq);
+ }
return RelOptPredicateList.EMPTY;
}
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdRowCount.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdRowCount.java
index 5eb8178826..2066c867fe 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdRowCount.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdRowCount.java
@@ -197,7 +197,12 @@ public class RelMdRowCount
return distinctRowCount;
}
- public Double getRowCount(TableScan rel, RelMetadataQuery mq) {
+ public @Nullable Double getRowCount(TableScan rel, RelMetadataQuery mq) {
+ final BuiltInMetadata.RowCount.Handler handler =
+ rel.getTable().unwrap(BuiltInMetadata.RowCount.Handler.class);
+ if (handler != null) {
+ return handler.getRowCount(rel, mq);
+ }
return rel.estimateRowCount(mq);
}
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdSelectivity.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdSelectivity.java
index f61b26cf88..709b8d11c7 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdSelectivity.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdSelectivity.java
@@ -25,6 +25,7 @@ import org.apache.calcite.rel.core.Join;
import org.apache.calcite.rel.core.Project;
import org.apache.calcite.rel.core.Sort;
import org.apache.calcite.rel.core.TableModify;
+import org.apache.calcite.rel.core.TableScan;
import org.apache.calcite.rel.core.Union;
import org.apache.calcite.rex.RexBuilder;
import org.apache.calcite.rex.RexLocalRef;
@@ -60,6 +61,16 @@ public class RelMdSelectivity
return BuiltInMetadata.Selectivity.DEF;
}
+ public @Nullable Double getSelectivity(TableScan scan, RelMetadataQuery mq,
+ RexNode predicate) {
+ final BuiltInMetadata.Selectivity.Handler handler =
+ scan.getTable().unwrap(BuiltInMetadata.Selectivity.Handler.class);
+ if (handler != null) {
+ return handler.getSelectivity(scan, mq, predicate);
+ }
+ return getSelectivity((RelNode) scan, mq, predicate);
+ }
+
public @Nullable Double getSelectivity(Union rel, RelMetadataQuery mq,
@Nullable RexNode predicate) {
if ((rel.getInputs().size() == 0) || (predicate == null)) {
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdSize.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdSize.java
index 77b2ed6fd7..ca91d51478 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdSize.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdSize.java
@@ -171,7 +171,12 @@ public class RelMdSize implements MetadataHandler<BuiltInMetadata.Size> {
return list.build();
}
- public List<@Nullable Double> averageColumnSizes(TableScan rel, RelMetadataQuery mq) {
+ public @Nullable List<@Nullable Double> averageColumnSizes(TableScan rel, RelMetadataQuery mq) {
+ final BuiltInMetadata.Size.Handler handler =
+ rel.getTable().unwrap(BuiltInMetadata.Size.Handler.class);
+ if (handler != null) {
+ return handler.averageColumnSizes(rel, mq);
+ }
final List<RelDataTypeField> fields = rel.getRowType().getFieldList();
final ImmutableNullableList.Builder<@Nullable Double> list = ImmutableNullableList.builder();
for (RelDataTypeField field : fields) {
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdTableReferences.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdTableReferences.java
index e9554a6946..4c78ab1b6c 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdTableReferences.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdTableReferences.java
@@ -92,6 +92,11 @@ public class RelMdTableReferences
* TableScan table reference.
*/
public Set<RelTableRef> getTableReferences(TableScan rel, RelMetadataQuery mq) {
+ final BuiltInMetadata.TableReferences.Handler handler =
+ rel.getTable().unwrap(BuiltInMetadata.TableReferences.Handler.class);
+ if (handler != null) {
+ return handler.getTableReferences(rel, mq);
+ }
return ImmutableSet.of(RelTableRef.of(rel.getTable(), 0));
}
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdUniqueKeys.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdUniqueKeys.java
index 21bfdbed29..13374cc208 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdUniqueKeys.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdUniqueKeys.java
@@ -322,6 +322,12 @@ public class RelMdUniqueKeys
public @Nullable Set<ImmutableBitSet> getUniqueKeys(TableScan rel, RelMetadataQuery mq,
boolean ignoreNulls) {
+ final BuiltInMetadata.UniqueKeys.Handler handler =
+ rel.getTable().unwrap(BuiltInMetadata.UniqueKeys.Handler.class);
+ if (handler != null) {
+ return handler.getUniqueKeys(rel, mq, ignoreNulls);
+ }
+
final List<ImmutableBitSet> keys = rel.getTable().getKeys();
if (keys == null) {
return null;
diff --git a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
index d7ec865c70..ee73bcab6b 100644
--- a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
@@ -3261,6 +3261,44 @@ public class RelMetadataTest {
});
}
+ /** Unit test for
+ * {@link org.apache.calcite.rel.metadata.RelMetadataQuery#getAverageColumnSizes(org.apache.calcite.rel.RelNode)}
+ * with a table that has its own implementation of {@link BuiltInMetadata.Size}. */
+ @Test void testCustomizedAverageColumnSizes() {
+ SqlTestFactory.CatalogReaderFactory factory = (typeFactory, caseSensitive) -> {
+ CompositeKeysCatalogReader catalogReader =
+ new CompositeKeysCatalogReader(typeFactory, false);
+ catalogReader.init();
+ return catalogReader;
+ };
+
+ final RelNode rel = sql("select key1, key2 from s.composite_keys_table")
+ .withCatalogReaderFactory(factory).toRel();
+ final RelMetadataQuery mq = rel.getCluster().getMetadataQuery();
+ List<Double> columnSizes = mq.getAverageColumnSizes(rel);
+ assertThat(columnSizes.size(), is(2));
+ assertThat(columnSizes.get(0), is(2.0));
+ assertThat(columnSizes.get(1), is(3.0));
+ }
+
+ /** Unit test for
+ * {@link org.apache.calcite.rel.metadata.RelMetadataQuery#getDistinctRowCount(RelNode, ImmutableBitSet, RexNode)}
+ * with a table that has its own implementation of {@link BuiltInMetadata.Size}. */
+ @Test void testCustomizedDistinctRowcount() {
+ SqlTestFactory.CatalogReaderFactory factory = (typeFactory, caseSensitive) -> {
+ CompositeKeysCatalogReader catalogReader =
+ new CompositeKeysCatalogReader(typeFactory, false);
+ catalogReader.init();
+ return catalogReader;
+ };
+
+ final RelNode rel = sql("select key1, key2 from s.composite_keys_table")
+ .withCatalogReaderFactory(factory).toRel();
+ final RelMetadataQuery mq = rel.getCluster().getMetadataQuery();
+ Double ndv = mq.getDistinctRowCount(rel, ImmutableBitSet.of(0, 1), null);
+ assertThat(ndv, is(100.0));
+ }
+
private void checkInputForCollationAndLimit(RelOptCluster cluster, RelOptTable empTable,
RelOptTable deptTable) {
final RexBuilder rexBuilder = cluster.getRexBuilder();
@@ -3404,8 +3442,48 @@ public class RelMetadataTest {
t1.addColumn("key1", typeFactory.createSqlType(SqlTypeName.VARCHAR), true);
t1.addColumn("key2", typeFactory.createSqlType(SqlTypeName.VARCHAR), true);
t1.addColumn("value1", typeFactory.createSqlType(SqlTypeName.INTEGER));
+ addSizeHandler(t1);
+ addDistinctRowcountHandler(t1);
+ addUniqueKeyHandler(t1);
registerTable(t1);
return this;
}
+
+ private void addSizeHandler(MockTable table) {
+ table.addWrap(
+ new BuiltInMetadata.Size.Handler() {
+ @Override public @Nullable Double averageRowSize(RelNode r, RelMetadataQuery mq) {
+ return null;
+ }
+
+ @Override public @Nullable List<@Nullable Double> averageColumnSizes(RelNode r,
+ RelMetadataQuery mq) {
+ List<Double> colSize = new ArrayList<>();
+ colSize.add(2D);
+ colSize.add(3D);
+ return colSize;
+ }
+ });
+ }
+
+ private void addDistinctRowcountHandler(MockTable table) {
+ table.addWrap(
+ new BuiltInMetadata.DistinctRowCount.Handler() {
+ @Override public @Nullable Double getDistinctRowCount(RelNode r, RelMetadataQuery mq,
+ ImmutableBitSet groupKey, @Nullable RexNode predicate) {
+ return 100D;
+ }
+ });
+ }
+
+ private void addUniqueKeyHandler(MockTable table) {
+ table.addWrap(
+ new BuiltInMetadata.UniqueKeys.Handler() {
+ @Override public @Nullable Set<ImmutableBitSet> getUniqueKeys(RelNode r,
+ RelMetadataQuery mq, boolean ignoreNulls) {
+ return ImmutableSet.of(ImmutableBitSet.of(0, 1));
+ }
+ });
+ }
}
}
diff --git a/core/src/test/resources/org/apache/calcite/rel/metadata/janino/GeneratedMetadata_ColumnOriginHandler.java b/core/src/test/resources/org/apache/calcite/rel/metadata/janino/GeneratedMetadata_ColumnOriginHandler.java
index d689d4a115..6063a0e006 100644
--- a/core/src/test/resources/org/apache/calcite/rel/metadata/janino/GeneratedMetadata_ColumnOriginHandler.java
+++ b/core/src/test/resources/org/apache/calcite/rel/metadata/janino/GeneratedMetadata_ColumnOriginHandler.java
@@ -90,6 +90,8 @@ public final class GeneratedMetadata_ColumnOriginHandler
return provider0.getColumnOrigins((org.apache.calcite.rel.core.TableFunctionScan) r, mq, a2);
} else if (r instanceof org.apache.calcite.rel.core.TableModify) {
return provider0.getColumnOrigins((org.apache.calcite.rel.core.TableModify) r, mq, a2);
+ } else if (r instanceof org.apache.calcite.rel.core.TableScan) {
+ return provider0.getColumnOrigins((org.apache.calcite.rel.core.TableScan) r, mq, a2);
} else if (r instanceof org.apache.calcite.rel.RelNode) {
return provider0.getColumnOrigins((org.apache.calcite.rel.RelNode) r, mq, a2);
} else {
diff --git a/core/src/test/resources/org/apache/calcite/rel/metadata/janino/GeneratedMetadata_DistinctRowCountHandler.java b/core/src/test/resources/org/apache/calcite/rel/metadata/janino/GeneratedMetadata_DistinctRowCountHandler.java
index 52bd502e3e..52ad30b842 100644
--- a/core/src/test/resources/org/apache/calcite/rel/metadata/janino/GeneratedMetadata_DistinctRowCountHandler.java
+++ b/core/src/test/resources/org/apache/calcite/rel/metadata/janino/GeneratedMetadata_DistinctRowCountHandler.java
@@ -80,6 +80,8 @@ public final class GeneratedMetadata_DistinctRowCountHandler
return provider0.getDistinctRowCount((org.apache.calcite.rel.core.Sort) r, mq, a2, a3);
} else if (r instanceof org.apache.calcite.rel.core.TableModify) {
return provider0.getDistinctRowCount((org.apache.calcite.rel.core.TableModify) r, mq, a2, a3);
+ } else if (r instanceof org.apache.calcite.rel.core.TableScan) {
+ return provider0.getDistinctRowCount((org.apache.calcite.rel.core.TableScan) r, mq, a2, a3);
} else if (r instanceof org.apache.calcite.rel.core.Union) {
return provider0.getDistinctRowCount((org.apache.calcite.rel.core.Union) r, mq, a2, a3);
} else if (r instanceof org.apache.calcite.rel.core.Values) {
diff --git a/core/src/test/resources/org/apache/calcite/rel/metadata/janino/GeneratedMetadata_ExplainVisibilityHandler.java b/core/src/test/resources/org/apache/calcite/rel/metadata/janino/GeneratedMetadata_ExplainVisibilityHandler.java
index 62d898c2f3..fb3ec846fb 100644
--- a/core/src/test/resources/org/apache/calcite/rel/metadata/janino/GeneratedMetadata_ExplainVisibilityHandler.java
+++ b/core/src/test/resources/org/apache/calcite/rel/metadata/janino/GeneratedMetadata_ExplainVisibilityHandler.java
@@ -68,7 +68,9 @@ public final class GeneratedMetadata_ExplainVisibilityHandler
org.apache.calcite.rel.RelNode r,
org.apache.calcite.rel.metadata.RelMetadataQuery mq,
org.apache.calcite.sql.SqlExplainLevel a2) {
- if (r instanceof org.apache.calcite.rel.RelNode) {
+ if (r instanceof org.apache.calcite.rel.core.TableScan) {
+ return provider0.isVisibleInExplain((org.apache.calcite.rel.core.TableScan) r, mq, a2);
+ } else if (r instanceof org.apache.calcite.rel.RelNode) {
return provider0.isVisibleInExplain((org.apache.calcite.rel.RelNode) r, mq, a2);
} else {
throw new java.lang.IllegalArgumentException("No handler for method [public abstract java.lang.Boolean org.apache.calcite.rel.metadata.BuiltInMetadata$ExplainVisibility$Handler.isVisibleInExplain(org.apache.calcite.rel.RelNode,org.apache.calcite.rel.metadata.RelMetadataQuery,org.apache.calcite.sql.SqlExplainLevel)] applied to argument of type [" + r.getClass() + "]; we recommend you create a catch-all (RelNode) handler");
diff --git a/core/src/test/resources/org/apache/calcite/rel/metadata/janino/GeneratedMetadata_PercentageOriginalRowsHandler.java b/core/src/test/resources/org/apache/calcite/rel/metadata/janino/GeneratedMetadata_PercentageOriginalRowsHandler.java
index 573ceb39e7..d83e952a92 100644
--- a/core/src/test/resources/org/apache/calcite/rel/metadata/janino/GeneratedMetadata_PercentageOriginalRowsHandler.java
+++ b/core/src/test/resources/org/apache/calcite/rel/metadata/janino/GeneratedMetadata_PercentageOriginalRowsHandler.java
@@ -64,6 +64,8 @@ public final class GeneratedMetadata_PercentageOriginalRowsHandler
return provider0.getPercentageOriginalRows((org.apache.calcite.rel.core.Aggregate) r, mq);
} else if (r instanceof org.apache.calcite.rel.core.Join) {
return provider0.getPercentageOriginalRows((org.apache.calcite.rel.core.Join) r, mq);
+ } else if (r instanceof org.apache.calcite.rel.core.TableScan) {
+ return provider0.getPercentageOriginalRows((org.apache.calcite.rel.core.TableScan) r, mq);
} else if (r instanceof org.apache.calcite.rel.core.Union) {
return provider0.getPercentageOriginalRows((org.apache.calcite.rel.core.Union) r, mq);
} else if (r instanceof org.apache.calcite.rel.RelNode) {
diff --git a/core/src/test/resources/org/apache/calcite/rel/metadata/janino/GeneratedMetadata_PopulationSizeHandler.java b/core/src/test/resources/org/apache/calcite/rel/metadata/janino/GeneratedMetadata_PopulationSizeHandler.java
index 944a4eb7f3..188fd5aa4d 100644
--- a/core/src/test/resources/org/apache/calcite/rel/metadata/janino/GeneratedMetadata_PopulationSizeHandler.java
+++ b/core/src/test/resources/org/apache/calcite/rel/metadata/janino/GeneratedMetadata_PopulationSizeHandler.java
@@ -76,6 +76,8 @@ public final class GeneratedMetadata_PopulationSizeHandler
return provider0.getPopulationSize((org.apache.calcite.rel.core.Sort) r, mq, a2);
} else if (r instanceof org.apache.calcite.rel.core.TableModify) {
return provider0.getPopulationSize((org.apache.calcite.rel.core.TableModify) r, mq, a2);
+ } else if (r instanceof org.apache.calcite.rel.core.TableScan) {
+ return provider0.getPopulationSize((org.apache.calcite.rel.core.TableScan) r, mq, a2);
} else if (r instanceof org.apache.calcite.rel.core.Union) {
return provider0.getPopulationSize((org.apache.calcite.rel.core.Union) r, mq, a2);
} else if (r instanceof org.apache.calcite.rel.core.Values) {
diff --git a/core/src/test/resources/org/apache/calcite/rel/metadata/janino/GeneratedMetadata_SelectivityHandler.java b/core/src/test/resources/org/apache/calcite/rel/metadata/janino/GeneratedMetadata_SelectivityHandler.java
index 4eed8d7071..7010ada5d3 100644
--- a/core/src/test/resources/org/apache/calcite/rel/metadata/janino/GeneratedMetadata_SelectivityHandler.java
+++ b/core/src/test/resources/org/apache/calcite/rel/metadata/janino/GeneratedMetadata_SelectivityHandler.java
@@ -76,6 +76,8 @@ public final class GeneratedMetadata_SelectivityHandler
return provider0.getSelectivity((org.apache.calcite.rel.core.Sort) r, mq, a2);
} else if (r instanceof org.apache.calcite.rel.core.TableModify) {
return provider0.getSelectivity((org.apache.calcite.rel.core.TableModify) r, mq, a2);
+ } else if (r instanceof org.apache.calcite.rel.core.TableScan) {
+ return provider0.getSelectivity((org.apache.calcite.rel.core.TableScan) r, mq, a2);
} else if (r instanceof org.apache.calcite.rel.core.Union) {
return provider0.getSelectivity((org.apache.calcite.rel.core.Union) r, mq, a2);
} else if (r instanceof org.apache.calcite.rel.RelNode) {
diff --git a/testkit/src/main/java/org/apache/calcite/test/catalog/MockCatalogReader.java b/testkit/src/main/java/org/apache/calcite/test/catalog/MockCatalogReader.java
index edffe58ec8..8cc3539697 100644
--- a/testkit/src/main/java/org/apache/calcite/test/catalog/MockCatalogReader.java
+++ b/testkit/src/main/java/org/apache/calcite/test/catalog/MockCatalogReader.java
@@ -366,7 +366,7 @@ public abstract class MockCatalogReader extends CalciteCatalogReader {
this.wraps = ImmutableList.of();
}
- void addWrap(Object wrap) {
+ public void addWrap(Object wrap) {
if (wraps instanceof ImmutableList) {
wraps = new ArrayList<>(wraps);
}