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 2015/06/13 02:38:05 UTC
[1/7] incubator-calcite git commit: [CALCITE-740] Redundant WHERE
clause causes wrong result in MongoDB adapter
Repository: incubator-calcite
Updated Branches:
refs/heads/master dbdb091dc -> 468a161bb
[CALCITE-740] Redundant WHERE clause causes wrong result in MongoDB adapter
Project: http://git-wip-us.apache.org/repos/asf/incubator-calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-calcite/commit/6ece12a8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-calcite/tree/6ece12a8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-calcite/diff/6ece12a8
Branch: refs/heads/master
Commit: 6ece12a862d9fb03f2be77c0d60880a30fbd79b1
Parents: dbdb091
Author: Julian Hyde <jh...@apache.org>
Authored: Mon Jun 8 12:05:44 2015 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Mon Jun 8 12:07:48 2015 -0700
----------------------------------------------------------------------
.../calcite/adapter/mongodb/MongoFilter.java | 34 ++++++++++++++++--
.../org/apache/calcite/test/MongoAdapterIT.java | 36 ++++++++++++++++++++
2 files changed, 67 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/6ece12a8/mongodb/src/main/java/org/apache/calcite/adapter/mongodb/MongoFilter.java
----------------------------------------------------------------------
diff --git a/mongodb/src/main/java/org/apache/calcite/adapter/mongodb/MongoFilter.java b/mongodb/src/main/java/org/apache/calcite/adapter/mongodb/MongoFilter.java
index 5f717d7..45b4baf 100644
--- a/mongodb/src/main/java/org/apache/calcite/adapter/mongodb/MongoFilter.java
+++ b/mongodb/src/main/java/org/apache/calcite/adapter/mongodb/MongoFilter.java
@@ -116,20 +116,48 @@ public class MongoFilter extends Filter implements MongoRel {
Map<String, Object> map = builder.map();
for (Map.Entry<String, RexLiteral> entry : eqMap.entrySet()) {
multimap.removeAll(entry.getKey());
- map.put(entry.getKey(), literalToString(entry.getValue()));
+ map.put(entry.getKey(), literalValue(entry.getValue()));
}
for (Map.Entry<String, Collection<Pair<String, RexLiteral>>> entry
: multimap.asMap().entrySet()) {
Map<String, Object> map2 = builder.map();
for (Pair<String, RexLiteral> s : entry.getValue()) {
- map2.put(s.left, literalToString(s.right));
+ addPredicate(map2, s.left, literalValue(s.right));
}
map.put(entry.getKey(), map2);
}
return map;
}
- private static Object literalToString(RexLiteral literal) {
+ private void addPredicate(Map<String, Object> map, String op, Object v) {
+ if (map.containsKey(op) && stronger(op, map.get(op), v)) {
+ return;
+ }
+ map.put(op, v);
+ }
+
+ /** Returns whether {@code v0} is a stronger value for operator {@code key}
+ * than {@code v1}.
+ *
+ * <p>For example, {@code stronger("$lt", 100, 200)} returns true, because
+ * "< 100" is a more powerful condition than "< 200".
+ */
+ private boolean stronger(String key, Object v0, Object v1) {
+ if (key.equals("$lt") || key.equals("$lte")) {
+ if (v0 instanceof Number && v1 instanceof Number) {
+ return ((Number) v0).doubleValue() < ((Number) v1).doubleValue();
+ }
+ if (v0 instanceof String && v1 instanceof String) {
+ return v0.toString().compareTo(v1.toString()) < 0;
+ }
+ }
+ if (key.equals("$gt") || key.equals("$gte")) {
+ return stronger("$lt", v1, v0);
+ }
+ return false;
+ }
+
+ private static Object literalValue(RexLiteral literal) {
return literal.getValue2();
}
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/6ece12a8/mongodb/src/test/java/org/apache/calcite/test/MongoAdapterIT.java
----------------------------------------------------------------------
diff --git a/mongodb/src/test/java/org/apache/calcite/test/MongoAdapterIT.java b/mongodb/src/test/java/org/apache/calcite/test/MongoAdapterIT.java
index f994142..2393660 100644
--- a/mongodb/src/test/java/org/apache/calcite/test/MongoAdapterIT.java
+++ b/mongodb/src/test/java/org/apache/calcite/test/MongoAdapterIT.java
@@ -716,6 +716,42 @@ public class MongoAdapterIT {
+ "STATE=WV; CITY=ATHENS\n");
}
+ /** MongoDB's predicates are handed (they can only accept literals on the
+ * right-hand size) so it's worth testing that we handle them right both
+ * ways around.
+ *
+ * <p>Test case for
+ * <a href="https://issues.apache.org/jira/browse/CALCITE-740">[CALCITE-740]
+ * Redundant WHERE clause causes wrong result in MongoDB adapter</a>. */
+ @Test public void testFilterPair() {
+ final int gt9k = 8125;
+ final int lt9k = 21227;
+ final int gt8k = 8707;
+ final int lt8k = 20645;
+ checkPredicate(gt9k, "where pop > 8000 and pop > 9000");
+ checkPredicate(gt9k, "where pop > 9000");
+ checkPredicate(lt9k, "where pop < 9000");
+ checkPredicate(gt8k, "where pop > 8000");
+ checkPredicate(lt8k, "where pop < 8000");
+ checkPredicate(gt9k, "where pop > 9000 and pop > 8000");
+ checkPredicate(gt8k, "where pop > 9000 or pop > 8000");
+ checkPredicate(gt8k, "where pop > 8000 or pop > 9000");
+ checkPredicate(lt8k, "where pop < 8000 and pop < 9000");
+ }
+
+ private void checkPredicate(int expected, String q) {
+ CalciteAssert.that()
+ .enable(enabled())
+ .with(ZIPS)
+ .query("select count(*) as c from zips\n" + q)
+ .returns("C=" + expected + "\n");
+ CalciteAssert.that()
+ .enable(enabled())
+ .with(ZIPS)
+ .query("select * from zips\n" + q)
+ .returnsCount(expected);
+ }
+
@Ignore
@Test public void testFoodmartQueries() {
final List<Pair<String, String>> queries = JdbcTest.getFoodmartQueries();
[7/7] incubator-calcite git commit: [CALCITE-757] Fix expansion of
view of another view (Venki Korukanti)
Posted by jh...@apache.org.
[CALCITE-757] Fix expansion of view of another view (Venki Korukanti)
Pass ViewExpanderImpl to SqlToRelConverter so that a view of another view is expanded properly.
The issue was found in [DRILL-1145].
Close apache/incubator-calcite#94
Project: http://git-wip-us.apache.org/repos/asf/incubator-calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-calcite/commit/468a161b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-calcite/tree/468a161b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-calcite/diff/468a161b
Branch: refs/heads/master
Commit: 468a161bbd8fd4994085d96e2bc801209a17cf76
Parents: 2b21765
Author: vkorukanti <ve...@gmail.com>
Authored: Fri Jun 5 11:02:46 2015 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Fri Jun 12 00:15:47 2015 -0700
----------------------------------------------------------------------
.../java/org/apache/calcite/prepare/PlannerImpl.java | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/468a161b/core/src/main/java/org/apache/calcite/prepare/PlannerImpl.java
----------------------------------------------------------------------
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 f39ab2c..1c67178 100644
--- a/core/src/main/java/org/apache/calcite/prepare/PlannerImpl.java
+++ b/core/src/main/java/org/apache/calcite/prepare/PlannerImpl.java
@@ -218,11 +218,18 @@ public class PlannerImpl implements Planner {
final RexBuilder rexBuilder = createRexBuilder();
final RelOptCluster cluster = RelOptCluster.create(planner, rexBuilder);
final SqlToRelConverter sqlToRelConverter =
- new SqlToRelConverter(null, validator, catalogReader, cluster,
- convertletTable);
+ new SqlToRelConverter(new ViewExpanderImpl(), validator,
+ catalogReader, cluster, convertletTable);
+
sqlToRelConverter.setTrimUnusedFields(false);
+ sqlToRelConverter.enableTableAccessConversion(false);
+
+ RelNode rel =
+ sqlToRelConverter.convertQuery(validatedSqlNode, true, false);
+ rel = sqlToRelConverter.flattenTypes(rel, true);
+ rel = RelDecorrelator.decorrelateQuery(rel);
- return sqlToRelConverter.convertQuery(validatedSqlNode, true, false);
+ return rel;
}
}
[2/7] incubator-calcite git commit: [CALCITE-429] Cardinality
provider for use by lattice algorithm
Posted by jh...@apache.org.
[CALCITE-429] Cardinality provider for use by lattice algorithm
Project: http://git-wip-us.apache.org/repos/asf/incubator-calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-calcite/commit/4cc539fc
Tree: http://git-wip-us.apache.org/repos/asf/incubator-calcite/tree/4cc539fc
Diff: http://git-wip-us.apache.org/repos/asf/incubator-calcite/diff/4cc539fc
Branch: refs/heads/master
Commit: 4cc539fc28fac0c5897ada1cc5e57729807d260d
Parents: 6ece12a
Author: Julian Hyde <jh...@apache.org>
Authored: Mon Jun 8 14:07:06 2015 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Thu Jun 11 16:12:26 2015 -0700
----------------------------------------------------------------------
.../calcite/avatica/test/AvaticaSuite.java | 1 +
avatica/pom.xml | 5 ++
.../apache/calcite/avatica/AvaticaUtils.java | 48 ++++++++++
.../calcite/avatica/ConnectionConfigImpl.java | 20 +----
.../calcite/avatica/test/AvaticaUtilsTest.java | 64 +++++++++++++
.../CachingLatticeStatisticProvider.java | 57 ++++++++++++
.../DelegatingLatticeStatisticProvider.java | 41 +++++++++
.../org/apache/calcite/materialize/Lattice.java | 95 ++++++++------------
.../materialize/LatticeStatisticProvider.java | 27 ++++++
.../apache/calcite/materialize/Lattices.java | 40 +++++++++
.../SqlLatticeStatisticProvider.java | 48 ++++++++++
.../org/apache/calcite/model/JsonLattice.java | 13 +++
.../org/apache/calcite/model/ModelHandler.java | 3 +
.../test/FoodMartLatticeStatisticProvider.java | 92 +++++++++++++++++++
.../org/apache/calcite/test/LatticeTest.java | 28 ++++--
site/_docs/model.md | 17 +++-
16 files changed, 517 insertions(+), 82 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/4cc539fc/avatica-server/src/test/java/org/apache/calcite/avatica/test/AvaticaSuite.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/test/java/org/apache/calcite/avatica/test/AvaticaSuite.java b/avatica-server/src/test/java/org/apache/calcite/avatica/test/AvaticaSuite.java
index 5afba20..4a0c26c 100644
--- a/avatica-server/src/test/java/org/apache/calcite/avatica/test/AvaticaSuite.java
+++ b/avatica-server/src/test/java/org/apache/calcite/avatica/test/AvaticaSuite.java
@@ -27,6 +27,7 @@ import org.junit.runners.Suite;
*/
@RunWith(Suite.class)
@Suite.SuiteClasses({
+ AvaticaUtilsTest.class,
ConnectStringParserTest.class,
RemoteDriverTest.class
})
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/4cc539fc/avatica/pom.xml
----------------------------------------------------------------------
diff --git a/avatica/pom.xml b/avatica/pom.xml
index 3e241db..50b80c7 100644
--- a/avatica/pom.xml
+++ b/avatica/pom.xml
@@ -53,6 +53,11 @@ limitations under the License.
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest-core</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/4cc539fc/avatica/src/main/java/org/apache/calcite/avatica/AvaticaUtils.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaUtils.java b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaUtils.java
index 77fafc4..5ca5245 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaUtils.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaUtils.java
@@ -16,6 +16,7 @@
*/
package org.apache.calcite.avatica;
+import java.lang.reflect.Field;
import java.util.AbstractList;
import java.util.HashMap;
import java.util.List;
@@ -117,6 +118,53 @@ public class AvaticaUtils {
}
return clazz;
}
+
+ /** Creates an instance of a plugin class. First looks for a static
+ * member called INSTANCE, then calls a public default constructor.
+ *
+ * <p>If className contains a "#" instead looks for a static field.
+ *
+ * @param pluginClass Class (or interface) to instantiate
+ * @param className Name of implementing class
+ * @param <T> Class
+ * @return Plugin instance
+ */
+ public static <T> T instantiatePlugin(Class<T> pluginClass,
+ String className) {
+ try {
+ // Given a static field, say "com.example.MyClass#FOO_INSTANCE", return
+ // the value of that static field.
+ if (className.contains("#")) {
+ try {
+ int i = className.indexOf('#');
+ String left = className.substring(0, i);
+ String right = className.substring(i + 1);
+ //noinspection unchecked
+ final Class<T> clazz = (Class) Class.forName(left);
+ final Field field;
+ field = clazz.getField(right);
+ return pluginClass.cast(field.get(null));
+ } catch (NoSuchFieldException e) {
+ // ignore
+ }
+ }
+ //noinspection unchecked
+ final Class<T> clazz = (Class) Class.forName(className);
+ assert pluginClass.isAssignableFrom(clazz);
+ try {
+ // We assume that if there is an INSTANCE field it is static and
+ // has the right type.
+ final Field field = clazz.getField("INSTANCE");
+ return pluginClass.cast(field.get(null));
+ } catch (NoSuchFieldException e) {
+ // ignore
+ }
+ return clazz.newInstance();
+ } catch (Exception e) {
+ throw new RuntimeException("Property '" + className
+ + "' not valid for plugin type " + pluginClass.getName(), e);
+ }
+ }
}
// End AvaticaUtils.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/4cc539fc/avatica/src/main/java/org/apache/calcite/avatica/ConnectionConfigImpl.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/ConnectionConfigImpl.java b/avatica/src/main/java/org/apache/calcite/avatica/ConnectionConfigImpl.java
index 300063f..3200bee 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/ConnectionConfigImpl.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/ConnectionConfigImpl.java
@@ -18,7 +18,6 @@ package org.apache.calcite.avatica;
import org.apache.calcite.avatica.remote.Service;
-import java.lang.reflect.Field;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;
@@ -217,24 +216,7 @@ public class ConnectionConfigImpl implements ConnectionConfig {
throw new RuntimeException("Required property '"
+ connectionProperty.camelName() + "' not specified");
}
- // First look for a C.INSTANCE field, then do new C().
- try {
- //noinspection unchecked
- final Class<T> clazz = (Class) Class.forName(s);
- assert pluginClass.isAssignableFrom(clazz);
- try {
- // We assume that if there is an INSTANCE field it is static and
- // has the right type.
- final Field field = clazz.getField("INSTANCE");
- return pluginClass.cast(field.get(null));
- } catch (NoSuchFieldException e) {
- // ignore
- }
- return clazz.newInstance();
- } catch (Exception e) {
- throw new RuntimeException("Property '" + s
- + "' not valid for plugin type " + pluginClass.getName(), e);
- }
+ return AvaticaUtils.instantiatePlugin(pluginClass, s);
}
};
}
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/4cc539fc/avatica/src/test/java/org/apache/calcite/avatica/test/AvaticaUtilsTest.java
----------------------------------------------------------------------
diff --git a/avatica/src/test/java/org/apache/calcite/avatica/test/AvaticaUtilsTest.java b/avatica/src/test/java/org/apache/calcite/avatica/test/AvaticaUtilsTest.java
new file mode 100644
index 0000000..ca548a6
--- /dev/null
+++ b/avatica/src/test/java/org/apache/calcite/avatica/test/AvaticaUtilsTest.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.avatica.test;
+
+import org.apache.calcite.avatica.AvaticaUtils;
+
+import org.junit.Test;
+
+import java.math.BigInteger;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+/**
+ * Unit test for Avatica utilities.
+ */
+public class AvaticaUtilsTest {
+ @Test public void testInstantiatePlugin() {
+ final String s =
+ AvaticaUtils.instantiatePlugin(String.class, "java.lang.String");
+ assertThat(s, is(""));
+
+ // No default constructor or INSTANCE member
+ try {
+ final Integer i =
+ AvaticaUtils.instantiatePlugin(Integer.class, "java.lang.Integer");
+ fail("expected error, got " + i);
+ } catch (Throwable e) {
+ assertThat(e.getMessage(),
+ is("Property 'java.lang.Integer' not valid for plugin type java.lang.Integer"));
+ }
+
+ final BigInteger b =
+ AvaticaUtils.instantiatePlugin(BigInteger.class, "java.math.BigInteger#ONE");
+ assertThat(b, is(BigInteger.ONE));
+
+ try {
+ final BigInteger b2 =
+ AvaticaUtils.instantiatePlugin(BigInteger.class,
+ "java.math.BigInteger.ONE");
+ fail("expected error, got " + b2);
+ } catch (Throwable e) {
+ assertThat(e.getMessage(),
+ is("Property 'java.math.BigInteger.ONE' not valid for plugin type java.math.BigInteger"));
+ }
+ }
+}
+
+// End AvaticaUtilsTest.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/4cc539fc/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
new file mode 100644
index 0000000..bf70e5d
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/materialize/CachingLatticeStatisticProvider.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.materialize;
+
+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 java.util.concurrent.ExecutionException;
+
+/**
+ * Implementation of {@link LatticeStatisticProvider} that gets statistics by
+ * executing "SELECT COUNT(DISTINCT ...) ..." SQL queries.
+ */
+class CachingLatticeStatisticProvider implements LatticeStatisticProvider {
+ private final LoadingCache<Pair<Lattice, Lattice.Column>, Integer> cache;
+
+ /** Creates a CachingStatisticProvider. */
+ public CachingLatticeStatisticProvider(
+ final LatticeStatisticProvider provider) {
+ cache = CacheBuilder.<Pair<Lattice, Lattice.Column>>newBuilder()
+ .build(
+ new CacheLoader<Pair<Lattice, Lattice.Column>, Integer>() {
+ public Integer load(Pair<Lattice, Lattice.Column> key)
+ throws Exception {
+ return provider.cardinality(key.left, key.right);
+ }
+ });
+ }
+
+ public int cardinality(Lattice lattice, Lattice.Column column) {
+ try {
+ return cache.get(Pair.of(lattice, column));
+ } catch (ExecutionException e) {
+ throw Throwables.propagate(e);
+ }
+ }
+}
+
+// End CachingLatticeStatisticProvider.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/4cc539fc/core/src/main/java/org/apache/calcite/materialize/DelegatingLatticeStatisticProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/materialize/DelegatingLatticeStatisticProvider.java b/core/src/main/java/org/apache/calcite/materialize/DelegatingLatticeStatisticProvider.java
new file mode 100644
index 0000000..e1ec6c5
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/materialize/DelegatingLatticeStatisticProvider.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.materialize;
+
+/**
+ * Implementation of {@link LatticeStatisticProvider} that delegates
+ * to an underlying provider.
+ */
+public class DelegatingLatticeStatisticProvider
+ implements LatticeStatisticProvider {
+ protected final LatticeStatisticProvider provider;
+
+ /** Creates a DelegatingLatticeStatisticProvider.
+ *
+ * @param provider Provider to which to delegate otherwise unhandled requests
+ */
+ protected DelegatingLatticeStatisticProvider(
+ LatticeStatisticProvider provider) {
+ this.provider = provider;
+ }
+
+ public int cardinality(Lattice lattice, Lattice.Column column) {
+ return provider.cardinality(lattice, column);
+ }
+}
+
+// End DelegatingLatticeStatisticProvider.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/4cc539fc/core/src/main/java/org/apache/calcite/materialize/Lattice.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/materialize/Lattice.java b/core/src/main/java/org/apache/calcite/materialize/Lattice.java
index 38b4eac..c2b07c3 100644
--- a/core/src/main/java/org/apache/calcite/materialize/Lattice.java
+++ b/core/src/main/java/org/apache/calcite/materialize/Lattice.java
@@ -16,7 +16,9 @@
*/
package org.apache.calcite.materialize;
+import org.apache.calcite.avatica.AvaticaUtils;
import org.apache.calcite.jdbc.CalcitePrepare;
+import org.apache.calcite.jdbc.CalciteRootSchema;
import org.apache.calcite.jdbc.CalciteSchema;
import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.prepare.CalcitePrepareImpl;
@@ -55,7 +57,6 @@ import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
-import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Ordering;
@@ -85,6 +86,7 @@ public class Lattice {
}
};
+ public final CalciteRootSchema rootSchema;
public final ImmutableList<Node> nodes;
public final ImmutableList<Column> columns;
public final boolean auto;
@@ -94,6 +96,7 @@ public class Lattice {
public final ImmutableList<Measure> defaultMeasures;
public final ImmutableList<Tile> tiles;
public final ImmutableList<String> uniqueColumnNames;
+ public final LatticeStatisticProvider statisticProvider;
private final Function<Integer, Column> toColumnFunction =
new Function<Integer, Column>() {
@@ -109,15 +112,18 @@ public class Lattice {
}
};
- private Lattice(ImmutableList<Node> nodes, boolean auto, boolean algorithm,
- long algorithmMaxMillis,
- Double rowCountEstimate, ImmutableList<Column> columns,
- ImmutableList<Measure> defaultMeasures, ImmutableList<Tile> tiles) {
+ private Lattice(CalciteRootSchema rootSchema, ImmutableList<Node> nodes,
+ boolean auto, boolean algorithm, long algorithmMaxMillis,
+ LatticeStatisticProvider statisticProvider, Double rowCountEstimate,
+ ImmutableList<Column> columns, ImmutableList<Measure> defaultMeasures,
+ ImmutableList<Tile> tiles) {
+ this.rootSchema = rootSchema;
this.nodes = Preconditions.checkNotNull(nodes);
this.columns = Preconditions.checkNotNull(columns);
this.auto = auto;
this.algorithm = algorithm;
this.algorithmMaxMillis = algorithmMaxMillis;
+ this.statisticProvider = Preconditions.checkNotNull(statisticProvider);
this.defaultMeasures = Preconditions.checkNotNull(defaultMeasures);
this.tiles = Preconditions.checkNotNull(tiles);
@@ -328,6 +334,14 @@ public class Lattice {
return buf.toString();
}
+ /** Returns a SQL query that counts the number of distinct values of the
+ * attributes given in {@code groupSet}. */
+ public String countSql(ImmutableBitSet groupSet) {
+ return "select count(*) as c from ("
+ + sql(groupSet, ImmutableList.<Measure>of())
+ + ")";
+ }
+
private static void use(List<Node> usedNodes, Node node) {
if (!usedNodes.contains(node)) {
if (node.parent != null) {
@@ -376,7 +390,7 @@ public class Lattice {
// distributed attribute with N1 * ... * Nm distinct values.
BigInteger n = BigInteger.ONE;
for (Column column : columns) {
- final int cardinality = cardinality(column);
+ final int cardinality = statisticProvider.cardinality(this, column);
if (cardinality > 1) {
n = n.multiply(BigInteger.valueOf(cardinality));
}
@@ -394,53 +408,6 @@ public class Lattice {
return Math.min(v, f);
}
- public static final Map<String, Integer> CARDINALITY_MAP =
- ImmutableMap.<String, Integer>builder()
- .put("brand_name", 111)
- .put("cases_per_pallet", 10)
- .put("customer_id", 5581)
- .put("day_of_month", 30)
- .put("fiscal_period", 0)
- .put("gross_weight", 376)
- .put("low_fat", 2)
- .put("month_of_year", 12)
- .put("net_weight", 332)
- .put("product_category", 45)
- .put("product_class_id", 102)
- .put("product_department", 22)
- .put("product_family", 3)
- .put("product_id", 1559)
- .put("product_name", 1559)
- .put("product_subcategory", 102)
- .put("promotion_id", 149)
- .put("quarter", 4)
- .put("recyclable_package", 2)
- .put("shelf_depth", 488)
- .put("shelf_height", 524)
- .put("shelf_width", 534)
- .put("SKU", 1559)
- .put("SRP", 315)
- .put("store_cost", 10777)
- .put("store_id", 13)
- .put("store_sales", 1049)
- .put("the_date", 323)
- .put("the_day", 7)
- .put("the_month", 12)
- .put("the_year", 1)
- .put("time_id", 323)
- .put("units_per_case", 36)
- .put("unit_sales", 6)
- .put("week_of_year", 52)
- .build();
-
- private int cardinality(Column column) {
- final Integer integer = CARDINALITY_MAP.get(column.alias);
- if (integer != null && integer > 0) {
- return integer;
- }
- return column.alias.length();
- }
-
/** Source relation of a lattice.
*
* <p>Relations form a tree; all relations except the root relation
@@ -601,12 +568,15 @@ public class Lattice {
ImmutableList.builder();
private final ImmutableList.Builder<Tile> tileListBuilder =
ImmutableList.builder();
+ private final CalciteRootSchema rootSchema;
private boolean algorithm = false;
private long algorithmMaxMillis = -1;
private boolean auto = true;
private Double rowCountEstimate;
+ private String statisticProvider;
public Builder(CalciteSchema schema, String sql) {
+ this.rootSchema = schema.root();
CalcitePrepare.ConvertResult parsed =
Schemas.convert(MaterializedViewTable.MATERIALIZATION_CONNECTION,
schema, schema.path(null), sql);
@@ -710,11 +680,24 @@ public class Lattice {
return this;
}
+ /** Sets the "statisticProvider" attribute.
+ *
+ * <p>If not set, the lattice will use {@link Lattices#CACHED_SQL}. */
+ public Builder statisticProvider(String statisticProvider) {
+ this.statisticProvider = statisticProvider;
+ return this;
+ }
+
/** Builds a lattice. */
public Lattice build() {
- return new Lattice(ImmutableList.copyOf(nodes), auto, algorithm,
- algorithmMaxMillis, rowCountEstimate, columns,
- defaultMeasureListBuilder.build(), tileListBuilder.build());
+ LatticeStatisticProvider statisticProvider =
+ this.statisticProvider != null
+ ? AvaticaUtils.instantiatePlugin(LatticeStatisticProvider.class,
+ this.statisticProvider)
+ : Lattices.CACHED_SQL;
+ return new Lattice(rootSchema, ImmutableList.copyOf(nodes), auto,
+ algorithm, algorithmMaxMillis, statisticProvider, rowCountEstimate,
+ columns, defaultMeasureListBuilder.build(), tileListBuilder.build());
}
/** Resolves the arguments of a
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/4cc539fc/core/src/main/java/org/apache/calcite/materialize/LatticeStatisticProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/materialize/LatticeStatisticProvider.java b/core/src/main/java/org/apache/calcite/materialize/LatticeStatisticProvider.java
new file mode 100644
index 0000000..46668cc
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/materialize/LatticeStatisticProvider.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.materialize;
+
+/**
+ * Estimates row counts for a lattice and its attributes.
+ */
+public interface LatticeStatisticProvider {
+ /** Returns an estimate of the number of distinct values in a column. */
+ int cardinality(Lattice lattice, Lattice.Column column);
+}
+
+// End LatticeStatisticProvider.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/4cc539fc/core/src/main/java/org/apache/calcite/materialize/Lattices.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/materialize/Lattices.java b/core/src/main/java/org/apache/calcite/materialize/Lattices.java
new file mode 100644
index 0000000..cf70719
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/materialize/Lattices.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.materialize;
+
+/**
+ * Utilities for {@link Lattice}, {@link LatticeStatisticProvider}.
+ */
+public class Lattices {
+ private Lattices() {}
+
+ /** Statistics provider that uses SQL. */
+ public static final LatticeStatisticProvider SQL =
+ SqlLatticeStatisticProvider.INSTANCE;
+
+ /** Statistics provider that uses SQL then stores the results in a cache. */
+ public static final LatticeStatisticProvider CACHED_SQL =
+ cache(SqlLatticeStatisticProvider.INSTANCE);
+
+ /** Wraps a statistic provider in a cache. */
+ public static LatticeStatisticProvider cache(
+ LatticeStatisticProvider provider) {
+ return new CachingLatticeStatisticProvider(provider);
+ }
+}
+
+// End Lattices.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/4cc539fc/core/src/main/java/org/apache/calcite/materialize/SqlLatticeStatisticProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/materialize/SqlLatticeStatisticProvider.java b/core/src/main/java/org/apache/calcite/materialize/SqlLatticeStatisticProvider.java
new file mode 100644
index 0000000..4a94847
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/materialize/SqlLatticeStatisticProvider.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.materialize;
+
+import org.apache.calcite.schema.ScannableTable;
+import org.apache.calcite.schema.Table;
+import org.apache.calcite.util.ImmutableBitSet;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+
+/**
+ * Implementation of {@link LatticeStatisticProvider} that gets statistics by
+ * executing "SELECT COUNT(DISTINCT ...) ..." SQL queries.
+ */
+class SqlLatticeStatisticProvider implements LatticeStatisticProvider {
+ static final SqlLatticeStatisticProvider INSTANCE =
+ new SqlLatticeStatisticProvider();
+
+ /** Creates an SqlLatticeStatisticProvider. */
+ private SqlLatticeStatisticProvider() {}
+
+ @Override public int cardinality(Lattice lattice, Lattice.Column column) {
+ final String sql = lattice.countSql(ImmutableBitSet.of(column.ordinal));
+ final Table table =
+ new MaterializationService.DefaultTableFactory()
+ .createTable(lattice.rootSchema, sql, ImmutableList.<String>of());
+ final Object[] values =
+ Iterables.getOnlyElement(((ScannableTable) table).scan(null));
+ return ((Number) values[0]).intValue();
+ }
+}
+
+// End SqlLatticeStatisticProvider.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/4cc539fc/core/src/main/java/org/apache/calcite/model/JsonLattice.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/model/JsonLattice.java b/core/src/main/java/org/apache/calcite/model/JsonLattice.java
index 80974a3..d96eb06 100644
--- a/core/src/main/java/org/apache/calcite/model/JsonLattice.java
+++ b/core/src/main/java/org/apache/calcite/model/JsonLattice.java
@@ -55,6 +55,19 @@ public class JsonLattice {
* <p>If null, Calcite will a query to find the real value. */
public Double rowCountEstimate;
+ /** Name of a class that provides estimates of the number of distinct values
+ * in each column.
+ *
+ * <p>The class must implement the
+ * {@link org.apache.calcite.materialize.LatticeStatisticProvider} interface.
+ *
+ * <p>Or, you can use a class name plus a static field, for example
+ * "org.apache.calcite.materialize.Lattices#CACHING_SQL_STATISTIC_PROVIDER".
+ *
+ * <p>If not set, Calcite will generate and execute a SQL query to find the
+ * real value, and cache the results. */
+ public String statisticProvider;
+
/** List of materialized aggregates to create up front. */
public final List<JsonTile> tiles = Lists.newArrayList();
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/4cc539fc/core/src/main/java/org/apache/calcite/model/ModelHandler.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/model/ModelHandler.java b/core/src/main/java/org/apache/calcite/model/ModelHandler.java
index dfdb901..0c0efa8 100644
--- a/core/src/main/java/org/apache/calcite/model/ModelHandler.java
+++ b/core/src/main/java/org/apache/calcite/model/ModelHandler.java
@@ -291,6 +291,9 @@ public class ModelHandler {
if (jsonLattice.rowCountEstimate != null) {
latticeBuilder.rowCountEstimate(jsonLattice.rowCountEstimate);
}
+ if (jsonLattice.statisticProvider != null) {
+ latticeBuilder.statisticProvider(jsonLattice.statisticProvider);
+ }
populateLattice(jsonLattice, latticeBuilder);
schema.add(jsonLattice.name, latticeBuilder.build());
} catch (Exception e) {
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/4cc539fc/core/src/test/java/org/apache/calcite/test/FoodMartLatticeStatisticProvider.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/FoodMartLatticeStatisticProvider.java b/core/src/test/java/org/apache/calcite/test/FoodMartLatticeStatisticProvider.java
new file mode 100644
index 0000000..3f36bf9
--- /dev/null
+++ b/core/src/test/java/org/apache/calcite/test/FoodMartLatticeStatisticProvider.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.test;
+
+import org.apache.calcite.materialize.DelegatingLatticeStatisticProvider;
+import org.apache.calcite.materialize.Lattice;
+import org.apache.calcite.materialize.LatticeStatisticProvider;
+import org.apache.calcite.materialize.Lattices;
+
+import com.google.common.collect.ImmutableMap;
+
+import java.util.Map;
+
+/**
+ * Implementation of {@link LatticeStatisticProvider}
+ * that has hard-coded values for various attributes in the FoodMart lattice.
+ *
+ * <p>This makes testing faster.
+ */
+public class FoodMartLatticeStatisticProvider
+ extends DelegatingLatticeStatisticProvider {
+ public static final FoodMartLatticeStatisticProvider INSTANCE =
+ new FoodMartLatticeStatisticProvider(Lattices.CACHED_SQL);
+
+ public static final Map<String, Integer> CARDINALITY_MAP =
+ ImmutableMap.<String, Integer>builder()
+ .put("brand_name", 111)
+ .put("cases_per_pallet", 10)
+ .put("customer_id", 5581)
+ .put("day_of_month", 30)
+ .put("fiscal_period", 0)
+ .put("gross_weight", 376)
+ .put("low_fat", 2)
+ .put("month_of_year", 12)
+ .put("net_weight", 332)
+ .put("product_category", 45)
+ .put("product_class_id", 102)
+ .put("product_department", 22)
+ .put("product_family", 3)
+ .put("product_id", 1559)
+ .put("product_name", 1559)
+ .put("product_subcategory", 102)
+ .put("promotion_id", 149)
+ .put("quarter", 4)
+ .put("recyclable_package", 2)
+ .put("shelf_depth", 488)
+ .put("shelf_height", 524)
+ .put("shelf_width", 534)
+ .put("SKU", 1559)
+ .put("SRP", 315)
+ .put("store_cost", 10777)
+ .put("store_id", 13)
+ .put("store_sales", 1049)
+ .put("the_date", 323)
+ .put("the_day", 7)
+ .put("the_month", 12)
+ .put("the_year", 1)
+ .put("time_id", 323)
+ .put("units_per_case", 36)
+ .put("unit_sales", 6)
+ .put("week_of_year", 52)
+ .build();
+
+ private FoodMartLatticeStatisticProvider(LatticeStatisticProvider provider) {
+ super(provider);
+ }
+
+ /** Returns an estimate of the number of distinct values in a column. */
+ public int cardinality(Lattice lattice, Lattice.Column column) {
+ final Integer integer = CARDINALITY_MAP.get(column.alias);
+ if (integer != null && integer > 0) {
+ return integer;
+ }
+ return column.alias.length();
+ }
+}
+
+// End FoodMartLatticeStatisticProvider.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/4cc539fc/core/src/test/java/org/apache/calcite/test/LatticeTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/LatticeTest.java b/core/src/test/java/org/apache/calcite/test/LatticeTest.java
index 492b377..b4a79af 100644
--- a/core/src/test/java/org/apache/calcite/test/LatticeTest.java
+++ b/core/src/test/java/org/apache/calcite/test/LatticeTest.java
@@ -16,6 +16,7 @@
*/
package org.apache.calcite.test;
+import org.apache.calcite.materialize.Lattices;
import org.apache.calcite.materialize.MaterializationService;
import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.rel.RelNode;
@@ -309,10 +310,25 @@ public class LatticeTest {
* tiles.
*
* <p>Test case for
- * <a href="https://issues.apache.org/jira/browse/CALCITE-428">CALCITE-428,
- * "Use optimization algorithm to suggest which tiles of a lattice to
- * materialize"</a>. */
+ * <a href="https://issues.apache.org/jira/browse/CALCITE-428">[CALCITE-428]
+ * Use optimization algorithm to suggest which tiles of a lattice to
+ * materialize</a>. */
@Test public void testTileAlgorithm() {
+ checkTileAlgorithm(FoodMartLatticeStatisticProvider.class.getCanonicalName(),
+ "EnumerableAggregate(group=[{2, 3}])\n"
+ + " EnumerableTableScan(table=[[adhoc, m{16, 17, 27, 31}]])");
+ }
+
+ @Test public void testTileAlgorithm2() {
+ // Different explain than above, but note that it still selects columns
+ // (27, 31).
+ checkTileAlgorithm(Lattices.class.getCanonicalName() + "#CACHED_SQL",
+ "EnumerableAggregate(group=[{0, 1}])\n"
+ + " EnumerableTableScan(table=[[adhoc, m{27, 31, 32, 36, 37}]");
+ }
+
+ private void checkTileAlgorithm(String statisticProvider,
+ String expectedExplain) {
MaterializationService.setThreadLocal();
MaterializationService.instance().clear();
foodmartModel(
@@ -329,6 +345,9 @@ public class LatticeTest {
+ " }, {\n"
+ " agg: 'count'\n"
+ " } ],\n"
+ + " statisticProvider: '"
+ + statisticProvider
+ + "',\n"
+ " tiles: [ {\n"
+ " dimensions: [ 'the_year', ['t', 'quarter'] ],\n"
+ " measures: [ ]\n"
@@ -337,8 +356,7 @@ public class LatticeTest {
+ "from \"foodmart\".\"sales_fact_1997\" as s\n"
+ "join \"foodmart\".\"time_by_day\" as t using (\"time_id\")\n")
.enableMaterializations(true)
- .explainContains("EnumerableAggregate(group=[{2, 3}])\n"
- + " EnumerableTableScan(table=[[adhoc, m{16, 17, 27, 31}]])")
+ .explainContains(expectedExplain)
.returnsUnordered("the_year=1997; quarter=Q1",
"the_year=1997; quarter=Q2",
"the_year=1997; quarter=Q3",
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/4cc539fc/site/_docs/model.md
----------------------------------------------------------------------
diff --git a/site/_docs/model.md b/site/_docs/model.md
index 78061b0..a6514a3 100644
--- a/site/_docs/model.md
+++ b/site/_docs/model.md
@@ -21,6 +21,7 @@ See the License for the specific language governing permissions and
limitations under the License.
{% endcomment %}
-->
+{% assign apiRoot = "/apidocs" %}
Calcite models can be represented as JSON files.
This page describes the structure of those files.
@@ -148,7 +149,8 @@ Like base class <a href="#schema">Schema</a>, occurs within `root.schemas`.
<a href="#schema">Schema</a>.
`factory` (required string) is the name of the factory class for this
-schema. Must implement interface `org.apache.calcite.schema.SchemaFactory`
+schema. Must implement interface
+[org.apache.calcite.schema.SchemaFactory]({{ apiRoot }}/org/apache/calcite/schema/SchemaFactory.html)
and have a public default constructor.
`operand` (optional map) contains attributes to be passed to the
@@ -293,7 +295,8 @@ Like base class <a href="#table">Table</a>, occurs within `root.schemas.tables`.
`name`, `type`, `columns` inherited from <a href="#table">Table</a>.
`factory` (required string) is the name of the factory class for this
-table. Must implement interface `org.apache.calcite.schema.TableFactory`
+table. Must implement interface
+[org.apache.calcite.schema.TableFactory]({{ apiRoot }}/org/apache/calcite/schema/TableFactory.html)
and have a public default constructor.
`operand` (optional map) contains attributes to be passed to the
@@ -401,6 +404,16 @@ just 'count(*)':
[ { name: 'count' } ]
{% endhighlight %}
+`statisticProvider` (optional name of a class that implements
+[org.apache.calcite.materialize.LatticeStatisticProvider]({{ apiRoot }}/org/apache/calcite/materialize/LatticeStatisticProvider.html))
+is provides estimates of the number of distinct values * in each column.
+
+You can use a class name, or a class plus a static field, for example
+`org.apache.calcite.materialize.Lattices#CACHING_SQL_STATISTIC_PROVIDER`.
+
+If not set, Calcite will generate and execute a SQL query to find the real
+value, and cache the results.
+
See also: <a href="lattice.md">Lattices</a>.
### Tile
[3/7] incubator-calcite git commit: Test case for [CALCITE-754]
Validator error when resolving OVER clause of JOIN query (Hsuan-Yi Chu)
Posted by jh...@apache.org.
Test case for [CALCITE-754] Validator error when resolving OVER clause of JOIN query (Hsuan-Yi Chu)
Close apache/incubator-calcite#93
Project: http://git-wip-us.apache.org/repos/asf/incubator-calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-calcite/commit/ebce955d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-calcite/tree/ebce955d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-calcite/diff/ebce955d
Branch: refs/heads/master
Commit: ebce955d700602720882aa01b6ddead9ab10bde0
Parents: 4cc539f
Author: Hsuan-Yi Chu <hs...@usc.edu>
Authored: Mon Jun 8 15:04:54 2015 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Thu Jun 11 23:10:30 2015 -0700
----------------------------------------------------------------------
.../org/apache/calcite/test/SqlValidatorTest.java | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/ebce955d/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
index 2bf64c7..4b7c1f8 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
@@ -4259,6 +4259,22 @@ public class SqlValidatorTest extends SqlValidatorTestCase {
"Column 'HIREDATE' not found in any table");
}
+ /** Test case for
+ * <a href="https://issues.apache.org/jira/browse/CALCITE-754">[CALCITE-754]
+ * Validator error when resolving OVER clause of JOIN query</a>. */
+ @Ignore
+ @Test public void testPartitionByColumnInJoinAlias() {
+ sql("select sum(1) over(partition by t1.ename) \n"
+ + "from emp t1, emp t2")
+ .ok();
+ sql("select sum(1) over(partition by emp.ename) \n"
+ + "from emp, dept")
+ .ok();
+ sql("select sum(1) over(partition by ^deptno^) \n"
+ + "from emp, dept")
+ .fails("Column 'DEPTNO' is ambiguous");
+ }
+
@Test public void testWindowNegative() {
// Do not fail when window has negative size. Allow
final String negSize = null;
[4/7] incubator-calcite git commit: Remove deprecated SqlTypeName
methods
Posted by jh...@apache.org.
Remove deprecated SqlTypeName methods
Project: http://git-wip-us.apache.org/repos/asf/incubator-calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-calcite/commit/67189631
Tree: http://git-wip-us.apache.org/repos/asf/incubator-calcite/tree/67189631
Diff: http://git-wip-us.apache.org/repos/asf/incubator-calcite/diff/67189631
Branch: refs/heads/master
Commit: 6718963132e8984877c379bc5fc95534b31022e4
Parents: 87acda3
Author: Julian Hyde <jh...@apache.org>
Authored: Thu Jun 11 22:55:39 2015 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Thu Jun 11 23:46:07 2015 -0700
----------------------------------------------------------------------
.../apache/calcite/sql/type/SqlTypeName.java | 42 --------------------
.../apache/calcite/test/SqlValidatorTest.java | 9 +++--
2 files changed, 5 insertions(+), 46 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/67189631/core/src/main/java/org/apache/calcite/sql/type/SqlTypeName.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/type/SqlTypeName.java b/core/src/main/java/org/apache/calcite/sql/type/SqlTypeName.java
index a7f6880..5f5b90c 100644
--- a/core/src/main/java/org/apache/calcite/sql/type/SqlTypeName.java
+++ b/core/src/main/java/org/apache/calcite/sql/type/SqlTypeName.java
@@ -17,7 +17,6 @@
package org.apache.calcite.sql.type;
import org.apache.calcite.avatica.util.DateTimeUtils;
-import org.apache.calcite.rel.type.RelDataTypeSystem;
import org.apache.calcite.sql.SqlLiteral;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.util.Util;
@@ -299,18 +298,6 @@ public enum SqlTypeName {
}
/**
- * Returns the default precision for this type if supported, otherwise -1 if
- * precision is either unsupported or must be specified explicitly.
- *
- * @deprecated Use
- * {@link org.apache.calcite.rel.type.RelDataTypeSystem#getDefaultPrecision(SqlTypeName)};
- * will be removed after calcite-0.9.1.
- */
- public int getDefaultPrecision() {
- return RelDataTypeSystem.DEFAULT.getDefaultPrecision(this);
- }
-
- /**
* @return default scale for this type if supported, otherwise -1 if scale
* is either unsupported or must be specified explicitly
*/
@@ -676,35 +663,6 @@ public enum SqlTypeName {
}
/**
- * Returns the maximum precision (or length) allowed for this type, or -1 if
- * precision/length are not applicable for this type.
- *
- * @return Maximum allowed precision
- *
- * @deprecated Use
- * {@link org.apache.calcite.rel.type.RelDataTypeSystem#getMaxScale(SqlTypeName)};
- * will be removed after calcite-0.9.1.
- */
- public int getMaxPrecision() {
- return RelDataTypeSystem.DEFAULT.getMaxPrecision(this);
- }
-
- /**
- * Returns the maximum scale (or fractional second precision in the case of
- * intervals) allowed for this type, or -1 if precision/length are not
- * applicable for this type.
- *
- * @return Maximum allowed scale
- *
- * @deprecated Use
- * {@link org.apache.calcite.rel.type.RelDataTypeSystem#getMaxScale(SqlTypeName)};
- * will be removed after calcite-0.9.1.
- */
- public int getMaxScale() {
- return RelDataTypeSystem.DEFAULT.getMaxScale(this);
- }
-
- /**
* Returns the minimum precision (or length) allowed for this type, or -1 if
* precision/length are not applicable for this type.
*
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/67189631/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
index af82649..811343b 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
@@ -3430,10 +3430,11 @@ public class SqlValidatorTest extends SqlValidatorTestCase {
SqlTypeName.INTERVAL_YEAR_MONTH.getMinPrecision() == 1);
assertTrue(
SqlTypeName.INTERVAL_DAY_TIME.getMinPrecision() == 1);
- assertTrue(
- SqlTypeName.INTERVAL_YEAR_MONTH.getMaxPrecision() == 10);
- assertTrue(
- SqlTypeName.INTERVAL_DAY_TIME.getMaxPrecision() == 10);
+ final RelDataTypeSystem defTypeSystem = RelDataTypeSystem.DEFAULT;
+ assertEquals(10,
+ defTypeSystem.getMaxPrecision(SqlTypeName.INTERVAL_YEAR_MONTH));
+ assertEquals(10,
+ defTypeSystem.getMaxPrecision(SqlTypeName.INTERVAL_DAY_TIME));
assertEquals(2,
typeSystem.getDefaultPrecision(SqlTypeName.INTERVAL_YEAR_MONTH));
assertEquals(2,
[6/7] incubator-calcite git commit: Fix coverity warnings
Posted by jh...@apache.org.
Fix coverity warnings
Project: http://git-wip-us.apache.org/repos/asf/incubator-calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-calcite/commit/2b217657
Tree: http://git-wip-us.apache.org/repos/asf/incubator-calcite/tree/2b217657
Diff: http://git-wip-us.apache.org/repos/asf/incubator-calcite/diff/2b217657
Branch: refs/heads/master
Commit: 2b2176577c9c36466772eee8636dca159bcc5d9a
Parents: 6718963
Author: Julian Hyde <jh...@apache.org>
Authored: Thu Jun 11 23:12:26 2015 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Thu Jun 11 23:46:07 2015 -0700
----------------------------------------------------------------------
.../src/main/java/org/apache/calcite/schema/Schemas.java | 11 ++++++++++-
.../main/java/org/apache/calcite/tools/RelBuilder.java | 5 +++--
2 files changed, 13 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2b217657/core/src/main/java/org/apache/calcite/schema/Schemas.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/schema/Schemas.java b/core/src/main/java/org/apache/calcite/schema/Schemas.java
index 7c09ffb..aa53419 100644
--- a/core/src/main/java/org/apache/calcite/schema/Schemas.java
+++ b/core/src/main/java/org/apache/calcite/schema/Schemas.java
@@ -473,9 +473,18 @@ public final class Schemas {
}
}
+ /** Returns a sub-schema of a given schema obtained by following a sequence
+ * of names.
+ *
+ * <p>The result is null if the initial schema is null or any sub-schema does
+ * not exist.
+ */
public static CalciteSchema subSchema(CalciteSchema schema,
- List<String> names) {
+ Iterable<String> names) {
for (String string : names) {
+ if (schema == null) {
+ return null;
+ }
schema = schema.getSubSchema(string, false);
}
return schema;
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2b217657/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/tools/RelBuilder.java b/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
index ce185d8..f664baf 100644
--- a/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
+++ b/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
@@ -864,14 +864,15 @@ public class RelBuilder {
}
final RexNode offsetNode = offset <= 0 ? null : literal(offset);
final RexNode fetchNode = fetch < 0 ? null : literal(fetch);
- if (extraNodes.size() > inputRowType.getFieldCount()) {
+ final boolean addedFields = extraNodes.size() > originalExtraNodes.size();
+ if (addedFields) {
project(extraNodes);
}
final RelNode sort =
sortFactory.createSort(build(), RelCollations.of(fieldCollations),
offsetNode, fetchNode);
push(sort);
- if (extraNodes.size() > inputRowType.getFieldCount()) {
+ if (addedFields) {
project(originalExtraNodes);
}
return this;
[5/7] incubator-calcite git commit: [CALCITE-754] Validator error
when resolving OVER clause of JOIN query
Posted by jh...@apache.org.
[CALCITE-754] Validator error when resolving OVER clause of JOIN query
Project: http://git-wip-us.apache.org/repos/asf/incubator-calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-calcite/commit/87acda31
Tree: http://git-wip-us.apache.org/repos/asf/incubator-calcite/tree/87acda31
Diff: http://git-wip-us.apache.org/repos/asf/incubator-calcite/diff/87acda31
Branch: refs/heads/master
Commit: 87acda3179d6a5536f8af1506d5048ef06aeb591
Parents: ebce955
Author: Julian Hyde <jh...@apache.org>
Authored: Thu Jun 11 22:52:47 2015 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Thu Jun 11 23:46:07 2015 -0700
----------------------------------------------------------------------
.../java/org/apache/calcite/sql/SqlNode.java | 5 +-
.../java/org/apache/calcite/sql/SqlWindow.java | 32 ++-------
.../apache/calcite/sql/fun/SqlCastFunction.java | 72 ++++++--------------
.../calcite/sql/validate/SelectNamespace.java | 2 +-
.../calcite/sql/validate/SqlValidatorImpl.java | 18 +----
.../calcite/sql/validate/SqlValidatorUtil.java | 39 +++++++++++
.../calcite/sql2rel/SqlToRelConverter.java | 1 +
.../apache/calcite/test/SqlValidatorTest.java | 1 -
8 files changed, 72 insertions(+), 98 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/87acda31/core/src/main/java/org/apache/calcite/sql/SqlNode.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlNode.java b/core/src/main/java/org/apache/calcite/sql/SqlNode.java
index 6708ba5..6531114 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlNode.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlNode.java
@@ -105,6 +105,7 @@ public abstract class SqlNode implements Cloneable {
return getKind().belongsTo(category);
}
+ @Deprecated // to be removed before 2.0
public static SqlNode[] cloneArray(SqlNode[] nodes) {
SqlNode[] clones = nodes.clone();
for (int i = 0; i < clones.length; i++) {
@@ -279,11 +280,13 @@ public abstract class SqlNode implements Cloneable {
/**
* Returns whether expression is always ascending, descending or constant.
- * This property is useful because it allows to safely aggregte infinite
+ * This property is useful because it allows to safely aggregate infinite
* streams of values.
*
* <p>The default implementation returns
* {@link SqlMonotonicity#NOT_MONOTONIC}.
+ *
+ * @param scope Scope
*/
public SqlMonotonicity getMonotonicity(SqlValidatorScope scope) {
return SqlMonotonicity.NOT_MONOTONIC;
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/87acda31/core/src/main/java/org/apache/calcite/sql/SqlWindow.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlWindow.java b/core/src/main/java/org/apache/calcite/sql/SqlWindow.java
index afc6b45..a8ae456 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlWindow.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlWindow.java
@@ -24,16 +24,14 @@ import org.apache.calcite.sql.type.ReturnTypes;
import org.apache.calcite.sql.type.SqlTypeFamily;
import org.apache.calcite.sql.util.SqlBasicVisitor;
import org.apache.calcite.sql.util.SqlVisitor;
-import org.apache.calcite.sql.validate.SqlMoniker;
-import org.apache.calcite.sql.validate.SqlMonotonicity;
import org.apache.calcite.sql.validate.SqlValidator;
import org.apache.calcite.sql.validate.SqlValidatorScope;
+import org.apache.calcite.sql.validate.SqlValidatorUtil;
import org.apache.calcite.util.ImmutableNullableList;
import org.apache.calcite.util.Util;
import com.google.common.collect.ImmutableList;
-import java.util.ArrayList;
import java.util.List;
import static org.apache.calcite.util.Static.RESOURCE;
@@ -329,28 +327,6 @@ public class SqlWindow extends SqlCall {
}
}
- /**
- * This method retrieves the list of columns for the current table then
- * walks through the list looking for a column that is monotonic (sorted)
- */
- static boolean isTableSorted(SqlValidatorScope scope) {
- List<SqlMoniker> columnNames = new ArrayList<SqlMoniker>();
-
- // REVIEW: jhyde, 2007/11/7: This is the only use of
- // findAllColumnNames. Find a better way to detect monotonicity, then
- // remove that method.
- scope.findAllColumnNames(columnNames);
- for (SqlMoniker columnName : columnNames) {
- SqlIdentifier columnId = columnName.toIdentifier();
- final SqlMonotonicity monotonicity =
- scope.getMonotonicity(columnId);
- if (monotonicity != SqlMonotonicity.NOT_MONOTONIC) {
- return true;
- }
- }
- return false;
- }
-
public static SqlNode createCurrentRow(SqlParserPos pos) {
return Bound.CURRENT_ROW.symbol(pos);
}
@@ -564,7 +540,7 @@ public class SqlWindow extends SqlCall {
// 6.10 rule 6a Function RANK & DENSE_RANK require ORDER BY clause
if (orderList.size() == 0
- && !SqlWindow.isTableSorted(scope)
+ && !SqlValidatorUtil.containsMonotonic(scope)
&& windowCall != null
&& windowCall.getOperator().requiresOrder()) {
throw validator.newValidationError(this, RESOURCE.funcNeedsOrderBy());
@@ -596,7 +572,7 @@ public class SqlWindow extends SqlCall {
// requires an ORDER BY clause if frame is logical(RANGE)
// We relax this requirement if the table appears to be
// sorted already
- if (!isRows() && !SqlWindow.isTableSorted(scope)) {
+ if (!isRows() && !SqlValidatorUtil.containsMonotonic(scope)) {
throw validator.newValidationError(this,
RESOURCE.overMissingOrderBy());
}
@@ -619,7 +595,7 @@ public class SqlWindow extends SqlCall {
// Validate across boundaries. 7.10 Rule 8 a-d
checkSpecialLiterals(this, validator);
} else if (orderList.size() == 0
- && !SqlWindow.isTableSorted(scope)
+ && !SqlValidatorUtil.containsMonotonic(scope)
&& windowCall != null
&& windowCall.getOperator().requiresOrder()) {
throw validator.newValidationError(this, RESOURCE.overMissingOrderBy());
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/87acda31/core/src/main/java/org/apache/calcite/sql/fun/SqlCastFunction.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlCastFunction.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlCastFunction.java
index 7c7c7c4..08bd3b3 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlCastFunction.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlCastFunction.java
@@ -39,7 +39,8 @@ import org.apache.calcite.sql.type.SqlTypeUtil;
import org.apache.calcite.sql.validate.SqlMonotonicity;
import org.apache.calcite.sql.validate.SqlValidatorScope;
-import java.util.HashSet;
+import com.google.common.collect.ImmutableSet;
+
import java.util.Set;
import static org.apache.calcite.util.Static.RESOURCE;
@@ -74,56 +75,25 @@ public class SqlCastFunction extends SqlFunction {
* List all casts that do not preserve monotonicity.
*/
private Set<TypeFamilyCast> createNonMonotonicPreservingCasts() {
- Set<TypeFamilyCast> result = new HashSet<TypeFamilyCast>();
- result.add(
- new TypeFamilyCast(
- SqlTypeFamily.EXACT_NUMERIC,
- SqlTypeFamily.CHARACTER));
- result.add(
- new TypeFamilyCast(
- SqlTypeFamily.NUMERIC,
- SqlTypeFamily.CHARACTER));
- result.add(
- new TypeFamilyCast(
- SqlTypeFamily.APPROXIMATE_NUMERIC,
- SqlTypeFamily.CHARACTER));
- result.add(
- new TypeFamilyCast(
- SqlTypeFamily.DATETIME_INTERVAL,
- SqlTypeFamily.CHARACTER));
- result.add(
- new TypeFamilyCast(
- SqlTypeFamily.CHARACTER,
- SqlTypeFamily.EXACT_NUMERIC));
- result.add(
- new TypeFamilyCast(
- SqlTypeFamily.CHARACTER,
- SqlTypeFamily.NUMERIC));
- result.add(
- new TypeFamilyCast(
- SqlTypeFamily.CHARACTER,
- SqlTypeFamily.APPROXIMATE_NUMERIC));
- result.add(
- new TypeFamilyCast(
- SqlTypeFamily.CHARACTER,
- SqlTypeFamily.DATETIME_INTERVAL));
- result.add(
- new TypeFamilyCast(
- SqlTypeFamily.DATETIME,
- SqlTypeFamily.TIME));
- result.add(
- new TypeFamilyCast(
- SqlTypeFamily.TIMESTAMP,
- SqlTypeFamily.TIME));
- result.add(
- new TypeFamilyCast(
- SqlTypeFamily.TIME,
- SqlTypeFamily.DATETIME));
- result.add(
- new TypeFamilyCast(
- SqlTypeFamily.TIME,
- SqlTypeFamily.TIMESTAMP));
- return result;
+ ImmutableSet.Builder<TypeFamilyCast> builder = ImmutableSet.builder();
+ add(builder, SqlTypeFamily.EXACT_NUMERIC, SqlTypeFamily.CHARACTER);
+ add(builder, SqlTypeFamily.NUMERIC, SqlTypeFamily.CHARACTER);
+ add(builder, SqlTypeFamily.APPROXIMATE_NUMERIC, SqlTypeFamily.CHARACTER);
+ add(builder, SqlTypeFamily.DATETIME_INTERVAL, SqlTypeFamily.CHARACTER);
+ add(builder, SqlTypeFamily.CHARACTER, SqlTypeFamily.EXACT_NUMERIC);
+ add(builder, SqlTypeFamily.CHARACTER, SqlTypeFamily.NUMERIC);
+ add(builder, SqlTypeFamily.CHARACTER, SqlTypeFamily.APPROXIMATE_NUMERIC);
+ add(builder, SqlTypeFamily.CHARACTER, SqlTypeFamily.DATETIME_INTERVAL);
+ add(builder, SqlTypeFamily.DATETIME, SqlTypeFamily.TIME);
+ add(builder, SqlTypeFamily.TIMESTAMP, SqlTypeFamily.TIME);
+ add(builder, SqlTypeFamily.TIME, SqlTypeFamily.DATETIME);
+ add(builder, SqlTypeFamily.TIME, SqlTypeFamily.TIMESTAMP);
+ return builder.build();
+ }
+
+ private void add(ImmutableSet.Builder<TypeFamilyCast> result,
+ SqlTypeFamily from, SqlTypeFamily to) {
+ result.add(new TypeFamilyCast(from, to));
}
private boolean isMonotonicPreservingCast(
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/87acda31/core/src/main/java/org/apache/calcite/sql/validate/SelectNamespace.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SelectNamespace.java b/core/src/main/java/org/apache/calcite/sql/validate/SelectNamespace.java
index a0e0ad2..48a45c1 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/SelectNamespace.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/SelectNamespace.java
@@ -52,7 +52,7 @@ public class SelectNamespace extends AbstractNamespace {
//~ Methods ----------------------------------------------------------------
// implement SqlValidatorNamespace, overriding return type
- public SqlSelect getNode() {
+ @Override public SqlSelect getNode() {
return select;
}
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/87acda31/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java
index 4a47c78..f210749 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java
@@ -3033,7 +3033,8 @@ public class SqlValidatorImpl implements SqlValidatorWithHints {
switch (modality) {
case STREAM:
SqlNodeList groupList = select.getGroup();
- if (groupList == null || !containsMonotonic(scope, groupList)) {
+ if (groupList == null
+ || !SqlValidatorUtil.containsMonotonic(scope, groupList)) {
if (fail) {
throw newValidationError(aggregateNode,
Static.RESOURCE.streamMustGroupByMonotonic());
@@ -3087,21 +3088,6 @@ public class SqlValidatorImpl implements SqlValidatorWithHints {
}
}
- private static boolean containsMonotonic(SelectScope scope,
- SqlNodeList nodes) {
- for (SqlNode node : nodes) {
- final SqlMonotonicity monotonicity = scope.getMonotonicity(node);
- switch (monotonicity) {
- case CONSTANT:
- case NOT_MONOTONIC:
- break;
- default:
- return true;
- }
- }
- return false;
- }
-
protected void validateWindowClause(SqlSelect select) {
final SqlNodeList windowList = select.getWindowList();
if ((windowList == null) || (windowList.size() == 0)) {
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/87acda31/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java
index 768852e..3ddeed4 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java
@@ -571,6 +571,45 @@ public class SqlValidatorUtil {
return ImmutableList.copyOf(flattenedBitSets);
}
+ /**
+ * Returns whether there are any input columns that are sorted.
+ *
+ * <p>If so, it can be the default ORDER BY clause for a WINDOW specification.
+ * (This is an extension to the SQL standard for streaming.)
+ */
+ public static boolean containsMonotonic(SqlValidatorScope scope) {
+ for (SqlValidatorNamespace ns : children(scope)) {
+ ns = ns.resolve();
+ for (String field : ns.getRowType().getFieldNames()) {
+ if (!ns.getMonotonicity(field).mayRepeat()) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private static List<SqlValidatorNamespace> children(SqlValidatorScope scope) {
+ return scope instanceof ListScope
+ ? ((ListScope) scope).getChildren()
+ : ImmutableList.<SqlValidatorNamespace>of();
+ }
+
+ /**
+ * Returns whether any of the given expressions are sorted.
+ *
+ * <p>If so, it can be the default ORDER BY clause for a WINDOW specification.
+ * (This is an extension to the SQL standard for streaming.)
+ */
+ static boolean containsMonotonic(SelectScope scope, SqlNodeList nodes) {
+ for (SqlNode node : nodes) {
+ if (!scope.getMonotonicity(node).mayRepeat()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
//~ Inner Classes ----------------------------------------------------------
/**
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/87acda31/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
index a190159..ec36ad8 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
@@ -3483,6 +3483,7 @@ public class SqlToRelConverter {
for (int i = 0; i < joinList.size(); i++) {
Object o = joinList.get(i);
if (o instanceof List) {
+ @SuppressWarnings("unchecked")
List<SqlNode> projectList = (List<SqlNode>) o;
final List<RexNode> selectList = new ArrayList<>();
final List<String> fieldNameList = new ArrayList<>();
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/87acda31/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
index 4b7c1f8..af82649 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
@@ -4262,7 +4262,6 @@ public class SqlValidatorTest extends SqlValidatorTestCase {
/** Test case for
* <a href="https://issues.apache.org/jira/browse/CALCITE-754">[CALCITE-754]
* Validator error when resolving OVER clause of JOIN query</a>. */
- @Ignore
@Test public void testPartitionByColumnInJoinAlias() {
sql("select sum(1) over(partition by t1.ename) \n"
+ "from emp t1, emp t2")