You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2016/03/17 21:10:13 UTC
[6/8] calcite git commit: [CALCITE-1147] Allow multiple providers for
the same kind of metadata
[CALCITE-1147] Allow multiple providers for the same kind of metadata
Make it possible to extend RelMetadataQuery for a user-defined metadata
type, and create a test case illustrating.
Give an explicit error when metadata provider does not have a RelNode
handler (that is, a safety net if there are no handlers for more specific
RelNode sub-classes).
Improve how we handle ExecutionException.
Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/94f8837c
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/94f8837c
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/94f8837c
Branch: refs/heads/master
Commit: 94f8837c4974edc33e58b16b9ee2f061125b9b60
Parents: 22aa8a8
Author: Julian Hyde <jh...@apache.org>
Authored: Fri Mar 11 15:35:59 2016 -0800
Committer: Julian Hyde <jh...@apache.org>
Committed: Thu Mar 17 12:32:01 2016 -0700
----------------------------------------------------------------------
.../CachingLatticeStatisticProvider.java | 5 +-
.../plan/hep/HepRelMetadataProvider.java | 8 +-
.../volcano/VolcanoRelMetadataProvider.java | 8 +-
.../metadata/CachingRelMetadataProvider.java | 3 +-
.../metadata/ChainedRelMetadataProvider.java | 10 +-
.../rel/metadata/JaninoRelMetadataProvider.java | 11 +-
.../rel/metadata/MetadataFactoryImpl.java | 10 +-
.../metadata/ReflectiveRelMetadataProvider.java | 52 +++---
.../rel/metadata/RelMetadataProvider.java | 5 +-
.../calcite/rel/metadata/RelMetadataQuery.java | 93 +++++-----
.../org/apache/calcite/test/CalciteAssert.java | 5 +-
.../apache/calcite/test/RelMetadataTest.java | 170 ++++++++++++++-----
.../apache/calcite/test/RelOptRulesTest.java | 2 +-
.../apache/calcite/test/SqlToRelTestBase.java | 29 +++-
14 files changed, 256 insertions(+), 155 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/calcite/blob/94f8837c/core/src/main/java/org/apache/calcite/materialize/CachingLatticeStatisticProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/materialize/CachingLatticeStatisticProvider.java b/core/src/main/java/org/apache/calcite/materialize/CachingLatticeStatisticProvider.java
index bf70e5d..bf2702c 100644
--- a/core/src/main/java/org/apache/calcite/materialize/CachingLatticeStatisticProvider.java
+++ b/core/src/main/java/org/apache/calcite/materialize/CachingLatticeStatisticProvider.java
@@ -22,6 +22,7 @@ import com.google.common.base.Throwables;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
+import com.google.common.util.concurrent.UncheckedExecutionException;
import java.util.concurrent.ExecutionException;
@@ -48,8 +49,8 @@ class CachingLatticeStatisticProvider implements LatticeStatisticProvider {
public int cardinality(Lattice lattice, Lattice.Column column) {
try {
return cache.get(Pair.of(lattice, column));
- } catch (ExecutionException e) {
- throw Throwables.propagate(e);
+ } catch (UncheckedExecutionException | ExecutionException e) {
+ throw Throwables.propagate(e.getCause());
}
}
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/94f8837c/core/src/main/java/org/apache/calcite/plan/hep/HepRelMetadataProvider.java
----------------------------------------------------------------------
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 317fe94..3ed2b96 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
@@ -24,10 +24,10 @@ import org.apache.calcite.rel.metadata.RelMetadataProvider;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.calcite.rel.metadata.UnboundMetadata;
-import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.Multimap;
import java.lang.reflect.Method;
-import java.util.Map;
/**
* HepRelMetadataProvider implements the {@link RelMetadataProvider} interface
@@ -62,9 +62,9 @@ class HepRelMetadataProvider implements RelMetadataProvider {
};
}
- public <M extends Metadata> Map<Method, MetadataHandler<M>>
+ public <M extends Metadata> Multimap<Method, MetadataHandler<M>>
handlers(MetadataDef<M> def) {
- return ImmutableMap.of();
+ return ImmutableMultimap.of();
}
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/94f8837c/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoRelMetadataProvider.java
----------------------------------------------------------------------
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 c32d7d3..f996707 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
@@ -24,10 +24,10 @@ import org.apache.calcite.rel.metadata.RelMetadataProvider;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.calcite.rel.metadata.UnboundMetadata;
-import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.Multimap;
import java.lang.reflect.Method;
-import java.util.Map;
/**
* VolcanoRelMetadataProvider implements the {@link RelMetadataProvider}
@@ -115,9 +115,9 @@ public class VolcanoRelMetadataProvider implements RelMetadataProvider {
};
}
- public <M extends Metadata> Map<Method, MetadataHandler<M>>
+ public <M extends Metadata> Multimap<Method, MetadataHandler<M>>
handlers(MetadataDef<M> def) {
- return ImmutableMap.of();
+ return ImmutableMultimap.of();
}
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/94f8837c/core/src/main/java/org/apache/calcite/rel/metadata/CachingRelMetadataProvider.java
----------------------------------------------------------------------
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 202bf4c..eb63604 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
@@ -22,6 +22,7 @@ import org.apache.calcite.rel.RelNode;
import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Multimap;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
@@ -77,7 +78,7 @@ public class CachingRelMetadataProvider implements RelMetadataProvider {
};
}
- public <M extends Metadata> Map<Method, MetadataHandler<M>>
+ public <M extends Metadata> Multimap<Method, MetadataHandler<M>>
handlers(MetadataDef<M> def) {
return underlyingProvider.handlers(def);
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/94f8837c/core/src/main/java/org/apache/calcite/rel/metadata/ChainedRelMetadataProvider.java
----------------------------------------------------------------------
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 698bc9c..1ecec0f 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
@@ -20,8 +20,9 @@ import org.apache.calcite.rel.RelNode;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Lists;
+import com.google.common.collect.Multimap;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
@@ -29,7 +30,6 @@ import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
/**
* Implementation of the {@link RelMetadataProvider}
@@ -104,10 +104,10 @@ public class ChainedRelMetadataProvider implements RelMetadataProvider {
}
}
- public <M extends Metadata> Map<Method, MetadataHandler<M>>
+ public <M extends Metadata> Multimap<Method, MetadataHandler<M>>
handlers(MetadataDef<M> def) {
- final ImmutableMap.Builder<Method, MetadataHandler<M>> builder =
- ImmutableMap.builder();
+ final ImmutableMultimap.Builder<Method, MetadataHandler<M>> builder =
+ ImmutableMultimap.builder();
for (RelMetadataProvider provider : providers.reverse()) {
builder.putAll(provider.handlers(def));
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/94f8837c/core/src/main/java/org/apache/calcite/rel/metadata/JaninoRelMetadataProvider.java
----------------------------------------------------------------------
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 ac7f4d1..ac395e4 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
@@ -63,6 +63,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
+import com.google.common.util.concurrent.UncheckedExecutionException;
import org.codehaus.commons.compiler.CompileException;
import org.codehaus.commons.compiler.CompilerFactoryFactory;
@@ -182,14 +183,14 @@ public class JaninoRelMetadataProvider implements RelMetadataProvider {
throw new UnsupportedOperationException();
}
- public <M extends Metadata> Map<Method, MetadataHandler<M>>
+ public <M extends Metadata> Multimap<Method, MetadataHandler<M>>
handlers(MetadataDef<M> def) {
return provider.handlers(def);
}
private static <M extends Metadata>
MetadataHandler<M> load3(MetadataDef<M> def,
- Map<Method, MetadataHandler<M>> map,
+ Multimap<Method, MetadataHandler<M>> map,
ImmutableList<Class<? extends RelNode>> relClasses) {
final StringBuilder buff = new StringBuilder();
final String name =
@@ -198,7 +199,7 @@ public class JaninoRelMetadataProvider implements RelMetadataProvider {
final List<Pair<String, MetadataHandler>> providerList = new ArrayList<>();
//noinspection unchecked
final ReflectiveRelMetadataProvider.Space space =
- new ReflectiveRelMetadataProvider.Space((Map) map);
+ new ReflectiveRelMetadataProvider.Space((Multimap) map);
for (MetadataHandler provider : space.providerMap.values()) {
if (providerSet.add(provider)) {
providerList.add(Pair.of("provider" + (providerSet.size() - 1),
@@ -445,8 +446,8 @@ public class JaninoRelMetadataProvider implements RelMetadataProvider {
ImmutableList.copyOf(ALL_RELS));
//noinspection unchecked
return (H) HANDLERS.get(key);
- } catch (ExecutionException e) {
- throw Throwables.propagate(e);
+ } catch (UncheckedExecutionException | ExecutionException e) {
+ throw Throwables.propagate(e.getCause());
}
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/94f8837c/core/src/main/java/org/apache/calcite/rel/metadata/MetadataFactoryImpl.java
----------------------------------------------------------------------
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 f5b5717..09446be 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
@@ -19,9 +19,11 @@ package org.apache.calcite.rel.metadata;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.util.Pair;
+import com.google.common.base.Throwables;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
+import com.google.common.util.concurrent.UncheckedExecutionException;
import java.util.concurrent.ExecutionException;
@@ -70,12 +72,8 @@ public class MetadataFactoryImpl implements MetadataFactory {
(Pair) Pair.of(rel.getClass(), metadataClazz);
final Metadata apply = cache.get(key).bind(rel, mq);
return metadataClazz.cast(apply);
- } catch (ExecutionException e) {
- if (e.getCause() instanceof RuntimeException) {
- throw (RuntimeException) e.getCause();
- } else {
- throw (Error) e.getCause();
- }
+ } catch (UncheckedExecutionException | ExecutionException e) {
+ throw Throwables.propagate(e.getCause());
}
}
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/94f8837c/core/src/main/java/org/apache/calcite/rel/metadata/ReflectiveRelMetadataProvider.java
----------------------------------------------------------------------
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 5f6d680..baceb35 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
@@ -25,9 +25,11 @@ import org.apache.calcite.util.Pair;
import org.apache.calcite.util.ReflectiveVisitor;
import org.apache.calcite.util.Util;
+import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.Multimap;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
@@ -63,7 +65,7 @@ public class ReflectiveRelMetadataProvider
//~ Instance fields --------------------------------------------------------
private final ConcurrentMap<Class<RelNode>, UnboundMetadata> map;
private final Class<? extends Metadata> metadataClass0;
- private final ImmutableMap<Method, MetadataHandler> handlerMap;
+ private final ImmutableMultimap<Method, MetadataHandler> handlerMap;
//~ Constructors -----------------------------------------------------------
@@ -77,11 +79,11 @@ public class ReflectiveRelMetadataProvider
protected ReflectiveRelMetadataProvider(
ConcurrentMap<Class<RelNode>, UnboundMetadata> map,
Class<? extends Metadata> metadataClass0,
- Map<Method, MetadataHandler> handlerMap) {
+ Multimap<Method, MetadataHandler> handlerMap) {
assert !map.isEmpty() : "are your methods named wrong?";
this.map = map;
this.metadataClass0 = metadataClass0;
- this.handlerMap = ImmutableMap.copyOf(handlerMap);
+ this.handlerMap = ImmutableMultimap.copyOf(handlerMap);
}
/** Returns an implementation of {@link RelMetadataProvider} that scans for
@@ -210,11 +212,11 @@ public class ReflectiveRelMetadataProvider
space.providerMap);
}
- public <M extends Metadata> Map<Method, MetadataHandler<M>>
+ public <M extends Metadata> Multimap<Method, MetadataHandler<M>>
handlers(MetadataDef<M> def) {
- final ImmutableMap.Builder<Method, MetadataHandler<M>> builder =
- ImmutableMap.builder();
- for (Map.Entry<Method, MetadataHandler> entry : handlerMap.entrySet()) {
+ final ImmutableMultimap.Builder<Method, MetadataHandler<M>> builder =
+ ImmutableMultimap.builder();
+ for (Map.Entry<Method, MetadataHandler> entry : handlerMap.entries()) {
if (def.methods.contains(entry.getKey())) {
//noinspection unchecked
builder.put(entry.getKey(), entry.getValue());
@@ -288,14 +290,14 @@ public class ReflectiveRelMetadataProvider
static class Space {
final Set<Class<RelNode>> classes = new HashSet<>();
final Map<Pair<Class<RelNode>, Method>, Method> handlerMap = new HashMap<>();
- final ImmutableMap<Method, MetadataHandler> providerMap;
+ final ImmutableMultimap<Method, MetadataHandler> providerMap;
- Space(Map<Method, MetadataHandler> providerMap) {
- this.providerMap = ImmutableMap.copyOf(providerMap);
+ Space(Multimap<Method, MetadataHandler> providerMap) {
+ this.providerMap = ImmutableMultimap.copyOf(providerMap);
// Find the distinct set of RelNode classes handled by this provider,
// ordered base-class first.
- for (Map.Entry<Method, MetadataHandler> entry : providerMap.entrySet()) {
+ for (Map.Entry<Method, MetadataHandler> entry : providerMap.entries()) {
final Method method = entry.getKey();
final MetadataHandler provider = entry.getValue();
for (final Method handlerMethod : provider.getClass().getMethods()) {
@@ -313,14 +315,14 @@ public class ReflectiveRelMetadataProvider
* nearest base class. Assumes that base classes have already been added to
* {@code map}. */
@SuppressWarnings({ "unchecked", "SuspiciousMethodCalls" })
- Method find(Class<? extends RelNode> relNodeClass, Method method) {
- Method implementingMethod;
- while (relNodeClass != null) {
- implementingMethod = handlerMap.get(Pair.of(relNodeClass, method));
+ Method find(final Class<? extends RelNode> relNodeClass, Method method) {
+ Preconditions.checkNotNull(relNodeClass);
+ for (Class r = relNodeClass;;) {
+ Method implementingMethod = handlerMap.get(Pair.of(r, method));
if (implementingMethod != null) {
return implementingMethod;
}
- for (Class<?> clazz : relNodeClass.getInterfaces()) {
+ for (Class<?> clazz : r.getInterfaces()) {
if (RelNode.class.isAssignableFrom(clazz)) {
implementingMethod = handlerMap.get(Pair.of(clazz, method));
if (implementingMethod != null) {
@@ -328,13 +330,13 @@ public class ReflectiveRelMetadataProvider
}
}
}
- if (RelNode.class.isAssignableFrom(relNodeClass.getSuperclass())) {
- relNodeClass = (Class<RelNode>) relNodeClass.getSuperclass();
- } else {
- relNodeClass = null;
+ r = r.getSuperclass();
+ if (r == null || !RelNode.class.isAssignableFrom(r)) {
+ throw new IllegalArgumentException("No handler for method [" + method
+ + "] applied to argument of type [" + relNodeClass
+ + "]; we recommend you create a catch-all (RelNode) handler");
}
}
- return null;
}
}
@@ -343,7 +345,7 @@ public class ReflectiveRelMetadataProvider
private Class<Metadata> metadataClass0;
public Space2(Class<Metadata> metadataClass0,
- ImmutableMap<Method, MetadataHandler> providerMap) {
+ ImmutableMultimap<Method, MetadataHandler> providerMap) {
super(providerMap);
this.metadataClass0 = metadataClass0;
}
@@ -359,8 +361,8 @@ public class ReflectiveRelMetadataProvider
assert method.getDeclaringClass() == metadataClass0;
}
- final ImmutableMap.Builder<Method, MetadataHandler> providerBuilder =
- ImmutableMap.builder();
+ final ImmutableMultimap.Builder<Method, MetadataHandler> providerBuilder =
+ ImmutableMultimap.builder();
for (final Method method : methods) {
providerBuilder.put(method, target);
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/94f8837c/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataProvider.java
----------------------------------------------------------------------
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 c1d5f39..b4ddbe2 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
@@ -18,8 +18,9 @@ package org.apache.calcite.rel.metadata;
import org.apache.calcite.rel.RelNode;
+import com.google.common.collect.Multimap;
+
import java.lang.reflect.Method;
-import java.util.Map;
/**
* RelMetadataProvider defines an interface for obtaining metadata about
@@ -65,7 +66,7 @@ public interface RelMetadataProvider {
apply(Class<? extends RelNode> relClass,
Class<? extends M> metadataClass);
- <M extends Metadata> Map<Method, MetadataHandler<M>>
+ <M extends Metadata> Multimap<Method, MetadataHandler<M>>
handlers(MetadataDef<M> def);
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/94f8837c/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java
index abca58e..4e07612 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java
@@ -80,7 +80,7 @@ public class RelMetadataQuery {
public final JaninoRelMetadataProvider metadataProvider;
- private static final RelMetadataQuery EMPTY = new RelMetadataQuery(false);
+ protected static final RelMetadataQuery EMPTY = new RelMetadataQuery(false);
private BuiltInMetadata.Collation.Handler collationHandler;
private BuiltInMetadata.ColumnOrigin.Handler columnOriginHandler;
@@ -108,7 +108,7 @@ public class RelMetadataQuery {
}
};
- private RelMetadataQuery(JaninoRelMetadataProvider metadataProvider,
+ protected RelMetadataQuery(JaninoRelMetadataProvider metadataProvider,
RelMetadataQuery prototype) {
this.metadataProvider = Preconditions.checkNotNull(metadataProvider);
this.collationHandler = prototype.collationHandler;
@@ -131,7 +131,7 @@ public class RelMetadataQuery {
this.uniqueKeysHandler = prototype.uniqueKeysHandler;
}
- private static <H> H initialHandler(Class<H> handlerClass) {
+ protected static <H> H initialHandler(Class<H> handlerClass) {
return handlerClass.cast(
Proxy.newProxyInstance(RelMetadataQuery.class.getClassLoader(),
new Class[] {handlerClass},
@@ -179,6 +179,13 @@ public class RelMetadataQuery {
this.uniqueKeysHandler = initialHandler(BuiltInMetadata.UniqueKeys.Handler.class);
}
+ /** Re-generates the handler for a given kind of metadata, adding support for
+ * {@code class_} if it is not already present. */
+ protected <M extends Metadata, H extends MetadataHandler<M>> H
+ revise(Class<? extends RelNode> class_, MetadataDef<M> def) {
+ return metadataProvider.revise(class_, def);
+ }
+
/**
* Returns the
* {@link BuiltInMetadata.RowCount#getRowCount()}
@@ -194,8 +201,7 @@ public class RelMetadataQuery {
Double result = rowCountHandler.getRowCount(rel, this);
return validateResult(result);
} catch (JaninoRelMetadataProvider.NoHandler e) {
- rowCountHandler = metadataProvider.revise(e.relClass,
- BuiltInMetadata.RowCount.DEF);
+ rowCountHandler = revise(e.relClass, BuiltInMetadata.RowCount.DEF);
}
}
}
@@ -213,8 +219,8 @@ public class RelMetadataQuery {
try {
return maxRowCountHandler.getMaxRowCount(rel, this);
} catch (JaninoRelMetadataProvider.NoHandler e) {
- maxRowCountHandler = metadataProvider.revise(e.relClass,
- BuiltInMetadata.MaxRowCount.DEF);
+ maxRowCountHandler =
+ revise(e.relClass, BuiltInMetadata.MaxRowCount.DEF);
}
}
}
@@ -232,8 +238,8 @@ public class RelMetadataQuery {
try {
return cumulativeCostHandler.getCumulativeCost(rel, this);
} catch (JaninoRelMetadataProvider.NoHandler e) {
- cumulativeCostHandler = metadataProvider.revise(e.relClass,
- BuiltInMetadata.CumulativeCost.DEF);
+ cumulativeCostHandler =
+ revise(e.relClass, BuiltInMetadata.CumulativeCost.DEF);
}
}
}
@@ -251,8 +257,8 @@ public class RelMetadataQuery {
try {
return nonCumulativeCostHandler.getNonCumulativeCost(rel, this);
} catch (JaninoRelMetadataProvider.NoHandler e) {
- nonCumulativeCostHandler = metadataProvider.revise(e.relClass,
- BuiltInMetadata.NonCumulativeCost.DEF);
+ nonCumulativeCostHandler =
+ revise(e.relClass, BuiltInMetadata.NonCumulativeCost.DEF);
}
}
}
@@ -273,8 +279,8 @@ public class RelMetadataQuery {
percentageOriginalRowsHandler.getPercentageOriginalRows(rel, this);
return validatePercentage(result);
} catch (JaninoRelMetadataProvider.NoHandler e) {
- percentageOriginalRowsHandler = metadataProvider.revise(e.relClass,
- BuiltInMetadata.PercentageOriginalRows.DEF);
+ percentageOriginalRowsHandler =
+ revise(e.relClass, BuiltInMetadata.PercentageOriginalRows.DEF);
}
}
}
@@ -295,8 +301,8 @@ public class RelMetadataQuery {
try {
return columnOriginHandler.getColumnOrigins(rel, this, column);
} catch (JaninoRelMetadataProvider.NoHandler e) {
- columnOriginHandler = metadataProvider.revise(e.relClass,
- BuiltInMetadata.ColumnOrigin.DEF);
+ columnOriginHandler =
+ revise(e.relClass, BuiltInMetadata.ColumnOrigin.DEF);
}
}
}
@@ -359,8 +365,8 @@ public class RelMetadataQuery {
Double result = selectivityHandler.getSelectivity(rel, this, predicate);
return validatePercentage(result);
} catch (JaninoRelMetadataProvider.NoHandler e) {
- selectivityHandler = metadataProvider.revise(e.relClass,
- BuiltInMetadata.Selectivity.DEF);
+ selectivityHandler =
+ revise(e.relClass, BuiltInMetadata.Selectivity.DEF);
}
}
}
@@ -396,8 +402,8 @@ public class RelMetadataQuery {
try {
return uniqueKeysHandler.getUniqueKeys(rel, this, ignoreNulls);
} catch (JaninoRelMetadataProvider.NoHandler e) {
- uniqueKeysHandler = metadataProvider.revise(e.relClass,
- BuiltInMetadata.UniqueKeys.DEF);
+ uniqueKeysHandler =
+ revise(e.relClass, BuiltInMetadata.UniqueKeys.DEF);
}
}
}
@@ -455,8 +461,8 @@ public class RelMetadataQuery {
return columnUniquenessHandler.areColumnsUnique(rel, this, columns,
ignoreNulls);
} catch (JaninoRelMetadataProvider.NoHandler e) {
- columnUniquenessHandler = metadataProvider.revise(e.relClass,
- BuiltInMetadata.ColumnUniqueness.DEF);
+ columnUniquenessHandler =
+ revise(e.relClass, BuiltInMetadata.ColumnUniqueness.DEF);
}
}
}
@@ -475,8 +481,7 @@ public class RelMetadataQuery {
try {
return collationHandler.collations(rel, this);
} catch (JaninoRelMetadataProvider.NoHandler e) {
- collationHandler = metadataProvider.revise(e.relClass,
- BuiltInMetadata.Collation.DEF);
+ collationHandler = revise(e.relClass, BuiltInMetadata.Collation.DEF);
}
}
}
@@ -495,8 +500,8 @@ public class RelMetadataQuery {
try {
return distributionHandler.distribution(rel, this);
} catch (JaninoRelMetadataProvider.NoHandler e) {
- distributionHandler = metadataProvider.revise(e.relClass,
- BuiltInMetadata.Distribution.DEF);
+ distributionHandler =
+ revise(e.relClass, BuiltInMetadata.Distribution.DEF);
}
}
}
@@ -521,8 +526,8 @@ public class RelMetadataQuery {
populationSizeHandler.getPopulationSize(rel, this, groupKey);
return validateResult(result);
} catch (JaninoRelMetadataProvider.NoHandler e) {
- populationSizeHandler = metadataProvider.revise(e.relClass,
- BuiltInMetadata.PopulationSize.DEF);
+ populationSizeHandler =
+ revise(e.relClass, BuiltInMetadata.PopulationSize.DEF);
}
}
}
@@ -540,8 +545,7 @@ public class RelMetadataQuery {
try {
return sizeHandler.averageRowSize(rel, this);
} catch (JaninoRelMetadataProvider.NoHandler e) {
- sizeHandler = metadataProvider.revise(e.relClass,
- BuiltInMetadata.Size.DEF);
+ sizeHandler = revise(e.relClass, BuiltInMetadata.Size.DEF);
}
}
}
@@ -561,8 +565,7 @@ public class RelMetadataQuery {
try {
return sizeHandler.averageColumnSizes(rel, this);
} catch (JaninoRelMetadataProvider.NoHandler e) {
- sizeHandler = metadataProvider.revise(e.relClass,
- BuiltInMetadata.Size.DEF);
+ sizeHandler = revise(e.relClass, BuiltInMetadata.Size.DEF);
}
}
}
@@ -591,8 +594,8 @@ public class RelMetadataQuery {
try {
return parallelismHandler.isPhaseTransition(rel, this);
} catch (JaninoRelMetadataProvider.NoHandler e) {
- parallelismHandler = metadataProvider.revise(e.relClass,
- BuiltInMetadata.Parallelism.DEF);
+ parallelismHandler =
+ revise(e.relClass, BuiltInMetadata.Parallelism.DEF);
}
}
}
@@ -610,8 +613,8 @@ public class RelMetadataQuery {
try {
return parallelismHandler.splitCount(rel, this);
} catch (JaninoRelMetadataProvider.NoHandler e) {
- parallelismHandler = metadataProvider.revise(e.relClass,
- BuiltInMetadata.Parallelism.DEF);
+ parallelismHandler =
+ revise(e.relClass, BuiltInMetadata.Parallelism.DEF);
}
}
}
@@ -631,8 +634,7 @@ public class RelMetadataQuery {
try {
return memoryHandler.memory(rel, this);
} catch (JaninoRelMetadataProvider.NoHandler e) {
- memoryHandler = metadataProvider.revise(e.relClass,
- BuiltInMetadata.Memory.DEF);
+ memoryHandler = revise(e.relClass, BuiltInMetadata.Memory.DEF);
}
}
}
@@ -652,8 +654,7 @@ public class RelMetadataQuery {
try {
return memoryHandler.cumulativeMemoryWithinPhase(rel, this);
} catch (JaninoRelMetadataProvider.NoHandler e) {
- memoryHandler = metadataProvider.revise(e.relClass,
- BuiltInMetadata.Memory.DEF);
+ memoryHandler = revise(e.relClass, BuiltInMetadata.Memory.DEF);
}
}
}
@@ -673,8 +674,7 @@ public class RelMetadataQuery {
try {
return memoryHandler.cumulativeMemoryWithinPhaseSplit(rel, this);
} catch (JaninoRelMetadataProvider.NoHandler e) {
- memoryHandler = metadataProvider.revise(e.relClass,
- BuiltInMetadata.Memory.DEF);
+ memoryHandler = revise(e.relClass, BuiltInMetadata.Memory.DEF);
}
}
}
@@ -701,8 +701,8 @@ public class RelMetadataQuery {
predicate);
return validateResult(result);
} catch (JaninoRelMetadataProvider.NoHandler e) {
- distinctRowCountHandler = metadataProvider.revise(e.relClass,
- BuiltInMetadata.DistinctRowCount.DEF);
+ distinctRowCountHandler =
+ revise(e.relClass, BuiltInMetadata.DistinctRowCount.DEF);
}
}
}
@@ -720,8 +720,7 @@ public class RelMetadataQuery {
try {
return predicatesHandler.getPredicates(rel, this);
} catch (JaninoRelMetadataProvider.NoHandler e) {
- predicatesHandler = metadataProvider.revise(e.relClass,
- BuiltInMetadata.Predicates.DEF);
+ predicatesHandler = revise(e.relClass, BuiltInMetadata.Predicates.DEF);
}
}
}
@@ -744,8 +743,8 @@ public class RelMetadataQuery {
explainLevel);
return b == null || b;
} catch (JaninoRelMetadataProvider.NoHandler e) {
- explainVisibilityHandler = metadataProvider.revise(e.relClass,
- BuiltInMetadata.ExplainVisibility.DEF);
+ explainVisibilityHandler =
+ revise(e.relClass, BuiltInMetadata.ExplainVisibility.DEF);
}
}
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/94f8837c/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/CalciteAssert.java b/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
index 729326a..7a962a0 100644
--- a/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
+++ b/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
@@ -48,6 +48,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultiset;
import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.UncheckedExecutionException;
import net.hydromatic.foodmart.data.hsqldb.FoodmartHsqldb;
import net.hydromatic.scott.data.hsqldb.ScottHsqldb;
@@ -1072,9 +1073,9 @@ public class CalciteAssert {
public Connection createConnection() throws SQLException {
try {
return Pool.POOL.get(factory);
- } catch (ExecutionException e) {
+ } catch (UncheckedExecutionException | ExecutionException e) {
throw new SQLException(
- "Unable to get pooled connection for " + factory, e);
+ "Unable to get pooled connection for " + factory, e.getCause());
}
}
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/94f8837c/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
----------------------------------------------------------------------
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 ab7e02d..562286a 100644
--- a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
@@ -17,6 +17,7 @@
package org.apache.calcite.test;
import org.apache.calcite.adapter.enumerable.EnumerableMergeJoin;
+import org.apache.calcite.linq4j.tree.Types;
import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.RelOptPlanner;
import org.apache.calcite.plan.RelOptPredicateList;
@@ -51,6 +52,7 @@ import org.apache.calcite.rel.logical.LogicalValues;
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;
import org.apache.calcite.rel.metadata.Metadata;
import org.apache.calcite.rel.metadata.MetadataDef;
import org.apache.calcite.rel.metadata.MetadataHandler;
@@ -71,6 +73,7 @@ import org.apache.calcite.tools.Frameworks;
import org.apache.calcite.util.ImmutableBitSet;
import org.apache.calcite.util.ImmutableIntList;
+import com.google.common.base.Function;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@@ -99,6 +102,7 @@ import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
/**
* Unit test for {@link DefaultRelMetadataProvider}. See
@@ -860,38 +864,88 @@ public class RelMetadataTest extends SqlToRelTestBase {
assertUniqueConsistent(rel);
}
+ @Test public void testBrokenCustomProvider() {
+ final List<String> buf = Lists.newArrayList();
+ ColTypeImpl.THREAD_LIST.set(buf);
+
+ final String sql = "select deptno, count(*) from emp where deptno > 10 "
+ + "group by deptno having count(*) = 0";
+ final RelRoot root = tester
+ .withClusterFactory(
+ new Function<RelOptCluster, RelOptCluster>() {
+ public RelOptCluster apply(RelOptCluster cluster) {
+ cluster.setMetadataProvider(
+ ChainedRelMetadataProvider.of(
+ ImmutableList.of(BrokenColTypeImpl.SOURCE,
+ cluster.getMetadataProvider())));
+ return cluster;
+ }
+ })
+ .convertSqlToRel(sql);
+
+ final RelNode rel = root.rel;
+ assertThat(rel, instanceOf(LogicalFilter.class));
+ final MyRelMetadataQuery mq = new MyRelMetadataQuery();
+
+ try {
+ assertThat(colType(mq, rel, 0), equalTo("DEPTNO-rel"));
+ fail("expected error");
+ } catch (IllegalArgumentException e) {
+ final String value = "No handler for method [public abstract java.lang.String "
+ + "org.apache.calcite.test.RelMetadataTest$ColType.getColType(int)] "
+ + "applied to argument of type [interface org.apache.calcite.rel.RelNode]; "
+ + "we recommend you create a catch-all (RelNode) handler";
+ assertThat(e.getMessage(), is(value));
+ }
+ }
+
+ public String colType(RelMetadataQuery mq, RelNode rel, int column) {
+ if (mq instanceof MyRelMetadataQuery) {
+ return ((MyRelMetadataQuery) mq).colType(rel, column);
+ } else {
+ return rel.metadata(ColType.class, mq).getColType(column);
+ }
+ }
+
@Test public void testCustomProvider() {
final List<String> buf = Lists.newArrayList();
ColTypeImpl.THREAD_LIST.set(buf);
- RelNode rel =
- convertSql("select deptno, count(*) from emp where deptno > 10 "
- + "group by deptno having count(*) = 0");
- rel.getCluster().setMetadataProvider(
- ChainedRelMetadataProvider.of(
- ImmutableList.of(
- ColTypeImpl.SOURCE, rel.getCluster().getMetadataProvider())));
+ final String sql = "select deptno, count(*) from emp where deptno > 10 "
+ + "group by deptno having count(*) = 0";
+ final RelRoot root = tester
+ .withClusterFactory(
+ new Function<RelOptCluster, RelOptCluster>() {
+ public RelOptCluster apply(RelOptCluster cluster) {
+ // Create a custom provider that includes ColType.
+ // Include the same provider twice just to be devious.
+ final ImmutableList<RelMetadataProvider> list =
+ ImmutableList.of(ColTypeImpl.SOURCE, ColTypeImpl.SOURCE,
+ cluster.getMetadataProvider());
+ cluster.setMetadataProvider(
+ ChainedRelMetadataProvider.of(list));
+ return cluster;
+ }
+ })
+ .convertSqlToRel(sql);
+ final RelNode rel = root.rel;
// Top node is a filter. Its metadata uses getColType(RelNode, int).
assertThat(rel, instanceOf(LogicalFilter.class));
final RelMetadataQuery mq = RelMetadataQuery.instance();
- assertThat(rel.metadata(ColType.class, mq).getColType(0),
- equalTo("DEPTNO-rel"));
- assertThat(rel.metadata(ColType.class, mq).getColType(1),
- equalTo("EXPR$1-rel"));
+ assertThat(colType(mq, rel, 0), equalTo("DEPTNO-rel"));
+ assertThat(colType(mq, rel, 1), equalTo("EXPR$1-rel"));
// Next node is an aggregate. Its metadata uses
// getColType(LogicalAggregate, int).
final RelNode input = rel.getInput(0);
assertThat(input, instanceOf(LogicalAggregate.class));
- assertThat(input.metadata(ColType.class, mq).getColType(0),
- equalTo("DEPTNO-agg"));
+ assertThat(colType(mq, input, 0), equalTo("DEPTNO-agg"));
// There is no caching. Another request causes another call to the provider.
assertThat(buf.toString(), equalTo("[DEPTNO-rel, EXPR$1-rel, DEPTNO-agg]"));
assertThat(buf.size(), equalTo(3));
- assertThat(input.metadata(ColType.class, mq).getColType(0),
- equalTo("DEPTNO-agg"));
+ assertThat(colType(mq, input, 0), equalTo("DEPTNO-agg"));
assertThat(buf.size(), equalTo(4));
// Now add a cache. Only the first request for each piece of metadata
@@ -900,31 +954,24 @@ public class RelMetadataTest extends SqlToRelTestBase {
rel.getCluster().setMetadataProvider(
new CachingRelMetadataProvider(
rel.getCluster().getMetadataProvider(), planner));
- assertThat(input.metadata(ColType.class, mq).getColType(0),
- equalTo("DEPTNO-agg"));
+ assertThat(colType(mq, input, 0), equalTo("DEPTNO-agg"));
assertThat(buf.size(), equalTo(5));
- assertThat(input.metadata(ColType.class, mq).getColType(0),
- equalTo("DEPTNO-agg"));
+ assertThat(colType(mq, input, 0), equalTo("DEPTNO-agg"));
assertThat(buf.size(), equalTo(5));
- assertThat(input.metadata(ColType.class, mq).getColType(1),
- equalTo("EXPR$1-agg"));
+ assertThat(colType(mq, input, 1), equalTo("EXPR$1-agg"));
assertThat(buf.size(), equalTo(6));
- assertThat(input.metadata(ColType.class, mq).getColType(1),
- equalTo("EXPR$1-agg"));
+ assertThat(colType(mq, input, 1), equalTo("EXPR$1-agg"));
assertThat(buf.size(), equalTo(6));
- assertThat(input.metadata(ColType.class, mq).getColType(0),
- equalTo("DEPTNO-agg"));
+ assertThat(colType(mq, input, 0), equalTo("DEPTNO-agg"));
assertThat(buf.size(), equalTo(6));
// With a different timestamp, a metadata item is re-computed on first call.
long timestamp = planner.getRelMetadataTimestamp(rel);
assertThat(timestamp, equalTo(0L));
((MockRelOptPlanner) planner).setRelMetadataTimestamp(timestamp + 1);
- assertThat(input.metadata(ColType.class, mq).getColType(0),
- equalTo("DEPTNO-agg"));
+ assertThat(colType(mq, input, 0), equalTo("DEPTNO-agg"));
assertThat(buf.size(), equalTo(7));
- assertThat(input.metadata(ColType.class, mq).getColType(0),
- equalTo("DEPTNO-agg"));
+ assertThat(colType(mq, input, 0), equalTo("DEPTNO-agg"));
assertThat(buf.size(), equalTo(7));
}
@@ -1383,28 +1430,27 @@ public class RelMetadataTest extends SqlToRelTestBase {
/** Custom metadata interface. */
public interface ColType extends Metadata {
+ Method METHOD = Types.lookupMethod(ColType.class, "getColType", int.class);
+
+ MetadataDef<ColType> DEF =
+ MetadataDef.of(ColType.class, ColType.Handler.class, METHOD);
+
String getColType(int column);
+
+ /** Handler API. */
+ interface Handler extends MetadataHandler<ColType> {
+ String getColType(RelNode r, RelMetadataQuery mq, int column);
+ }
}
/** A provider for {@link org.apache.calcite.test.RelMetadataTest.ColType} via
* reflection. */
- public static class ColTypeImpl implements MetadataHandler {
+ public abstract static class PartialColTypeImpl
+ implements MetadataHandler<ColType> {
static final ThreadLocal<List<String>> THREAD_LIST = new ThreadLocal<>();
- static final Method METHOD;
- static {
- try {
- METHOD = ColType.class.getMethod("getColType", int.class);
- } catch (NoSuchMethodException e) {
- throw new RuntimeException(e);
- }
- }
-
- public static final RelMetadataProvider SOURCE =
- ReflectiveRelMetadataProvider.reflectiveSource(
- METHOD, new ColTypeImpl());
- public MetadataDef getDef() {
- throw new UnsupportedOperationException();
+ public MetadataDef<ColType> getDef() {
+ return ColType.DEF;
}
/** Implementation of {@link ColType#getColType(int)} for
@@ -1417,6 +1463,13 @@ public class RelMetadataTest extends SqlToRelTestBase {
THREAD_LIST.get().add(name);
return name;
}
+ }
+
+ /** A provider for {@link org.apache.calcite.test.RelMetadataTest.ColType} via
+ * reflection. */
+ public static class ColTypeImpl extends PartialColTypeImpl {
+ public static final RelMetadataProvider SOURCE =
+ ReflectiveRelMetadataProvider.reflectiveSource(ColType.METHOD, new ColTypeImpl());
/** Implementation of {@link ColType#getColType(int)} for
* {@link RelNode}, called via reflection. */
@@ -1428,6 +1481,35 @@ public class RelMetadataTest extends SqlToRelTestBase {
return name;
}
}
+
+ /** Implementation of {@link ColType} that has no fall-back for {@link RelNode}. */
+ public static class BrokenColTypeImpl extends PartialColTypeImpl {
+ public static final RelMetadataProvider SOURCE =
+ ReflectiveRelMetadataProvider.reflectiveSource(ColType.METHOD,
+ new BrokenColTypeImpl());
+ }
+
+ /** Extension to {@link RelMetadataQuery} to support {@link ColType}.
+ *
+ * <p>Illustrates how you would package up a user-defined metadata type. */
+ private static class MyRelMetadataQuery extends RelMetadataQuery {
+ private ColType.Handler colTypeHandler;
+
+ public MyRelMetadataQuery() {
+ super(THREAD_PROVIDERS.get(), EMPTY);
+ colTypeHandler = initialHandler(ColType.Handler.class);
+ }
+
+ public String colType(RelNode rel, int column) {
+ for (;;) {
+ try {
+ return colTypeHandler.getColType(rel, this, column);
+ } catch (JaninoRelMetadataProvider.NoHandler e) {
+ colTypeHandler = revise(e.relClass, ColType.DEF);
+ }
+ }
+ }
+ }
}
// End RelMetadataTest.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/94f8837c/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
index 7bd85cb..9a2c3db 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -2036,7 +2036,7 @@ public class RelOptRulesTest extends RelOptTestBase {
* Wrong collation trait in SortJoinTransposeRule for right joins</a>. */
@Test public void testSortJoinTranspose4() {
// Create a customized test with RelCollation trait in the test cluster.
- Tester tester = new TesterImpl(getDiffRepos(), true, true, false, null) {
+ Tester tester = new TesterImpl(getDiffRepos(), true, true, false, null, null) {
@Override public RelOptPlanner createPlanner() {
return new MockRelOptPlanner() {
@Override public List<RelTraitDef> getRelTraitDefs() {
http://git-wip-us.apache.org/repos/asf/calcite/blob/94f8837c/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java b/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java
index 7e818af..3d7f609 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java
@@ -92,7 +92,7 @@ public abstract class SqlToRelTestBase {
}
protected Tester createTester() {
- return new TesterImpl(getDiffRepos(), false, false, true, null);
+ return new TesterImpl(getDiffRepos(), false, false, true, null, null);
}
/**
@@ -221,6 +221,8 @@ public abstract class SqlToRelTestBase {
/** Returns a tester that optionally trims unused fields. */
Tester withTrim(boolean enable);
+
+ Tester withClusterFactory(Function<RelOptCluster, RelOptCluster> function);
}
//~ Inner Classes ----------------------------------------------------------
@@ -463,6 +465,7 @@ public abstract class SqlToRelTestBase {
private final boolean enableExpand;
private final Function<RelDataTypeFactory, Prepare.CatalogReader>
catalogReaderFactory;
+ private final Function<RelOptCluster, RelOptCluster> clusterFactory;
private RelDataTypeFactory typeFactory;
/**
@@ -473,16 +476,19 @@ public abstract class SqlToRelTestBase {
* @param enableTrim Whether to trim unused fields
* @param enableExpand Whether to expand sub-queries
* @param catalogReaderFactory Function to create catalog reader, or null
+ * @param clusterFactory Called after a cluster has been created
*/
protected TesterImpl(DiffRepository diffRepos, boolean enableDecorrelate,
boolean enableTrim, boolean enableExpand,
Function<RelDataTypeFactory, Prepare.CatalogReader>
- catalogReaderFactory) {
+ catalogReaderFactory,
+ Function<RelOptCluster, RelOptCluster> clusterFactory) {
this.diffRepos = diffRepos;
this.enableDecorrelate = enableDecorrelate;
this.enableTrim = enableTrim;
this.enableExpand = enableExpand;
this.catalogReaderFactory = catalogReaderFactory;
+ this.clusterFactory = clusterFactory;
}
public RelRoot convertSqlToRel(String sql) {
@@ -528,8 +534,11 @@ public abstract class SqlToRelTestBase {
final Prepare.CatalogReader catalogReader,
final RelDataTypeFactory typeFactory) {
final RexBuilder rexBuilder = new RexBuilder(typeFactory);
- final RelOptCluster cluster =
+ RelOptCluster cluster =
RelOptCluster.create(getPlanner(), rexBuilder);
+ if (clusterFactory != null) {
+ cluster = clusterFactory.apply(cluster);
+ }
return new SqlToRelConverter(null, validator, catalogReader, cluster,
StandardConvertletTable.INSTANCE);
}
@@ -659,27 +668,33 @@ public abstract class SqlToRelTestBase {
return this.enableDecorrelate == enable
? this
: new TesterImpl(diffRepos, enable, enableTrim, enableExpand,
- catalogReaderFactory);
+ catalogReaderFactory, clusterFactory);
}
public Tester withTrim(boolean enable) {
return this.enableTrim == enable
? this
: new TesterImpl(diffRepos, enableDecorrelate, enable, enableExpand,
- catalogReaderFactory);
+ catalogReaderFactory, clusterFactory);
}
public Tester withExpand(boolean expand) {
return this.enableExpand == expand
? this
: new TesterImpl(diffRepos, enableDecorrelate, enableTrim, expand,
- catalogReaderFactory);
+ catalogReaderFactory, clusterFactory);
}
public Tester withCatalogReaderFactory(
Function<RelDataTypeFactory, Prepare.CatalogReader> factory) {
return new TesterImpl(diffRepos, enableDecorrelate, false, enableExpand,
- factory);
+ factory, clusterFactory);
+ }
+
+ public Tester withClusterFactory(
+ Function<RelOptCluster, RelOptCluster> clusterFactory) {
+ return new TesterImpl(diffRepos, enableDecorrelate, false, enableExpand,
+ catalogReaderFactory, clusterFactory);
}
}