[CALCITE-4544] Deprecate Metadata API backed by Java Reflection (James Starr)
Deprecating:
* RelOptPlanner.registerMetadataProviders - Used to support custom nodes
in reflection based rel metadata. The generated code based rel
metadata has tight couple so this is not needed.
* RelOptPlanner.getRelMetadataTimestamp - Used for cache invalidation in
reflection based rel metadata. The generated code based rel
metadata has tight couple so this is not needed.
* RelOptCluster.metadataFactory - Exposing an api for reflection based
rel metadata.
* RelNode.metadata - An api for accessing reflection based rel metadata.
* CachingRelMetadataProvider - Implements caching for reflection based
rel metadata. Generated code base rel metadata use a Table in
RelMetadataQuery and tight coupling for caching.
* RelMetadataProvider.apply - The primary entry point reflection based
rel metadata.
* MetadataFactory - An api for reflection based rel metadata.
* MockRelOptPlanner.setRelMetadataTimestamp - Used in testing reflection
based rel metadata.
* ReflectiveRelMetadataProvider.{map, metadataClass0 - Used in the
implementation reflection based rel metadata.
* VolcanoRelMetadataProvider - Supports custom volcanno rels in
reflection based rel metadata.
* HepRelMetadataProvider - Supports custom hep rels in reflection based
rel metadata.
Close apache/calcite#2475
diff --git a/core/src/main/java/org/apache/calcite/plan/AbstractRelOptPlanner.java b/core/src/main/java/org/apache/calcite/plan/AbstractRelOptPlanner.java
index 34a5bce..749538f 100644
--- a/core/src/main/java/org/apache/calcite/plan/AbstractRelOptPlanner.java
+++ b/core/src/main/java/org/apache/calcite/plan/AbstractRelOptPlanner.java
@@ -222,6 +222,7 @@
@Override public void registerSchema(RelOptSchema schema) {
}
+ @Deprecated // to be removed before 2.0
@Override public long getRelMetadataTimestamp(RelNode rel) {
return 0;
}
@@ -253,7 +254,7 @@
return mq.getCumulativeCost(rel);
}
- @SuppressWarnings("deprecation")
+ @Deprecated // to be removed before 2.0
@Override public @Nullable RelOptCost getCost(RelNode rel) {
final RelMetadataQuery mq = rel.getCluster().getMetadataQuery();
return getCost(rel, mq);
@@ -268,6 +269,7 @@
listener.addListener(newListener);
}
+ @Deprecated // to be removed before 2.0
@Override public void registerMetadataProviders(List<RelMetadataProvider> list) {
}
diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptCluster.java b/core/src/main/java/org/apache/calcite/plan/RelOptCluster.java
index 8231c11..eaec60a 100644
--- a/core/src/main/java/org/apache/calcite/plan/RelOptCluster.java
+++ b/core/src/main/java/org/apache/calcite/plan/RelOptCluster.java
@@ -22,7 +22,6 @@
import org.apache.calcite.rel.metadata.DefaultRelMetadataProvider;
import org.apache.calcite.rel.metadata.JaninoRelMetadataProvider;
import org.apache.calcite.rel.metadata.MetadataFactory;
-import org.apache.calcite.rel.metadata.MetadataFactoryImpl;
import org.apache.calcite.rel.metadata.RelMetadataProvider;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.calcite.rel.metadata.RelMetadataQueryBase;
@@ -56,6 +55,7 @@
private RexNode originalExpression;
private final RexBuilder rexBuilder;
private RelMetadataProvider metadataProvider;
+ @Deprecated // to be removed before 2.0
private MetadataFactory metadataFactory;
private @Nullable HintStrategyTable hintStrategies;
private final RelTraitSet emptyTraitSet;
@@ -146,11 +146,13 @@
* @param metadataProvider custom provider
*/
@EnsuresNonNull({"this.metadataProvider", "this.metadataFactory"})
+ @SuppressWarnings("deprecation")
public void setMetadataProvider(
@UnknownInitialization RelOptCluster this,
RelMetadataProvider metadataProvider) {
this.metadataProvider = metadataProvider;
- this.metadataFactory = new MetadataFactoryImpl(metadataProvider);
+ this.metadataFactory =
+ new org.apache.calcite.rel.metadata.MetadataFactoryImpl(metadataProvider);
// Wrap the metadata provider as a JaninoRelMetadataProvider
// and set it to the ThreadLocal,
// JaninoRelMetadataProvider is required by the RelMetadataQuery.
@@ -158,6 +160,12 @@
.set(JaninoRelMetadataProvider.of(metadataProvider));
}
+ /**
+ * Returns a {@link MetadataFactory}.
+ *
+ * @deprecated Use {@link #getMetadataQuery()}.
+ */
+ @Deprecated // to be removed before 2.0
public MetadataFactory getMetadataFactory() {
return metadataFactory;
}
diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptPlanner.java b/core/src/main/java/org/apache/calcite/plan/RelOptPlanner.java
index b3ec59e..1ef7933 100644
--- a/core/src/main/java/org/apache/calcite/plan/RelOptPlanner.java
+++ b/core/src/main/java/org/apache/calcite/plan/RelOptPlanner.java
@@ -284,6 +284,7 @@
*
* @param list receives planner's custom providers, if any
*/
+ @Deprecated // to be removed before 2.0
void registerMetadataProviders(List<RelMetadataProvider> list);
/**
@@ -294,6 +295,7 @@
* @param rel rel of interest
* @return timestamp of last change which might affect metadata derivation
*/
+ @Deprecated // to be removed before 2.0
long getRelMetadataTimestamp(RelNode rel);
/**
diff --git a/core/src/main/java/org/apache/calcite/plan/hep/HepPlanner.java b/core/src/main/java/org/apache/calcite/plan/hep/HepPlanner.java
index 8af32d9..601aef4 100644
--- a/core/src/main/java/org/apache/calcite/plan/hep/HepPlanner.java
+++ b/core/src/main/java/org/apache/calcite/plan/hep/HepPlanner.java
@@ -1060,11 +1060,13 @@
}
// implement RelOptPlanner
+ @Deprecated // to be removed before 2.0
@Override public void registerMetadataProviders(List<RelMetadataProvider> list) {
list.add(0, new HepRelMetadataProvider());
}
// implement RelOptPlanner
+ @Deprecated // to be removed before 2.0
@Override public long getRelMetadataTimestamp(RelNode rel) {
// TODO jvs 20-Apr-2006: This is overly conservative. Better would be
// to keep a timestamp per HepRelVertex, and update only affected
diff --git a/core/src/main/java/org/apache/calcite/plan/hep/HepRelMetadataProvider.java b/core/src/main/java/org/apache/calcite/plan/hep/HepRelMetadataProvider.java
index 825b420..7b71053 100644
--- a/core/src/main/java/org/apache/calcite/plan/hep/HepRelMetadataProvider.java
+++ b/core/src/main/java/org/apache/calcite/plan/hep/HepRelMetadataProvider.java
@@ -36,6 +36,7 @@
* HepRelMetadataProvider implements the {@link RelMetadataProvider} interface
* by combining metadata from the rels inside of a {@link HepRelVertex}.
*/
+@Deprecated // to be removed before 2.0
class HepRelMetadataProvider implements RelMetadataProvider {
//~ Methods ----------------------------------------------------------------
@@ -47,6 +48,7 @@
return 107;
}
+ @Deprecated // to be removed before 2.0
@Override public <@Nullable M extends @Nullable Metadata> UnboundMetadata<M> apply(
Class<? extends RelNode> relClass,
final Class<? extends M> metadataClass) {
diff --git a/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoPlanner.java b/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoPlanner.java
index 3648cd0..c09ada9 100644
--- a/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoPlanner.java
+++ b/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoPlanner.java
@@ -1443,11 +1443,13 @@
}
// implement RelOptPlanner
+ @Deprecated // to be removed before 2.0
@Override public void registerMetadataProviders(List<RelMetadataProvider> list) {
list.add(0, new VolcanoRelMetadataProvider());
}
// implement RelOptPlanner
+ @Deprecated // to be removed before 2.0
@Override public long getRelMetadataTimestamp(RelNode rel) {
RelSubset subset = getSubset(rel);
if (subset == null) {
diff --git a/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoRelMetadataProvider.java b/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoRelMetadataProvider.java
index 3a6ae00..a99a6dc 100644
--- a/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoRelMetadataProvider.java
+++ b/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoRelMetadataProvider.java
@@ -35,6 +35,7 @@
* VolcanoRelMetadataProvider implements the {@link RelMetadataProvider}
* interface by combining metadata from the rels making up an equivalence class.
*/
+@Deprecated // to be removed before 2.0
public class VolcanoRelMetadataProvider implements RelMetadataProvider {
//~ Methods ----------------------------------------------------------------
@@ -46,6 +47,7 @@
return 103;
}
+ @Deprecated // to be removed before 2.0
@Override public <@Nullable M extends @Nullable Metadata> @Nullable UnboundMetadata<M> apply(
Class<? extends RelNode> relClass,
final Class<? extends M> metadataClass) {
diff --git a/core/src/main/java/org/apache/calcite/prepare/PlannerImpl.java b/core/src/main/java/org/apache/calcite/prepare/PlannerImpl.java
index fddafd0..4140b0b 100644
--- a/core/src/main/java/org/apache/calcite/prepare/PlannerImpl.java
+++ b/core/src/main/java/org/apache/calcite/prepare/PlannerImpl.java
@@ -362,6 +362,7 @@
return requireNonNull(typeFactory, "typeFactory");
}
+ @SuppressWarnings("deprecation")
@Override public RelNode transform(int ruleSetIndex, RelTraitSet requiredOutputTraits,
RelNode rel) {
ensure(State.STATE_5_CONVERTED);
diff --git a/core/src/main/java/org/apache/calcite/rel/AbstractRelNode.java b/core/src/main/java/org/apache/calcite/rel/AbstractRelNode.java
index c72562f..f7902cf 100644
--- a/core/src/main/java/org/apache/calcite/rel/AbstractRelNode.java
+++ b/core/src/main/java/org/apache/calcite/rel/AbstractRelNode.java
@@ -233,6 +233,7 @@
return planner.getCostFactory().makeCost(rowCount, rowCount, 0);
}
+ @Deprecated // to be removed before 2.0
@Override public final <@Nullable M extends @Nullable Metadata> M metadata(Class<M> metadataClass,
RelMetadataQuery mq) {
final MetadataFactory factory = cluster.getMetadataFactory();
diff --git a/core/src/main/java/org/apache/calcite/rel/RelNode.java b/core/src/main/java/org/apache/calcite/rel/RelNode.java
index 50a43fd..21f6586 100644
--- a/core/src/main/java/org/apache/calcite/rel/RelNode.java
+++ b/core/src/main/java/org/apache/calcite/rel/RelNode.java
@@ -205,6 +205,8 @@
/**
* Returns a metadata interface.
*
+ * @deprecated Use {@link RelMetadataQuery} via {@link #getCluster()}.
+ *
* @param <M> Type of metadata being requested
* @param metadataClass Metadata interface
* @param mq Metadata query
@@ -213,6 +215,7 @@
* although if the information is not present the metadata object may
* return null from all methods)
*/
+ @Deprecated // to be removed before 2.0
<@Nullable M extends @Nullable Metadata> M metadata(Class<M> metadataClass, RelMetadataQuery mq);
/**
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/CachingRelMetadataProvider.java b/core/src/main/java/org/apache/calcite/rel/metadata/CachingRelMetadataProvider.java
index 8391833..0c7349f 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/CachingRelMetadataProvider.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/CachingRelMetadataProvider.java
@@ -40,6 +40,7 @@
* Implementation of the {@link RelMetadataProvider}
* interface that caches results from an underlying provider.
*/
+@Deprecated // to be removed before 2.0
public class CachingRelMetadataProvider implements RelMetadataProvider {
//~ Instance fields --------------------------------------------------------
@@ -59,7 +60,7 @@
}
//~ Methods ----------------------------------------------------------------
-
+ @Deprecated // to be removed before 2.0
@Override public <@Nullable M extends @Nullable Metadata> @Nullable UnboundMetadata<M> apply(
Class<? extends RelNode> relClass,
final Class<? extends M> metadataClass) {
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/ChainedRelMetadataProvider.java b/core/src/main/java/org/apache/calcite/rel/metadata/ChainedRelMetadataProvider.java
index ce90695..a0c4520 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/ChainedRelMetadataProvider.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/ChainedRelMetadataProvider.java
@@ -70,6 +70,7 @@
return providers.hashCode();
}
+ @Deprecated // to be removed before 2.0
@Override public <@Nullable M extends @Nullable Metadata> @Nullable UnboundMetadata<M> apply(
Class<? extends RelNode> relClass,
final Class<? extends M> metadataClass) {
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/JaninoRelMetadataProvider.java b/core/src/main/java/org/apache/calcite/rel/metadata/JaninoRelMetadataProvider.java
index 76106c9..9c939b5 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/JaninoRelMetadataProvider.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/JaninoRelMetadataProvider.java
@@ -182,6 +182,7 @@
return 109 + provider.hashCode();
}
+ @Deprecated // to be removed before 2.0
@Override public <@Nullable M extends @Nullable Metadata> UnboundMetadata<M> apply(
Class<? extends RelNode> relClass, Class<? extends M> metadataClass) {
throw new UnsupportedOperationException();
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/MetadataFactoryImpl.java b/core/src/main/java/org/apache/calcite/rel/metadata/MetadataFactoryImpl.java
index 59e910d..c78d34a 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/MetadataFactoryImpl.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/MetadataFactoryImpl.java
@@ -36,7 +36,10 @@
* <p>The cache does not store metadata. It remembers which providers can
* provide which kinds of metadata, for which kinds of relational
* expressions.</p>
+ *
+ * @deprecated Use {@link RelMetadataQuery}.
*/
+@Deprecated // to be removed before 2.0
public class MetadataFactoryImpl implements MetadataFactory {
@SuppressWarnings("unchecked")
public static final UnboundMetadata<@Nullable Metadata> DUMMY = (rel, mq) -> null;
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/ReflectiveRelMetadataProvider.java b/core/src/main/java/org/apache/calcite/rel/metadata/ReflectiveRelMetadataProvider.java
index 783e250..122367b 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/ReflectiveRelMetadataProvider.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/ReflectiveRelMetadataProvider.java
@@ -64,7 +64,9 @@
implements RelMetadataProvider, ReflectiveVisitor {
//~ Instance fields --------------------------------------------------------
+ @Deprecated // to be removed before 2.0
private final ConcurrentMap<Class<RelNode>, UnboundMetadata> map;
+ @Deprecated // to be removed before 2.0
private final Class<? extends Metadata> metadataClass0;
private final ImmutableMultimap<Method, MetadataHandler> handlerMap;
@@ -229,7 +231,7 @@
}
//~ Methods ----------------------------------------------------------------
-
+ @Deprecated // to be removed before 2.0
@Override public <@Nullable M extends @Nullable Metadata> @Nullable UnboundMetadata<M> apply(
Class<? extends RelNode> relClass, Class<? extends M> metadataClass) {
if (metadataClass == metadataClass0) {
@@ -240,6 +242,7 @@
}
@SuppressWarnings({ "unchecked", "SuspiciousMethodCalls" })
+ @Deprecated // to be removed before 2.0
public <@Nullable M extends @Nullable Metadata> @Nullable UnboundMetadata<M> apply(
Class<? extends RelNode> relClass) {
List<Class<? extends RelNode>> newSources = new ArrayList<>();
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataProvider.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataProvider.java
index 1bd9a20..84cff20 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataProvider.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataProvider.java
@@ -59,11 +59,14 @@
* Double d = selectivity.selectivity(predicate);
* </pre></blockquote>
*
+ * @deprecated Use {@link RelMetadataQuery}.
+ *
* @param relClass Type of relational expression
* @param metadataClass Type of metadata
* @return Function that will field a metadata instance; or null if this
* provider cannot supply metadata of this type
*/
+ @Deprecated // to be removed before 2.0
<@Nullable M extends @Nullable Metadata> @Nullable UnboundMetadata<M> apply(
Class<? extends RelNode> relClass, Class<? extends M> metadataClass);
diff --git a/core/src/main/java/org/apache/calcite/tools/Programs.java b/core/src/main/java/org/apache/calcite/tools/Programs.java
index b973c5c..63bc896 100644
--- a/core/src/main/java/org/apache/calcite/tools/Programs.java
+++ b/core/src/main/java/org/apache/calcite/tools/Programs.java
@@ -151,6 +151,7 @@
}
/** Creates a program that executes a {@link HepProgram}. */
+ @SuppressWarnings("deprecation")
public static Program of(final HepProgram hepProgram, final boolean noDag,
final RelMetadataProvider metadataProvider) {
return (planner, rel, requiredOutputTraits, materializations, lattices) -> {
diff --git a/core/src/test/java/org/apache/calcite/test/MockRelOptPlanner.java b/core/src/test/java/org/apache/calcite/test/MockRelOptPlanner.java
index d2a7a52..6e317a7 100644
--- a/core/src/test/java/org/apache/calcite/test/MockRelOptPlanner.java
+++ b/core/src/test/java/org/apache/calcite/test/MockRelOptPlanner.java
@@ -204,10 +204,12 @@
return true;
}
+ @Deprecated // to be removed before 2.0
@Override public long getRelMetadataTimestamp(RelNode rel) {
return metadataTimestamp;
}
+ @Deprecated // to be removed before 2.0
/** Allow tests to tweak the timestamp. */
public void setRelMetadataTimestamp(long metadataTimestamp) {
this.metadataTimestamp = metadataTimestamp;
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 b24985e..a497a34 100644
--- a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
@@ -66,7 +66,6 @@
import org.apache.calcite.rel.logical.LogicalUnion;
import org.apache.calcite.rel.logical.LogicalValues;
import org.apache.calcite.rel.metadata.BuiltInMetadata;
-import org.apache.calcite.rel.metadata.CachingRelMetadataProvider;
import org.apache.calcite.rel.metadata.ChainedRelMetadataProvider;
import org.apache.calcite.rel.metadata.DefaultRelMetadataProvider;
import org.apache.calcite.rel.metadata.JaninoRelMetadataProvider;
@@ -80,6 +79,7 @@
import org.apache.calcite.rel.metadata.RelMdUtil;
import org.apache.calcite.rel.metadata.RelMetadataProvider;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
+import org.apache.calcite.rel.metadata.UnboundMetadata;
import org.apache.calcite.rel.rules.CoreRules;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
@@ -997,10 +997,6 @@
RelNode rel =
convertSql("select deptno, count(*) from emp where deptno > 10 "
+ "group by deptno having count(*) = 0");
- rel.getCluster().setMetadataProvider(
- new CachingRelMetadataProvider(
- rel.getCluster().getMetadataProvider(),
- rel.getCluster().getPlanner()));
final RelMetadataQuery mq = rel.getCluster().getMetadataQuery();
Double result = mq.getSelectivity(rel, null);
assertThat(result,
@@ -1021,11 +1017,20 @@
final RelNode rel = convertSql("select * from emp");
final RelMetadataProvider metadataProvider =
rel.getCluster().getMetadataProvider();
- final RelOptPlanner planner = rel.getCluster().getPlanner();
for (int i = 0; i < iterationCount; i++) {
- RelMetadataQuery.THREAD_PROVIDERS.set(
- JaninoRelMetadataProvider.of(
- new CachingRelMetadataProvider(metadataProvider, planner)));
+ RelMetadataProvider wrappedProvider = new RelMetadataProvider() {
+ @Deprecated // to be removed before 2.0
+ @Override public @Nullable <M extends @Nullable Metadata> UnboundMetadata<M> apply(
+ Class<? extends RelNode> relClass, Class<? extends M> metadataClass) {
+ return metadataProvider.apply(relClass, metadataClass);
+ }
+
+ @Override public <M extends Metadata> Multimap<Method, MetadataHandler<M>> handlers(
+ MetadataDef<M> def) {
+ return metadataProvider.handlers(def);
+ }
+ };
+ RelMetadataQuery.THREAD_PROVIDERS.set(JaninoRelMetadataProvider.of(wrappedProvider));
final RelMetadataQuery mq = rel.getCluster().getMetadataQuery();
final Double result = mq.getRowCount(rel);
assertThat(result, within(14d, 0.1d));
@@ -1583,6 +1588,7 @@
}
}
+ @Deprecated // to be removed before 2.0
public String colType(RelMetadataQuery mq, RelNode rel, int column) {
return rel.metadata(ColType.class, mq).getColType(column);
}
@@ -1591,6 +1597,7 @@
return myRelMetadataQuery.colType(rel, column);
}
+ @Deprecated // to be removed before 2.0
@Test void testCustomProviderWithRelMetadataFactory() {
final List<String> buf = new ArrayList<>();
ColTypeImpl.THREAD_LIST.set(buf);
@@ -1633,7 +1640,7 @@
// generates a new call to the provider.
final RelOptPlanner planner = rel.getCluster().getPlanner();
rel.getCluster().setMetadataProvider(
- new CachingRelMetadataProvider(
+ new org.apache.calcite.rel.metadata.CachingRelMetadataProvider(
rel.getCluster().getMetadataProvider(), planner));
assertThat(colType(mq, input, 0), equalTo("DEPTNO-agg"));
assertThat(buf.size(), equalTo(5));
@@ -3484,6 +3491,7 @@
implements MetadataHandler<ColType> {
static final ThreadLocal<List<String>> THREAD_LIST = new ThreadLocal<>();
+ @Deprecated
public MetadataDef<ColType> getDef() {
return ColType.DEF;
}
diff --git a/core/src/test/java/org/apache/calcite/test/RelOptTestBase.java b/core/src/test/java/org/apache/calcite/test/RelOptTestBase.java
index 5d04585..f94242a 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptTestBase.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptTestBase.java
@@ -115,7 +115,6 @@
final DiffRepository diffRepos = getDiffRepos();
List<RelMetadataProvider> list = new ArrayList<>();
list.add(DefaultRelMetadataProvider.INSTANCE);
- planner.registerMetadataProviders(list);
RelMetadataProvider plannerChain =
ChainedRelMetadataProvider.of(list);
final RelOptCluster cluster = relInitial.getCluster();