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 2018/06/26 05:41:44 UTC
[2/3] calcite git commit: Fix-up for [CALCITE-2345] and [CALCITE-2347]
http://git-wip-us.apache.org/repos/asf/calcite/blob/6e8bb5a1/elasticsearch5/src/test/java/org/apache/calcite/adapter/elasticsearch5/Elasticsearch5AdapterTest.java
----------------------------------------------------------------------
diff --git a/elasticsearch5/src/test/java/org/apache/calcite/adapter/elasticsearch5/Elasticsearch5AdapterTest.java b/elasticsearch5/src/test/java/org/apache/calcite/adapter/elasticsearch5/Elasticsearch5AdapterTest.java
new file mode 100644
index 0000000..9dedbda
--- /dev/null
+++ b/elasticsearch5/src/test/java/org/apache/calcite/adapter/elasticsearch5/Elasticsearch5AdapterTest.java
@@ -0,0 +1,405 @@
+/*
+ * 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.adapter.elasticsearch5;
+
+import org.apache.calcite.jdbc.CalciteConnection;
+import org.apache.calcite.schema.SchemaPlus;
+import org.apache.calcite.schema.impl.ViewTable;
+import org.apache.calcite.schema.impl.ViewTableMacro;
+import org.apache.calcite.test.CalciteAssert;
+import org.apache.calcite.test.ElasticsearchChecker;
+
+import com.google.common.io.LineProcessor;
+import com.google.common.io.Resources;
+
+import org.elasticsearch.action.bulk.BulkItemResponse;
+import org.elasticsearch.action.bulk.BulkRequestBuilder;
+import org.elasticsearch.action.bulk.BulkResponse;
+import org.elasticsearch.action.support.WriteRequest;
+import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.common.xcontent.XContentFactory;
+import org.elasticsearch.common.xcontent.XContentType;
+
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Locale;
+
+/**
+ * Set of tests for the Elasticsearch 5 adapter.
+ *
+ * <p>Uses a real instance via {@link EmbeddedElasticsearchPolicy}.
+ * The document source is a local {@code zips-mini.json} file
+ * (located in the classpath).
+ */
+public class Elasticsearch5AdapterTest {
+
+ @ClassRule // init once for all tests
+ public static final EmbeddedElasticsearchPolicy POLICY =
+ EmbeddedElasticsearchPolicy.create();
+
+ private static final String ZIPS = "zips";
+
+ /**
+ * Used to create {@code zips} index and insert some data
+ *
+ * @throws Exception when ES instance setup failed
+ */
+ @BeforeClass
+ public static void setupInstance() throws Exception {
+ // define mapping so fields are searchable (term query)
+ XContentBuilder mapping = XContentFactory.jsonBuilder().startObject()
+ .startObject("properties")
+ .startObject("city").field("type", "string")
+ .field("index", "not_analyzed").endObject()
+ .startObject("state").field("type", "string")
+ .field("index", "not_analyzed").endObject()
+ .startObject("pop").field("type", "long").endObject()
+ .endObject()
+ .endObject();
+
+ // create index
+ POLICY.client().admin().indices()
+ .prepareCreate(ZIPS)
+ .addMapping(ZIPS, mapping)
+ .get();
+
+ BulkRequestBuilder bulk = POLICY.client().prepareBulk()
+ .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
+
+ // load records from file
+ Resources.readLines(Elasticsearch5AdapterTest.class.getResource("/zips-mini.json"),
+ StandardCharsets.UTF_8, new LineProcessor<Void>() {
+ @Override public boolean processLine(String line) throws IOException {
+ line = line.replaceAll("_id", "id"); // _id is a reserved attribute in ES
+ bulk.add(POLICY.client().prepareIndex(ZIPS, ZIPS)
+ .setSource(line.getBytes(StandardCharsets.UTF_8), XContentType.JSON));
+ return true;
+ }
+
+ @Override public Void getResult() {
+ return null;
+ }
+ });
+
+ if (bulk.numberOfActions() == 0) {
+ throw new IllegalStateException("No records to be indexed");
+ }
+
+ BulkResponse response = bulk.execute().get();
+
+ if (response.hasFailures()) {
+ throw new IllegalStateException(
+ String.format(Locale.getDefault(), "Failed to populate %s:\n%s", POLICY.httpAddress(),
+ Arrays.stream(response.getItems()).filter(BulkItemResponse::isFailed)
+ .map(BulkItemResponse::getFailureMessage).findFirst().orElse("<unknown>")));
+ }
+
+ }
+
+ private CalciteAssert.ConnectionFactory newConnectionFactory() {
+ return new CalciteAssert.ConnectionFactory() {
+ @Override public Connection createConnection() throws SQLException {
+ final Connection connection = DriverManager.getConnection("jdbc:calcite:");
+ final SchemaPlus root = connection.unwrap(CalciteConnection.class).getRootSchema();
+
+ root.add("elastic", new Elasticsearch5Schema(POLICY.client(), ZIPS));
+
+ // add calcite view programmatically
+ final String viewSql = "select cast(_MAP['city'] AS varchar(20)) AS \"city\", "
+ + " cast(_MAP['loc'][0] AS float) AS \"longitude\",\n"
+ + " cast(_MAP['loc'][1] AS float) AS \"latitude\",\n"
+ + " cast(_MAP['pop'] AS integer) AS \"pop\", "
+ + " cast(_MAP['state'] AS varchar(2)) AS \"state\", "
+ + " cast(_MAP['id'] AS varchar(5)) AS \"id\" "
+ + "from \"elastic\".\"zips\"";
+
+ ViewTableMacro macro = ViewTable.viewMacro(root, viewSql,
+ Collections.singletonList("elastic"), Arrays.asList("elastic", "view"), false);
+ root.add("ZIPS", macro);
+
+ return connection;
+ }
+ };
+ }
+
+ private CalciteAssert.AssertThat calciteAssert() {
+ return CalciteAssert.that()
+ .with(newConnectionFactory());
+ }
+
+ /**
+ * Tests using calcite view
+ */
+ @Test
+ public void view() {
+ calciteAssert()
+ .query("select * from zips where \"city\" = 'BROOKLYN'")
+ .returns("city=BROOKLYN; longitude=-73.956985; latitude=40.646694; "
+ + "pop=111396; state=NY; id=11226\n")
+ .returnsCount(1);
+ }
+
+ @Test
+ public void emptyResult() {
+ CalciteAssert.that()
+ .with(newConnectionFactory())
+ .query("select * from zips limit 0")
+ .returnsCount(0);
+
+ CalciteAssert.that()
+ .with(newConnectionFactory())
+ .query("select * from \"elastic\".\"zips\" where _MAP['Foo'] = '_MISSING_'")
+ .returnsCount(0);
+ }
+
+ @Test
+ public void basic() throws Exception {
+ CalciteAssert.that()
+ .with(newConnectionFactory())
+ .query("select * from \"elastic\".\"zips\" where _MAP['city'] = 'BROOKLYN'")
+ .returnsCount(1);
+
+ CalciteAssert.that()
+ .with(newConnectionFactory())
+ .query("select * from \"elastic\".\"zips\" where"
+ + " _MAP['city'] in ('BROOKLYN', 'WASHINGTON')")
+ .returnsCount(2);
+
+ // lower-case
+ CalciteAssert.that()
+ .with(newConnectionFactory())
+ .query("select * from \"elastic\".\"zips\" where "
+ + "_MAP['city'] in ('brooklyn', 'Brooklyn', 'BROOK') ")
+ .returnsCount(0);
+
+ // missing field
+ CalciteAssert.that()
+ .with(newConnectionFactory())
+ .query("select * from \"elastic\".\"zips\" where _MAP['CITY'] = 'BROOKLYN'")
+ .returnsCount(0);
+
+ // limit works
+ CalciteAssert.that()
+ .with(newConnectionFactory())
+ .query("select * from \"elastic\".\"zips\" limit 42")
+ .returnsCount(42);
+
+ }
+
+ @Test public void testSort() {
+ final String explain = "PLAN=ElasticsearchToEnumerableConverter\n"
+ + " ElasticsearchSort(sort0=[$4], dir0=[ASC])\n"
+ + " ElasticsearchProject(city=[CAST(ITEM($0, 'city')):VARCHAR(20) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\"], longitude=[CAST(ITEM(ITEM($0, 'loc'), 0)):FLOAT], latitude=[CAST(ITEM(ITEM($0, 'loc'), 1)):FLOAT], pop=[CAST(ITEM($0, 'pop')):INTEGER], state=[CAST(ITEM($0, 'state')):VARCHAR(2) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\"], id=[CAST(ITEM($0, 'id')):VARCHAR(5) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\"])\n"
+ + " ElasticsearchTableScan(table=[[elastic, zips]])";
+
+ calciteAssert()
+ .query("select * from zips order by \"state\"")
+ .returnsCount(10)
+ .explainContains(explain);
+ }
+
+ @Test public void testSortLimit() {
+ final String sql = "select \"state\", \"pop\" from zips\n"
+ + "order by \"state\", \"pop\" offset 2 rows fetch next 3 rows only";
+ calciteAssert()
+ .query(sql)
+ .returnsUnordered("state=AK; pop=32383",
+ "state=AL; pop=42124",
+ "state=AL; pop=43862")
+ .queryContains(
+ ElasticsearchChecker.elasticsearchChecker(
+ "\"_source\" : [\"state\", \"pop\"]",
+ "\"sort\": [ {\"state\": \"asc\"}, {\"pop\": \"asc\"}]",
+ "\"from\": 2",
+ "\"size\": 3"));
+ }
+
+
+
+ @Test public void testOffsetLimit() {
+ final String sql = "select \"state\", \"id\" from zips\n"
+ + "offset 2 fetch next 3 rows only";
+ calciteAssert()
+ .query(sql)
+ .runs()
+ .queryContains(
+ ElasticsearchChecker.elasticsearchChecker(
+ "\"from\": 2",
+ "\"size\": 3",
+ "\"_source\" : [\"state\", \"id\"]"));
+ }
+
+ @Test public void testLimit() {
+ final String sql = "select \"state\", \"id\" from zips\n"
+ + "fetch next 3 rows only";
+
+ calciteAssert()
+ .query(sql)
+ .runs()
+ .queryContains(
+ ElasticsearchChecker.elasticsearchChecker(
+ "\"size\": 3",
+ "\"_source\" : [\"state\", \"id\"]"));
+ }
+
+ @Test public void testFilterSort() {
+ final String sql = "select * from zips\n"
+ + "where \"state\" = 'CA' and \"pop\" >= 94000\n"
+ + "order by \"state\", \"pop\"";
+ final String explain = "PLAN=ElasticsearchToEnumerableConverter\n"
+ + " ElasticsearchSort(sort0=[$4], sort1=[$3], dir0=[ASC], dir1=[ASC])\n"
+ + " ElasticsearchProject(city=[CAST(ITEM($0, 'city')):VARCHAR(20) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\"], longitude=[CAST(ITEM(ITEM($0, 'loc'), 0)):FLOAT], latitude=[CAST(ITEM(ITEM($0, 'loc'), 1)):FLOAT], pop=[CAST(ITEM($0, 'pop')):INTEGER], state=[CAST(ITEM($0, 'state')):VARCHAR(2) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\"], id=[CAST(ITEM($0, 'id')):VARCHAR(5) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\"])\n"
+ + " ElasticsearchFilter(condition=[AND(=(CAST(ITEM($0, 'state')):VARCHAR(2) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\", 'CA'), >=(CAST(ITEM($0, 'pop')):INTEGER, 94000))])\n"
+ + " ElasticsearchTableScan(table=[[elastic, zips]])\n\n";
+ calciteAssert()
+ .query(sql)
+ .returnsOrdered("city=NORWALK; longitude=-118.081767; latitude=33.90564;"
+ + " pop=94188; state=CA; id=90650",
+ "city=LOS ANGELES; longitude=-118.258189; latitude=34.007856;"
+ + " pop=96074; state=CA; id=90011",
+ "city=BELL GARDENS; longitude=-118.17205; latitude=33.969177;"
+ + " pop=99568; state=CA; id=90201")
+ .queryContains(
+ ElasticsearchChecker.elasticsearchChecker("\"query\" : "
+ + "{\"constant_score\":{\"filter\":{\"bool\":"
+ + "{\"must\":[{\"term\":{\"state\":\"CA\"}},"
+ + "{\"range\":{\"pop\":{\"gte\":94000}}}]}}}}",
+ "\"script_fields\": {\"longitude\":{\"script\":\"params._source.loc[0]\"}, "
+ + "\"latitude\":{\"script\":\"params._source.loc[1]\"}, "
+ + "\"city\":{\"script\": \"params._source.city\"}, "
+ + "\"pop\":{\"script\": \"params._source.pop\"}, "
+ + "\"state\":{\"script\": \"params._source.state\"}, "
+ + "\"id\":{\"script\": \"params._source.id\"}}",
+ "\"sort\": [ {\"state\": \"asc\"}, {\"pop\": \"asc\"}]"))
+ .explainContains(explain);
+ }
+
+ @Test public void testFilterSortDesc() {
+ final String sql = "select * from zips\n"
+ + "where \"pop\" BETWEEN 95000 AND 100000\n"
+ + "order by \"state\" desc, \"pop\"";
+ calciteAssert()
+ .query(sql)
+ .limit(4)
+ .returnsOrdered(
+ "city=LOS ANGELES; longitude=-118.258189; latitude=34.007856; pop=96074; state=CA; id=90011",
+ "city=BELL GARDENS; longitude=-118.17205; latitude=33.969177; pop=99568; state=CA; id=90201");
+ }
+
+ @Test public void testFilterRedundant() {
+ final String sql = "select * from zips\n"
+ + "where \"state\" > 'CA' and \"state\" < 'AZ' and \"state\" = 'OK'";
+ calciteAssert()
+ .query(sql)
+ .runs()
+ .queryContains(
+ ElasticsearchChecker.elasticsearchChecker(""
+ + "\"query\" : {\"constant_score\":{\"filter\":{\"bool\":"
+ + "{\"must\":[{\"term\":{\"state\":\"OK\"}}]}}}}",
+ "\"script_fields\": {\"longitude\":{\"script\":\"params._source.loc[0]\"}, "
+ + "\"latitude\":{\"script\":\"params._source.loc[1]\"}, "
+ + "\"city\":{\"script\": \"params._source.city\"}, "
+ + "\"pop\":{\"script\": \"params._source.pop\"}, \"state\":{\"script\": \"params._source.state\"}, "
+ + "\"id\":{\"script\": \"params._source.id\"}}"
+ ));
+ }
+
+ @Test public void testInPlan() {
+ final String[] searches = {
+ "\"query\" : {\"constant_score\":{\"filter\":{\"bool\":{\"should\":"
+ + "[{\"bool\":{\"must\":[{\"term\":{\"pop\":96074}}]}},{\"bool\":{\"must\":[{\"term\":"
+ + "{\"pop\":99568}}]}}]}}}}",
+ "\"script_fields\": {\"longitude\":{\"script\":\"params._source.loc[0]\"}, "
+ + "\"latitude\":{\"script\":\"params._source.loc[1]\"}, "
+ + "\"city\":{\"script\": \"params._source.city\"}, "
+ + "\"pop\":{\"script\": \"params._source.pop\"}, "
+ + "\"state\":{\"script\": \"params._source.state\"}, "
+ + "\"id\":{\"script\": \"params._source.id\"}}"
+ };
+
+ calciteAssert()
+ .query("select * from zips where \"pop\" in (96074, 99568)")
+ .returnsUnordered(
+ "city=BELL GARDENS; longitude=-118.17205; latitude=33.969177; pop=99568; state=CA; id=90201",
+ "city=LOS ANGELES; longitude=-118.258189; latitude=34.007856; pop=96074; state=CA; id=90011"
+ )
+ .queryContains(ElasticsearchChecker.elasticsearchChecker(searches));
+ }
+
+ @Test public void testZips() {
+ calciteAssert()
+ .query("select \"state\", \"city\" from zips")
+ .returnsCount(10);
+ }
+
+ @Test public void testProject() {
+ final String sql = "select \"state\", \"city\", 0 as \"zero\"\n"
+ + "from zips\n"
+ + "order by \"state\", \"city\"";
+
+ calciteAssert()
+ .query(sql)
+ .limit(2)
+ .returnsUnordered("state=AK; city=ANCHORAGE; zero=0",
+ "state=AK; city=FAIRBANKS; zero=0")
+ .queryContains(
+ ElasticsearchChecker.elasticsearchChecker("\"script_fields\": "
+ + "{\"zero\":{\"script\": \"0\"}, "
+ + "\"state\":{\"script\": \"params._source.state\"}, "
+ + "\"city\":{\"script\": \"params._source.city\"}}",
+ "\"sort\": [ {\"state\": \"asc\"}, {\"city\": \"asc\"}]"));
+ }
+
+ @Test public void testFilter() {
+ final String explain = "PLAN=ElasticsearchToEnumerableConverter\n"
+ + " ElasticsearchProject(state=[CAST(ITEM($0, 'state')):VARCHAR(2) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\"], city=[CAST(ITEM($0, 'city')):VARCHAR(20) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\"])\n"
+ + " ElasticsearchFilter(condition=[=(CAST(ITEM($0, 'state')):VARCHAR(2) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\", 'CA')])\n"
+ + " ElasticsearchTableScan(table=[[elastic, zips]])";
+ calciteAssert()
+ .query("select \"state\", \"city\" from zips where \"state\" = 'CA'")
+ .limit(3)
+ .returnsUnordered("state=CA; city=BELL GARDENS",
+ "state=CA; city=LOS ANGELES",
+ "state=CA; city=NORWALK")
+ .explainContains(explain);
+ }
+
+ @Test public void testFilterReversed() {
+ calciteAssert()
+ .query("select \"state\", \"city\" from zips where 'WI' < \"state\" order by \"city\"")
+ .limit(2)
+ .returnsUnordered("state=WV; city=BECKLEY",
+ "state=WY; city=CHEYENNE");
+ calciteAssert()
+ .query("select \"state\", \"city\" from zips where \"state\" > 'WI' order by \"city\"")
+ .limit(2)
+ .returnsUnordered("state=WV; city=BECKLEY",
+ "state=WY; city=CHEYENNE");
+ }
+
+}
+
+// End Elasticsearch5AdapterTest.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/6e8bb5a1/elasticsearch5/src/test/java/org/apache/calcite/adapter/elasticsearch5/EmbeddedElasticsearchNode.java
----------------------------------------------------------------------
diff --git a/elasticsearch5/src/test/java/org/apache/calcite/adapter/elasticsearch5/EmbeddedElasticsearchNode.java b/elasticsearch5/src/test/java/org/apache/calcite/adapter/elasticsearch5/EmbeddedElasticsearchNode.java
index d603d87..cd8af9a 100644
--- a/elasticsearch5/src/test/java/org/apache/calcite/adapter/elasticsearch5/EmbeddedElasticsearchNode.java
+++ b/elasticsearch5/src/test/java/org/apache/calcite/adapter/elasticsearch5/EmbeddedElasticsearchNode.java
@@ -118,7 +118,7 @@ class EmbeddedElasticsearchNode implements AutoCloseable {
}
/**
- * Exposes elastic
+ * Exposes an Elasticsearch
* <a href="https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/transport-client.html">transport client</a>
* (use of HTTP client is preferred).
*
http://git-wip-us.apache.org/repos/asf/calcite/blob/6e8bb5a1/elasticsearch5/src/test/java/org/apache/calcite/adapter/elasticsearch5/EmbeddedElasticsearchPolicy.java
----------------------------------------------------------------------
diff --git a/elasticsearch5/src/test/java/org/apache/calcite/adapter/elasticsearch5/EmbeddedElasticsearchPolicy.java b/elasticsearch5/src/test/java/org/apache/calcite/adapter/elasticsearch5/EmbeddedElasticsearchPolicy.java
new file mode 100644
index 0000000..6db2ddb
--- /dev/null
+++ b/elasticsearch5/src/test/java/org/apache/calcite/adapter/elasticsearch5/EmbeddedElasticsearchPolicy.java
@@ -0,0 +1,103 @@
+/*
+ * 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.adapter.elasticsearch5;
+
+import com.google.common.base.Preconditions;
+
+import org.elasticsearch.client.Client;
+import org.elasticsearch.common.transport.TransportAddress;
+
+import org.junit.rules.ExternalResource;
+
+/**
+ * Junit rule that is used to initialize a single Elasticsearch node for tests.
+ *
+ * <p>For performance reasons (node startup costs),
+ * the same instance is usually shared across multiple tests.
+ *
+ * <p>This rule should be used as follows:
+ * <pre>
+ *
+ * public class MyTest {
+ * @ClassRule
+ * public static final ElasticSearchRule RULE = ElasticSearchRule.create();
+ *
+ * @BeforeClass
+ * public static void setup() {
+ * // ... populate instance
+ * }
+ *
+ * @Test
+ * public void myTest() {
+ * TransportAddress address = RULE.httpAddress();
+ * // .... (connect to ES)
+ * }
+ * }
+ * </pre>
+ *
+ * @see ExternalResource
+ */
+class EmbeddedElasticsearchPolicy extends ExternalResource {
+
+ private final EmbeddedElasticsearchNode node;
+
+ private EmbeddedElasticsearchPolicy(EmbeddedElasticsearchNode resource) {
+ this.node = Preconditions.checkNotNull(resource, "resource");
+ }
+
+ @Override protected void before() throws Throwable {
+ node.start();
+ }
+
+ @Override protected void after() {
+ try {
+ node.close();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Factory method to create this rule.
+ *
+ * @return new rule instance to be used in unit tests
+ */
+ public static EmbeddedElasticsearchPolicy create() {
+ return new EmbeddedElasticsearchPolicy(EmbeddedElasticsearchNode.create());
+ }
+
+ /**
+ * Exposes current ES transport client.
+ * @return running (and initialized) instance of ES node
+ */
+ Client client() {
+ return node.client();
+ }
+
+ /**
+ * HTTP address for rest clients (can be ES native or any other).
+ *
+ * @return {@code HTTP} connection parameters
+ */
+ TransportAddress httpAddress() {
+ return node.httpAddress();
+ }
+
+
+}
+
+// End EmbeddedElasticsearchPolicy.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/6e8bb5a1/elasticsearch5/src/test/java/org/apache/calcite/test/ElasticsearchChecker.java
----------------------------------------------------------------------
diff --git a/elasticsearch5/src/test/java/org/apache/calcite/test/ElasticsearchChecker.java b/elasticsearch5/src/test/java/org/apache/calcite/test/ElasticsearchChecker.java
new file mode 100644
index 0000000..550c04c
--- /dev/null
+++ b/elasticsearch5/src/test/java/org/apache/calcite/test/ElasticsearchChecker.java
@@ -0,0 +1,53 @@
+/*
+ * 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 com.google.common.base.Function;
+
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+/**
+ * Utility methods for Elasticsearch tests.
+ */
+public class ElasticsearchChecker {
+
+ private ElasticsearchChecker() {}
+
+ /**
+ * Returns a function that checks that a particular Elasticsearch pipeline is
+ * generated to implement a query.
+ *
+ * @param strings expected expressions
+ * @return validation function
+ */
+ public static Function<List, Void> elasticsearchChecker(final String... strings) {
+ return new Function<List, Void>() {
+ @Nullable
+ @Override public Void apply(@Nullable List actual) {
+ Object[] actualArray = actual == null || actual.isEmpty() ? null
+ : ((List) actual.get(0)).toArray();
+ CalciteAssert.assertArrayEqual("expected Elasticsearch query not found", strings,
+ actualArray);
+ return null;
+ }
+ };
+ }
+}
+
+// End ElasticsearchChecker.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/6e8bb5a1/elasticsearch5/src/test/resources/log4j2.xml
----------------------------------------------------------------------
diff --git a/elasticsearch5/src/test/resources/log4j2.xml b/elasticsearch5/src/test/resources/log4j2.xml
index b38aca2..0a12b9c 100644
--- a/elasticsearch5/src/test/resources/log4j2.xml
+++ b/elasticsearch5/src/test/resources/log4j2.xml
@@ -13,4 +13,4 @@
<AppenderRef ref="console" />
</Root>
</Loggers>
-</Configuration>
\ No newline at end of file
+</Configuration>
http://git-wip-us.apache.org/repos/asf/calcite/blob/6e8bb5a1/elasticsearch5/src/test/resources/zips-mini.json
----------------------------------------------------------------------
diff --git a/elasticsearch5/src/test/resources/zips-mini.json b/elasticsearch5/src/test/resources/zips-mini.json
index d70eadc..858117a 100644
--- a/elasticsearch5/src/test/resources/zips-mini.json
+++ b/elasticsearch5/src/test/resources/zips-mini.json
@@ -146,4 +146,4 @@
{ "_id" : "98310", "city" : "BREMERTON", "loc" : [ -122.629913, 47.601916 ], "pop" : 49057, "state" : "WA" }
{ "_id" : "99504", "city" : "ANCHORAGE", "loc" : [ -149.74467, 61.203696 ], "pop" : 32383, "state" : "AK" }
{ "_id" : "99709", "city" : "FAIRBANKS", "loc" : [ -147.846917, 64.85437 ], "pop" : 23238, "state" : "AK" }
-{ "_id" : "99801", "city" : "JUNEAU", "loc" : [ -134.529429, 58.362767 ], "pop" : 24947, "state" : "AK" }
\ No newline at end of file
+{ "_id" : "99801", "city" : "JUNEAU", "loc" : [ -134.529429, 58.362767 ], "pop" : 24947, "state" : "AK" }
http://git-wip-us.apache.org/repos/asf/calcite/blob/6e8bb5a1/mongodb/src/test/java/org/apache/calcite/adapter/mongodb/MongoAdapterTest.java
----------------------------------------------------------------------
diff --git a/mongodb/src/test/java/org/apache/calcite/adapter/mongodb/MongoAdapterTest.java b/mongodb/src/test/java/org/apache/calcite/adapter/mongodb/MongoAdapterTest.java
index a4d8900..d6a45d9 100644
--- a/mongodb/src/test/java/org/apache/calcite/adapter/mongodb/MongoAdapterTest.java
+++ b/mongodb/src/test/java/org/apache/calcite/adapter/mongodb/MongoAdapterTest.java
@@ -22,7 +22,6 @@ import org.apache.calcite.schema.SchemaPlus;
import org.apache.calcite.test.CalciteAssert;
import org.apache.calcite.test.MongoAssertions;
-
import org.apache.calcite.util.Bug;
import org.apache.calcite.util.Util;
@@ -65,6 +64,8 @@ import java.util.Map;
* Testing mongo adapter functionality. By default runs with
* <a href="https://github.com/fakemongo/fongo">Fongo</a> unless {@code IT} maven profile is enabled
* (via {@code $ mvn -Pit install}).
+ *
+ * @see MongoDatabasePolicy
*/
public class MongoAdapterTest implements SchemaFactory {
@@ -75,27 +76,27 @@ public class MongoAdapterTest implements SchemaFactory {
protected static final int ZIPS_SIZE = 149;
@ClassRule
- public static final MongoDatabaseRule RULE = MongoDatabaseRule.create();
+ public static final MongoDatabasePolicy POLICY = MongoDatabasePolicy.create();
private static MongoSchema schema;
@BeforeClass
public static void setUp() throws Exception {
- MongoDatabase database = RULE.database();
+ MongoDatabase database = POLICY.database();
populate(database.getCollection("zips"), MongoAdapterTest.class.getResource("/zips-mini.json"));
populate(database.getCollection("store"), FoodmartJson.class.getResource("/store.json"));
populate(database.getCollection("warehouse"),
- FoodmartJson.class.getResource("/warehouse.json"));
+ FoodmartJson.class.getResource("/warehouse.json"));
// Manually insert data for data-time test.
MongoCollection<BsonDocument> datatypes = database.getCollection("datatypes")
- .withDocumentClass(BsonDocument.class);
+ .withDocumentClass(BsonDocument.class);
if (datatypes.count() > 0) {
datatypes.deleteMany(new BsonDocument());
}
BsonDocument doc = new BsonDocument();
- Date date = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).parse("2012-09-05");
+ Date date = new SimpleDateFormat("yyyy-MM-dd", Locale.ROOT).parse("2012-09-05");
doc.put("date", new BsonDateTime(date.getTime()));
doc.put("value", new BsonInt32(1231));
doc.put("ownerId", new BsonString("531e7789e4b0853ddb861313"));
@@ -105,7 +106,7 @@ public class MongoAdapterTest implements SchemaFactory {
}
private static void populate(MongoCollection<Document> collection, URL resource)
- throws IOException {
+ throws IOException {
Preconditions.checkNotNull(collection, "collection");
if (collection.count() > 0) {
@@ -130,7 +131,7 @@ public class MongoAdapterTest implements SchemaFactory {
* Returns always the same schema to avoid initialization costs.
*/
@Override public Schema create(SchemaPlus parentSchema, String name,
- Map<String, Object> operand) {
+ Map<String, Object> operand) {
return schema;
}
@@ -139,7 +140,7 @@ public class MongoAdapterTest implements SchemaFactory {
model = model.replace(MongoSchemaFactory.class.getName(), MongoAdapterTest.class.getName());
return CalciteAssert.that()
- .withModel(model);
+ .withModel(model);
}
private CalciteAssert.AssertThat assertModel(URL url) {
@@ -151,53 +152,52 @@ public class MongoAdapterTest implements SchemaFactory {
}
}
- @Test
- public void testSort() {
+ @Test public void testSort() {
assertModel(MODEL)
- .query("select * from zips order by state")
- .returnsCount(ZIPS_SIZE)
- .explainContains("PLAN=MongoToEnumerableConverter\n"
- + " MongoSort(sort0=[$4], dir0=[ASC])\n"
- + " MongoProject(CITY=[CAST(ITEM($0, 'city')):VARCHAR(20) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\"], LONGITUDE=[CAST(ITEM(ITEM($0, 'loc'), 0)):FLOAT], LATITUDE=[CAST(ITEM(ITEM($0, 'loc'), 1)):FLOAT], POP=[CAST(ITEM($0, 'pop')):INTEGER], STATE=[CAST(ITEM($0, 'state')):VARCHAR(2) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\"], ID=[CAST(ITEM($0, '_id')):VARCHAR(5) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\"])\n"
- + " MongoTableScan(table=[[mongo_raw, zips]])");
+ .query("select * from zips order by state")
+ .returnsCount(ZIPS_SIZE)
+ .explainContains("PLAN=MongoToEnumerableConverter\n"
+ + " MongoSort(sort0=[$4], dir0=[ASC])\n"
+ + " MongoProject(CITY=[CAST(ITEM($0, 'city')):VARCHAR(20) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\"], LONGITUDE=[CAST(ITEM(ITEM($0, 'loc'), 0)):FLOAT], LATITUDE=[CAST(ITEM(ITEM($0, 'loc'), 1)):FLOAT], POP=[CAST(ITEM($0, 'pop')):INTEGER], STATE=[CAST(ITEM($0, 'state')):VARCHAR(2) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\"], ID=[CAST(ITEM($0, '_id')):VARCHAR(5) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\"])\n"
+ + " MongoTableScan(table=[[mongo_raw, zips]])");
}
@Test public void testSortLimit() {
assertModel(MODEL)
- .query("select state, id from zips\n"
- + "order by state, id offset 2 rows fetch next 3 rows only")
- .returnsOrdered("STATE=AK; ID=99801",
- "STATE=AL; ID=35215",
- "STATE=AL; ID=35401")
- .queryContains(
- mongoChecker(
- "{$project: {STATE: '$state', ID: '$_id'}}",
- "{$sort: {STATE: 1, ID: 1}}",
- "{$skip: 2}",
- "{$limit: 3}"));
+ .query("select state, id from zips\n"
+ + "order by state, id offset 2 rows fetch next 3 rows only")
+ .returnsOrdered("STATE=AK; ID=99801",
+ "STATE=AL; ID=35215",
+ "STATE=AL; ID=35401")
+ .queryContains(
+ mongoChecker(
+ "{$project: {STATE: '$state', ID: '$_id'}}",
+ "{$sort: {STATE: 1, ID: 1}}",
+ "{$skip: 2}",
+ "{$limit: 3}"));
}
@Test public void testOffsetLimit() {
assertModel(MODEL)
- .query("select state, id from zips\n"
- + "offset 2 fetch next 3 rows only")
- .runs()
- .queryContains(
- mongoChecker(
- "{$skip: 2}",
- "{$limit: 3}",
- "{$project: {STATE: '$state', ID: '$_id'}}"));
+ .query("select state, id from zips\n"
+ + "offset 2 fetch next 3 rows only")
+ .runs()
+ .queryContains(
+ mongoChecker(
+ "{$skip: 2}",
+ "{$limit: 3}",
+ "{$project: {STATE: '$state', ID: '$_id'}}"));
}
@Test public void testLimit() {
assertModel(MODEL)
- .query("select state, id from zips\n"
- + "fetch next 3 rows only")
- .runs()
- .queryContains(
- mongoChecker(
- "{$limit: 3}",
- "{$project: {STATE: '$state', ID: '$_id'}}"));
+ .query("select state, id from zips\n"
+ + "fetch next 3 rows only")
+ .runs()
+ .queryContains(
+ mongoChecker(
+ "{$limit: 3}",
+ "{$project: {STATE: '$state', ID: '$_id'}}"));
}
@Ignore
@@ -205,76 +205,76 @@ public class MongoAdapterTest implements SchemaFactory {
// LONGITUDE and LATITUDE are null because of CALCITE-194.
Util.discard(Bug.CALCITE_194_FIXED);
assertModel(MODEL)
- .query("select * from zips\n"
- + "where city = 'SPRINGFIELD' and id >= '70000'\n"
- + "order by state, id")
- .returns(""
- + "CITY=SPRINGFIELD; LONGITUDE=null; LATITUDE=null; POP=752; STATE=AR; ID=72157\n"
- + "CITY=SPRINGFIELD; LONGITUDE=null; LATITUDE=null; POP=1992; STATE=CO; ID=81073\n"
- + "CITY=SPRINGFIELD; LONGITUDE=null; LATITUDE=null; POP=5597; STATE=LA; ID=70462\n"
- + "CITY=SPRINGFIELD; LONGITUDE=null; LATITUDE=null; POP=32384; STATE=OR; ID=97477\n"
- + "CITY=SPRINGFIELD; LONGITUDE=null; LATITUDE=null; POP=27521; STATE=OR; ID=97478\n")
- .queryContains(
- mongoChecker(
- "{\n"
- + " $match: {\n"
- + " city: \"SPRINGFIELD\",\n"
- + " _id: {\n"
- + " $gte: \"70000\"\n"
- + " }\n"
- + " }\n"
- + "}",
- "{$project: {CITY: '$city', LONGITUDE: '$loc[0]', LATITUDE: '$loc[1]', POP: '$pop', STATE: '$state', ID: '$_id'}}",
- "{$sort: {STATE: 1, ID: 1}}"))
- .explainContains("PLAN=MongoToEnumerableConverter\n"
- + " MongoSort(sort0=[$4], sort1=[$5], dir0=[ASC], dir1=[ASC])\n"
- + " MongoProject(CITY=[CAST(ITEM($0, 'city')):VARCHAR(20) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\"], LONGITUDE=[CAST(ITEM(ITEM($0, 'loc'), 0)):FLOAT], LATITUDE=[CAST(ITEM(ITEM($0, 'loc'), 1)):FLOAT], POP=[CAST(ITEM($0, 'pop')):INTEGER], STATE=[CAST(ITEM($0, 'state')):VARCHAR(2) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\"], ID=[CAST(ITEM($0, '_id')):VARCHAR(5) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\"])\n"
- + " MongoFilter(condition=[AND(=(CAST(ITEM($0, 'city')):VARCHAR(20) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\", 'SPRINGFIELD'), >=(CAST(ITEM($0, '_id')):VARCHAR(5) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\", '70000'))])\n"
- + " MongoTableScan(table=[[mongo_raw, zips]])");
+ .query("select * from zips\n"
+ + "where city = 'SPRINGFIELD' and id >= '70000'\n"
+ + "order by state, id")
+ .returns(""
+ + "CITY=SPRINGFIELD; LONGITUDE=null; LATITUDE=null; POP=752; STATE=AR; ID=72157\n"
+ + "CITY=SPRINGFIELD; LONGITUDE=null; LATITUDE=null; POP=1992; STATE=CO; ID=81073\n"
+ + "CITY=SPRINGFIELD; LONGITUDE=null; LATITUDE=null; POP=5597; STATE=LA; ID=70462\n"
+ + "CITY=SPRINGFIELD; LONGITUDE=null; LATITUDE=null; POP=32384; STATE=OR; ID=97477\n"
+ + "CITY=SPRINGFIELD; LONGITUDE=null; LATITUDE=null; POP=27521; STATE=OR; ID=97478\n")
+ .queryContains(
+ mongoChecker(
+ "{\n"
+ + " $match: {\n"
+ + " city: \"SPRINGFIELD\",\n"
+ + " _id: {\n"
+ + " $gte: \"70000\"\n"
+ + " }\n"
+ + " }\n"
+ + "}",
+ "{$project: {CITY: '$city', LONGITUDE: '$loc[0]', LATITUDE: '$loc[1]', POP: '$pop', STATE: '$state', ID: '$_id'}}",
+ "{$sort: {STATE: 1, ID: 1}}"))
+ .explainContains("PLAN=MongoToEnumerableConverter\n"
+ + " MongoSort(sort0=[$4], sort1=[$5], dir0=[ASC], dir1=[ASC])\n"
+ + " MongoProject(CITY=[CAST(ITEM($0, 'city')):VARCHAR(20) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\"], LONGITUDE=[CAST(ITEM(ITEM($0, 'loc'), 0)):FLOAT], LATITUDE=[CAST(ITEM(ITEM($0, 'loc'), 1)):FLOAT], POP=[CAST(ITEM($0, 'pop')):INTEGER], STATE=[CAST(ITEM($0, 'state')):VARCHAR(2) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\"], ID=[CAST(ITEM($0, '_id')):VARCHAR(5) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\"])\n"
+ + " MongoFilter(condition=[AND(=(CAST(ITEM($0, 'city')):VARCHAR(20) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\", 'SPRINGFIELD'), >=(CAST(ITEM($0, '_id')):VARCHAR(5) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\", '70000'))])\n"
+ + " MongoTableScan(table=[[mongo_raw, zips]])");
}
@Test public void testFilterSortDesc() {
assertModel(MODEL)
- .query("select * from zips\n"
- + "where pop BETWEEN 45000 AND 46000\n"
- + "order by state desc, pop")
- .limit(4)
- .returnsOrdered(
- "CITY=BECKLEY; LONGITUDE=null; LATITUDE=null; POP=45196; STATE=WV; ID=25801",
- "CITY=ROCKERVILLE; LONGITUDE=null; LATITUDE=null; POP=45328; STATE=SD; ID=57701",
- "CITY=PAWTUCKET; LONGITUDE=null; LATITUDE=null; POP=45442; STATE=RI; ID=02860",
- "CITY=LAWTON; LONGITUDE=null; LATITUDE=null; POP=45542; STATE=OK; ID=73505");
+ .query("select * from zips\n"
+ + "where pop BETWEEN 45000 AND 46000\n"
+ + "order by state desc, pop")
+ .limit(4)
+ .returnsOrdered(
+ "CITY=BECKLEY; LONGITUDE=null; LATITUDE=null; POP=45196; STATE=WV; ID=25801",
+ "CITY=ROCKERVILLE; LONGITUDE=null; LATITUDE=null; POP=45328; STATE=SD; ID=57701",
+ "CITY=PAWTUCKET; LONGITUDE=null; LATITUDE=null; POP=45442; STATE=RI; ID=02860",
+ "CITY=LAWTON; LONGITUDE=null; LATITUDE=null; POP=45542; STATE=OK; ID=73505");
}
@Ignore("broken; [CALCITE-2115] is logged to fix it")
@Test public void testUnionPlan() {
assertModel(MODEL)
- .query("select * from \"sales_fact_1997\"\n"
- + "union all\n"
- + "select * from \"sales_fact_1998\"")
- .explainContains("PLAN=EnumerableUnion(all=[true])\n"
- + " MongoToEnumerableConverter\n"
- + " MongoProject(product_id=[CAST(ITEM($0, 'product_id')):DOUBLE])\n"
- + " MongoTableScan(table=[[_foodmart, sales_fact_1997]])\n"
- + " MongoToEnumerableConverter\n"
- + " MongoProject(product_id=[CAST(ITEM($0, 'product_id')):DOUBLE])\n"
- + " MongoTableScan(table=[[_foodmart, sales_fact_1998]])")
- .limit(2)
- .returns(
- MongoAssertions.checkResultUnordered(
- "product_id=337", "product_id=1512"));
+ .query("select * from \"sales_fact_1997\"\n"
+ + "union all\n"
+ + "select * from \"sales_fact_1998\"")
+ .explainContains("PLAN=EnumerableUnion(all=[true])\n"
+ + " MongoToEnumerableConverter\n"
+ + " MongoProject(product_id=[CAST(ITEM($0, 'product_id')):DOUBLE])\n"
+ + " MongoTableScan(table=[[_foodmart, sales_fact_1997]])\n"
+ + " MongoToEnumerableConverter\n"
+ + " MongoProject(product_id=[CAST(ITEM($0, 'product_id')):DOUBLE])\n"
+ + " MongoTableScan(table=[[_foodmart, sales_fact_1998]])")
+ .limit(2)
+ .returns(
+ MongoAssertions.checkResultUnordered(
+ "product_id=337", "product_id=1512"));
}
@Ignore(
- "java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Double")
+ "java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Double")
@Test public void testFilterUnionPlan() {
assertModel(MODEL)
- .query("select * from (\n"
- + " select * from \"sales_fact_1997\"\n"
- + " union all\n"
- + " select * from \"sales_fact_1998\")\n"
- + "where \"product_id\" = 1")
- .runs();
+ .query("select * from (\n"
+ + " select * from \"sales_fact_1997\"\n"
+ + " union all\n"
+ + " select * from \"sales_fact_1998\")\n"
+ + "where \"product_id\" = 1")
+ .runs();
}
/** Tests that we don't generate multiple constraints on the same column.
@@ -282,111 +282,111 @@ public class MongoAdapterTest implements SchemaFactory {
* operators. */
@Test public void testFilterRedundant() {
assertModel(MODEL)
- .query(
- "select * from zips where state > 'CA' and state < 'AZ' and state = 'OK'")
- .runs()
- .queryContains(
- mongoChecker(
- "{\n"
- + " \"$match\": {\n"
- + " \"state\": \"OK\"\n"
- + " }\n"
- + "}",
- "{$project: {CITY: '$city', LONGITUDE: '$loc[0]', LATITUDE: '$loc[1]', POP: '$pop', STATE: '$state', ID: '$_id'}}"));
+ .query(
+ "select * from zips where state > 'CA' and state < 'AZ' and state = 'OK'")
+ .runs()
+ .queryContains(
+ mongoChecker(
+ "{\n"
+ + " \"$match\": {\n"
+ + " \"state\": \"OK\"\n"
+ + " }\n"
+ + "}",
+ "{$project: {CITY: '$city', LONGITUDE: '$loc[0]', LATITUDE: '$loc[1]', POP: '$pop', STATE: '$state', ID: '$_id'}}"));
}
@Test public void testSelectWhere() {
assertModel(MODEL)
- .query(
- "select * from \"warehouse\" where \"warehouse_state_province\" = 'CA'")
- .explainContains("PLAN=MongoToEnumerableConverter\n"
- + " MongoProject(warehouse_id=[CAST(ITEM($0, 'warehouse_id')):DOUBLE], warehouse_state_province=[CAST(ITEM($0, 'warehouse_state_province')):VARCHAR(20) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\"])\n"
- + " MongoFilter(condition=[=(CAST(ITEM($0, 'warehouse_state_province')):VARCHAR(20) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\", 'CA')])\n"
- + " MongoTableScan(table=[[mongo_raw, warehouse]])")
- .returns(
- MongoAssertions.checkResultUnordered(
- "warehouse_id=6; warehouse_state_province=CA",
- "warehouse_id=7; warehouse_state_province=CA",
- "warehouse_id=14; warehouse_state_province=CA",
- "warehouse_id=24; warehouse_state_province=CA"))
- .queryContains(
- // Per https://issues.apache.org/jira/browse/CALCITE-164,
- // $match must occur before $project for good performance.
- mongoChecker(
- "{\n"
- + " \"$match\": {\n"
- + " \"warehouse_state_province\": \"CA\"\n"
- + " }\n"
- + "}",
- "{$project: {warehouse_id: 1, warehouse_state_province: 1}}"));
+ .query(
+ "select * from \"warehouse\" where \"warehouse_state_province\" = 'CA'")
+ .explainContains("PLAN=MongoToEnumerableConverter\n"
+ + " MongoProject(warehouse_id=[CAST(ITEM($0, 'warehouse_id')):DOUBLE], warehouse_state_province=[CAST(ITEM($0, 'warehouse_state_province')):VARCHAR(20) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\"])\n"
+ + " MongoFilter(condition=[=(CAST(ITEM($0, 'warehouse_state_province')):VARCHAR(20) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\", 'CA')])\n"
+ + " MongoTableScan(table=[[mongo_raw, warehouse]])")
+ .returns(
+ MongoAssertions.checkResultUnordered(
+ "warehouse_id=6; warehouse_state_province=CA",
+ "warehouse_id=7; warehouse_state_province=CA",
+ "warehouse_id=14; warehouse_state_province=CA",
+ "warehouse_id=24; warehouse_state_province=CA"))
+ .queryContains(
+ // Per https://issues.apache.org/jira/browse/CALCITE-164,
+ // $match must occur before $project for good performance.
+ mongoChecker(
+ "{\n"
+ + " \"$match\": {\n"
+ + " \"warehouse_state_province\": \"CA\"\n"
+ + " }\n"
+ + "}",
+ "{$project: {warehouse_id: 1, warehouse_state_province: 1}}"));
}
@Test public void testInPlan() {
assertModel(MODEL)
- .query("select \"store_id\", \"store_name\" from \"store\"\n"
- + "where \"store_name\" in ('Store 1', 'Store 10', 'Store 11', 'Store 15', 'Store 16', 'Store 24', 'Store 3', 'Store 7')")
- .returns(
- MongoAssertions.checkResultUnordered(
- "store_id=1; store_name=Store 1",
- "store_id=3; store_name=Store 3",
- "store_id=7; store_name=Store 7",
- "store_id=10; store_name=Store 10",
- "store_id=11; store_name=Store 11",
- "store_id=15; store_name=Store 15",
- "store_id=16; store_name=Store 16",
- "store_id=24; store_name=Store 24"))
- .queryContains(
- mongoChecker(
- "{\n"
- + " \"$match\": {\n"
- + " \"$or\": [\n"
- + " {\n"
- + " \"store_name\": \"Store 1\"\n"
- + " },\n"
- + " {\n"
- + " \"store_name\": \"Store 10\"\n"
- + " },\n"
- + " {\n"
- + " \"store_name\": \"Store 11\"\n"
- + " },\n"
- + " {\n"
- + " \"store_name\": \"Store 15\"\n"
- + " },\n"
- + " {\n"
- + " \"store_name\": \"Store 16\"\n"
- + " },\n"
- + " {\n"
- + " \"store_name\": \"Store 24\"\n"
- + " },\n"
- + " {\n"
- + " \"store_name\": \"Store 3\"\n"
- + " },\n"
- + " {\n"
- + " \"store_name\": \"Store 7\"\n"
- + " }\n"
- + " ]\n"
- + " }\n"
- + "}",
- "{$project: {store_id: 1, store_name: 1}}"));
+ .query("select \"store_id\", \"store_name\" from \"store\"\n"
+ + "where \"store_name\" in ('Store 1', 'Store 10', 'Store 11', 'Store 15', 'Store 16', 'Store 24', 'Store 3', 'Store 7')")
+ .returns(
+ MongoAssertions.checkResultUnordered(
+ "store_id=1; store_name=Store 1",
+ "store_id=3; store_name=Store 3",
+ "store_id=7; store_name=Store 7",
+ "store_id=10; store_name=Store 10",
+ "store_id=11; store_name=Store 11",
+ "store_id=15; store_name=Store 15",
+ "store_id=16; store_name=Store 16",
+ "store_id=24; store_name=Store 24"))
+ .queryContains(
+ mongoChecker(
+ "{\n"
+ + " \"$match\": {\n"
+ + " \"$or\": [\n"
+ + " {\n"
+ + " \"store_name\": \"Store 1\"\n"
+ + " },\n"
+ + " {\n"
+ + " \"store_name\": \"Store 10\"\n"
+ + " },\n"
+ + " {\n"
+ + " \"store_name\": \"Store 11\"\n"
+ + " },\n"
+ + " {\n"
+ + " \"store_name\": \"Store 15\"\n"
+ + " },\n"
+ + " {\n"
+ + " \"store_name\": \"Store 16\"\n"
+ + " },\n"
+ + " {\n"
+ + " \"store_name\": \"Store 24\"\n"
+ + " },\n"
+ + " {\n"
+ + " \"store_name\": \"Store 3\"\n"
+ + " },\n"
+ + " {\n"
+ + " \"store_name\": \"Store 7\"\n"
+ + " }\n"
+ + " ]\n"
+ + " }\n"
+ + "}",
+ "{$project: {store_id: 1, store_name: 1}}"));
}
/** Simple query based on the "mongo-zips" model. */
@Test public void testZips() {
assertModel(MODEL)
- .query("select state, city from zips")
- .returnsCount(ZIPS_SIZE);
+ .query("select state, city from zips")
+ .returnsCount(ZIPS_SIZE);
}
@Test public void testCountGroupByEmpty() {
assertModel(MODEL)
- .query("select count(*) from zips")
- .returns(String.format(Locale.getDefault(), "EXPR$0=%d\n", ZIPS_SIZE))
- .explainContains("PLAN=MongoToEnumerableConverter\n"
- + " MongoAggregate(group=[{}], EXPR$0=[COUNT()])\n"
- + " MongoTableScan(table=[[mongo_raw, zips]])")
- .queryContains(
- mongoChecker(
- "{$group: {_id: {}, 'EXPR$0': {$sum: 1}}}"));
+ .query("select count(*) from zips")
+ .returns(String.format(Locale.ROOT, "EXPR$0=%d\n", ZIPS_SIZE))
+ .explainContains("PLAN=MongoToEnumerableConverter\n"
+ + " MongoAggregate(group=[{}], EXPR$0=[COUNT()])\n"
+ + " MongoTableScan(table=[[mongo_raw, zips]])")
+ .queryContains(
+ mongoChecker(
+ "{$group: {_id: {}, 'EXPR$0': {$sum: 1}}}"));
}
@Test public void testCountGroupByEmptyMultiplyBy2() {
@@ -394,197 +394,197 @@ public class MongoAdapterTest implements SchemaFactory {
MongoAssertions.assumeRealMongoInstance();
assertModel(MODEL)
- .query("select count(*)*2 from zips")
- .returns(String.format(Locale.getDefault(), "EXPR$0=%d\n", ZIPS_SIZE * 2))
- .queryContains(
- mongoChecker(
- "{$group: {_id: {}, _0: {$sum: 1}}}",
- "{$project: {'EXPR$0': {$multiply: ['$_0', {$literal: 2}]}}}"));
+ .query("select count(*)*2 from zips")
+ .returns(String.format(Locale.ROOT, "EXPR$0=%d\n", ZIPS_SIZE * 2))
+ .queryContains(
+ mongoChecker(
+ "{$group: {_id: {}, _0: {$sum: 1}}}",
+ "{$project: {'EXPR$0': {$multiply: ['$_0', {$literal: 2}]}}}"));
}
@Test public void testGroupByOneColumnNotProjected() {
assertModel(MODEL)
- .query("select count(*) from zips group by state order by 1")
- .limit(2)
- .returnsUnordered("EXPR$0=2",
- "EXPR$0=2")
- .queryContains(
- mongoChecker(
- "{$project: {STATE: '$state'}}",
- "{$group: {_id: '$STATE', 'EXPR$0': {$sum: 1}}}",
- "{$project: {STATE: '$_id', 'EXPR$0': '$EXPR$0'}}",
- "{$project: {'EXPR$0': 1}}",
- "{$sort: {EXPR$0: 1}}"));
+ .query("select count(*) from zips group by state order by 1")
+ .limit(2)
+ .returnsUnordered("EXPR$0=2",
+ "EXPR$0=2")
+ .queryContains(
+ mongoChecker(
+ "{$project: {STATE: '$state'}}",
+ "{$group: {_id: '$STATE', 'EXPR$0': {$sum: 1}}}",
+ "{$project: {STATE: '$_id', 'EXPR$0': '$EXPR$0'}}",
+ "{$project: {'EXPR$0': 1}}",
+ "{$sort: {EXPR$0: 1}}"));
}
@Test public void testGroupByOneColumn() {
assertModel(MODEL)
- .query(
- "select state, count(*) as c from zips group by state order by state")
- .limit(3)
- .returns("STATE=AK; C=3\nSTATE=AL; C=3\nSTATE=AR; C=3\n")
- .queryContains(
- mongoChecker(
- "{$project: {STATE: '$state'}}",
- "{$group: {_id: '$STATE', C: {$sum: 1}}}",
- "{$project: {STATE: '$_id', C: '$C'}}",
- "{$sort: {STATE: 1}}"));
+ .query(
+ "select state, count(*) as c from zips group by state order by state")
+ .limit(3)
+ .returns("STATE=AK; C=3\nSTATE=AL; C=3\nSTATE=AR; C=3\n")
+ .queryContains(
+ mongoChecker(
+ "{$project: {STATE: '$state'}}",
+ "{$group: {_id: '$STATE', C: {$sum: 1}}}",
+ "{$project: {STATE: '$_id', C: '$C'}}",
+ "{$sort: {STATE: 1}}"));
}
@Test public void testGroupByOneColumnReversed() {
// Note extra $project compared to testGroupByOneColumn.
assertModel(MODEL)
- .query(
- "select count(*) as c, state from zips group by state order by state")
- .limit(2)
- .returns("C=3; STATE=AK\nC=3; STATE=AL\n")
- .queryContains(
- mongoChecker(
- "{$project: {STATE: '$state'}}",
- "{$group: {_id: '$STATE', C: {$sum: 1}}}",
- "{$project: {STATE: '$_id', C: '$C'}}",
- "{$project: {C: 1, STATE: 1}}",
- "{$sort: {STATE: 1}}"));
+ .query(
+ "select count(*) as c, state from zips group by state order by state")
+ .limit(2)
+ .returns("C=3; STATE=AK\nC=3; STATE=AL\n")
+ .queryContains(
+ mongoChecker(
+ "{$project: {STATE: '$state'}}",
+ "{$group: {_id: '$STATE', C: {$sum: 1}}}",
+ "{$project: {STATE: '$_id', C: '$C'}}",
+ "{$project: {C: 1, STATE: 1}}",
+ "{$sort: {STATE: 1}}"));
}
@Test public void testGroupByAvg() {
assertModel(MODEL)
- .query(
- "select state, avg(pop) as a from zips group by state order by state")
- .limit(2)
- .returns("STATE=AK; A=26856\nSTATE=AL; A=43383\n")
- .queryContains(
- mongoChecker(
- "{$project: {POP: '$pop', STATE: '$state'}}",
- "{$group: {_id: '$STATE', A: {$avg: '$POP'}}}",
- "{$project: {STATE: '$_id', A: '$A'}}",
- "{$sort: {STATE: 1}}"));
+ .query(
+ "select state, avg(pop) as a from zips group by state order by state")
+ .limit(2)
+ .returns("STATE=AK; A=26856\nSTATE=AL; A=43383\n")
+ .queryContains(
+ mongoChecker(
+ "{$project: {POP: '$pop', STATE: '$state'}}",
+ "{$group: {_id: '$STATE', A: {$avg: '$POP'}}}",
+ "{$project: {STATE: '$_id', A: '$A'}}",
+ "{$sort: {STATE: 1}}"));
}
@Test public void testGroupByAvgSumCount() {
// This operation not supported by fongo: https://github.com/fakemongo/fongo/issues/152
MongoAssertions.assumeRealMongoInstance();
assertModel(MODEL)
- .query(
- "select state, avg(pop) as a, sum(pop) as s, count(pop) as c from zips group by state order by state")
- .limit(2)
- .returns("STATE=AK; A=26856; S=80568; C=3\n"
- + "STATE=AL; A=43383; S=130151; C=3\n")
- .queryContains(
- mongoChecker(
- "{$project: {POP: '$pop', STATE: '$state'}}",
- "{$group: {_id: '$STATE', _1: {$sum: '$POP'}, _2: {$sum: {$cond: [ {$eq: ['POP', null]}, 0, 1]}}}}",
- "{$project: {STATE: '$_id', _1: '$_1', _2: '$_2'}}",
- "{$sort: {STATE: 1}}",
- "{$project: {STATE: 1, A: {$divide: [{$cond:[{$eq: ['$_2', {$literal: 0}]},null,'$_1']}, '$_2']}, S: {$cond:[{$eq: ['$_2', {$literal: 0}]},null,'$_1']}, C: '$_2'}}"));
+ .query(
+ "select state, avg(pop) as a, sum(pop) as s, count(pop) as c from zips group by state order by state")
+ .limit(2)
+ .returns("STATE=AK; A=26856; S=80568; C=3\n"
+ + "STATE=AL; A=43383; S=130151; C=3\n")
+ .queryContains(
+ mongoChecker(
+ "{$project: {POP: '$pop', STATE: '$state'}}",
+ "{$group: {_id: '$STATE', _1: {$sum: '$POP'}, _2: {$sum: {$cond: [ {$eq: ['POP', null]}, 0, 1]}}}}",
+ "{$project: {STATE: '$_id', _1: '$_1', _2: '$_2'}}",
+ "{$sort: {STATE: 1}}",
+ "{$project: {STATE: 1, A: {$divide: [{$cond:[{$eq: ['$_2', {$literal: 0}]},null,'$_1']}, '$_2']}, S: {$cond:[{$eq: ['$_2', {$literal: 0}]},null,'$_1']}, C: '$_2'}}"));
}
@Test public void testGroupByHaving() {
assertModel(MODEL)
- .query("select state, count(*) as c from zips\n"
- + "group by state having count(*) > 2 order by state")
- .returnsCount(47)
- .queryContains(
- mongoChecker(
- "{$project: {STATE: '$state'}}",
- "{$group: {_id: '$STATE', C: {$sum: 1}}}",
- "{$project: {STATE: '$_id', C: '$C'}}",
- "{\n"
- + " \"$match\": {\n"
- + " \"C\": {\n"
- + " \"$gt\": 2\n"
- + " }\n"
- + " }\n"
- + "}",
- "{$sort: {STATE: 1}}"));
+ .query("select state, count(*) as c from zips\n"
+ + "group by state having count(*) > 2 order by state")
+ .returnsCount(47)
+ .queryContains(
+ mongoChecker(
+ "{$project: {STATE: '$state'}}",
+ "{$group: {_id: '$STATE', C: {$sum: 1}}}",
+ "{$project: {STATE: '$_id', C: '$C'}}",
+ "{\n"
+ + " \"$match\": {\n"
+ + " \"C\": {\n"
+ + " \"$gt\": 2\n"
+ + " }\n"
+ + " }\n"
+ + "}",
+ "{$sort: {STATE: 1}}"));
}
@Ignore("https://issues.apache.org/jira/browse/CALCITE-270")
@Test public void testGroupByHaving2() {
assertModel(MODEL)
- .query("select state, count(*) as c from zips\n"
- + "group by state having sum(pop) > 12000000")
- .returns("STATE=NY; C=1596\n"
- + "STATE=TX; C=1676\n"
- + "STATE=FL; C=826\n"
- + "STATE=CA; C=1523\n")
- .queryContains(
- mongoChecker(
- "{$project: {STATE: '$state', POP: '$pop'}}",
- "{$group: {_id: '$STATE', C: {$sum: 1}, _2: {$sum: '$POP'}}}",
- "{$project: {STATE: '$_id', C: '$C', _2: '$_2'}}",
- "{\n"
- + " $match: {\n"
- + " _2: {\n"
- + " $gt: 12000000\n"
- + " }\n"
- + " }\n"
- + "}",
- "{$project: {STATE: 1, C: 1}}"));
+ .query("select state, count(*) as c from zips\n"
+ + "group by state having sum(pop) > 12000000")
+ .returns("STATE=NY; C=1596\n"
+ + "STATE=TX; C=1676\n"
+ + "STATE=FL; C=826\n"
+ + "STATE=CA; C=1523\n")
+ .queryContains(
+ mongoChecker(
+ "{$project: {STATE: '$state', POP: '$pop'}}",
+ "{$group: {_id: '$STATE', C: {$sum: 1}, _2: {$sum: '$POP'}}}",
+ "{$project: {STATE: '$_id', C: '$C', _2: '$_2'}}",
+ "{\n"
+ + " $match: {\n"
+ + " _2: {\n"
+ + " $gt: 12000000\n"
+ + " }\n"
+ + " }\n"
+ + "}",
+ "{$project: {STATE: 1, C: 1}}"));
}
@Test public void testGroupByMinMaxSum() {
assertModel(MODEL)
- .query("select count(*) as c, state,\n"
- + " min(pop) as min_pop, max(pop) as max_pop, sum(pop) as sum_pop\n"
- + "from zips group by state order by state")
- .limit(2)
- .returns("C=3; STATE=AK; MIN_POP=23238; MAX_POP=32383; SUM_POP=80568\n"
- + "C=3; STATE=AL; MIN_POP=42124; MAX_POP=44165; SUM_POP=130151\n")
- .queryContains(
- mongoChecker(
- "{$project: {POP: '$pop', STATE: '$state'}}",
- "{$group: {_id: '$STATE', C: {$sum: 1}, MIN_POP: {$min: '$POP'}, MAX_POP: {$max: '$POP'}, SUM_POP: {$sum: '$POP'}}}",
- "{$project: {STATE: '$_id', C: '$C', MIN_POP: '$MIN_POP', MAX_POP: '$MAX_POP', SUM_POP: '$SUM_POP'}}",
- "{$project: {C: 1, STATE: 1, MIN_POP: 1, MAX_POP: 1, SUM_POP: 1}}",
- "{$sort: {STATE: 1}}"));
+ .query("select count(*) as c, state,\n"
+ + " min(pop) as min_pop, max(pop) as max_pop, sum(pop) as sum_pop\n"
+ + "from zips group by state order by state")
+ .limit(2)
+ .returns("C=3; STATE=AK; MIN_POP=23238; MAX_POP=32383; SUM_POP=80568\n"
+ + "C=3; STATE=AL; MIN_POP=42124; MAX_POP=44165; SUM_POP=130151\n")
+ .queryContains(
+ mongoChecker(
+ "{$project: {POP: '$pop', STATE: '$state'}}",
+ "{$group: {_id: '$STATE', C: {$sum: 1}, MIN_POP: {$min: '$POP'}, MAX_POP: {$max: '$POP'}, SUM_POP: {$sum: '$POP'}}}",
+ "{$project: {STATE: '$_id', C: '$C', MIN_POP: '$MIN_POP', MAX_POP: '$MAX_POP', SUM_POP: '$SUM_POP'}}",
+ "{$project: {C: 1, STATE: 1, MIN_POP: 1, MAX_POP: 1, SUM_POP: 1}}",
+ "{$sort: {STATE: 1}}"));
}
@Test public void testGroupComposite() {
assertModel(MODEL)
- .query("select count(*) as c, state, city from zips\n"
- + "group by state, city\n"
- + "order by c desc, city\n"
- + "limit 2")
- .returns("C=1; STATE=SD; CITY=ABERDEEN\n"
- + "C=1; STATE=SC; CITY=AIKEN\n")
- .queryContains(
- mongoChecker(
- "{$project: {CITY: '$city', STATE: '$state'}}",
- "{$group: {_id: {CITY: '$CITY', STATE: '$STATE'}, C: {$sum: 1}}}",
- "{$project: {_id: 0, CITY: '$_id.CITY', STATE: '$_id.STATE', C: '$C'}}",
- "{$sort: {C: -1, CITY: 1}}",
- "{$limit: 2}",
- "{$project: {C: 1, STATE: 1, CITY: 1}}"));
+ .query("select count(*) as c, state, city from zips\n"
+ + "group by state, city\n"
+ + "order by c desc, city\n"
+ + "limit 2")
+ .returns("C=1; STATE=SD; CITY=ABERDEEN\n"
+ + "C=1; STATE=SC; CITY=AIKEN\n")
+ .queryContains(
+ mongoChecker(
+ "{$project: {CITY: '$city', STATE: '$state'}}",
+ "{$group: {_id: {CITY: '$CITY', STATE: '$STATE'}, C: {$sum: 1}}}",
+ "{$project: {_id: 0, CITY: '$_id.CITY', STATE: '$_id.STATE', C: '$C'}}",
+ "{$sort: {C: -1, CITY: 1}}",
+ "{$limit: 2}",
+ "{$project: {C: 1, STATE: 1, CITY: 1}}"));
}
@Ignore("broken; [CALCITE-2115] is logged to fix it")
@Test public void testDistinctCount() {
assertModel(MODEL)
- .query("select state, count(distinct city) as cdc from zips\n"
- + "where state in ('CA', 'TX') group by state order by state")
- .returns("STATE=CA; CDC=1072\n"
- + "STATE=TX; CDC=1233\n")
- .queryContains(
- mongoChecker(
- "{\n"
- + " \"$match\": {\n"
- + " \"$or\": [\n"
- + " {\n"
- + " \"state\": \"CA\"\n"
- + " },\n"
- + " {\n"
- + " \"state\": \"TX\"\n"
- + " }\n"
- + " ]\n"
- + " }\n"
- + "}",
- "{$project: {CITY: '$city', STATE: '$state'}}",
- "{$group: {_id: {CITY: '$CITY', STATE: '$STATE'}}}",
- "{$project: {_id: 0, CITY: '$_id.CITY', STATE: '$_id.STATE'}}",
- "{$group: {_id: '$STATE', CDC: {$sum: {$cond: [ {$eq: ['CITY', null]}, 0, 1]}}}}",
- "{$project: {STATE: '$_id', CDC: '$CDC'}}",
- "{$sort: {STATE: 1}}"));
+ .query("select state, count(distinct city) as cdc from zips\n"
+ + "where state in ('CA', 'TX') group by state order by state")
+ .returns("STATE=CA; CDC=1072\n"
+ + "STATE=TX; CDC=1233\n")
+ .queryContains(
+ mongoChecker(
+ "{\n"
+ + " \"$match\": {\n"
+ + " \"$or\": [\n"
+ + " {\n"
+ + " \"state\": \"CA\"\n"
+ + " },\n"
+ + " {\n"
+ + " \"state\": \"TX\"\n"
+ + " }\n"
+ + " ]\n"
+ + " }\n"
+ + "}",
+ "{$project: {CITY: '$city', STATE: '$state'}}",
+ "{$group: {_id: {CITY: '$CITY', STATE: '$STATE'}}}",
+ "{$project: {_id: 0, CITY: '$_id.CITY', STATE: '$_id.STATE'}}",
+ "{$group: {_id: '$STATE', CDC: {$sum: {$cond: [ {$eq: ['CITY', null]}, 0, 1]}}}}",
+ "{$project: {STATE: '$_id', CDC: '$CDC'}}",
+ "{$sort: {STATE: 1}}"));
}
@Test public void testDistinctCountOrderBy() {
@@ -592,52 +592,52 @@ public class MongoAdapterTest implements SchemaFactory {
// https://github.com/fakemongo/fongo/issues/152
MongoAssertions.assumeRealMongoInstance();
assertModel(MODEL)
- .query("select state, count(distinct city) as cdc\n"
- + "from zips\n"
- + "group by state\n"
- + "order by cdc desc, state\n"
- + "limit 5")
- .returns("STATE=AK; CDC=3\n"
- + "STATE=AL; CDC=3\n"
- + "STATE=AR; CDC=3\n"
- + "STATE=AZ; CDC=3\n"
- + "STATE=CA; CDC=3\n")
- .queryContains(
- mongoChecker(
- "{$project: {CITY: '$city', STATE: '$state'}}",
- "{$group: {_id: {CITY: '$CITY', STATE: '$STATE'}}}",
- "{$project: {_id: 0, CITY: '$_id.CITY', STATE: '$_id.STATE'}}",
- "{$group: {_id: '$STATE', CDC: {$sum: {$cond: [ {$eq: ['CITY', null]}, 0, 1]}}}}",
- "{$project: {STATE: '$_id', CDC: '$CDC'}}",
- "{$sort: {CDC: -1, STATE: 1}}",
- "{$limit: 5}"));
+ .query("select state, count(distinct city) as cdc\n"
+ + "from zips\n"
+ + "group by state\n"
+ + "order by cdc desc, state\n"
+ + "limit 5")
+ .returns("STATE=AK; CDC=3\n"
+ + "STATE=AL; CDC=3\n"
+ + "STATE=AR; CDC=3\n"
+ + "STATE=AZ; CDC=3\n"
+ + "STATE=CA; CDC=3\n")
+ .queryContains(
+ mongoChecker(
+ "{$project: {CITY: '$city', STATE: '$state'}}",
+ "{$group: {_id: {CITY: '$CITY', STATE: '$STATE'}}}",
+ "{$project: {_id: 0, CITY: '$_id.CITY', STATE: '$_id.STATE'}}",
+ "{$group: {_id: '$STATE', CDC: {$sum: {$cond: [ {$eq: ['CITY', null]}, 0, 1]}}}}",
+ "{$project: {STATE: '$_id', CDC: '$CDC'}}",
+ "{$sort: {CDC: -1, STATE: 1}}",
+ "{$limit: 5}"));
}
@Ignore("broken; [CALCITE-2115] is logged to fix it")
@Test public void testProject() {
assertModel(MODEL)
- .query("select state, city, 0 as zero from zips order by state, city")
- .limit(2)
- .returns("STATE=AK; CITY=AKHIOK; ZERO=0\n"
- + "STATE=AK; CITY=AKIACHAK; ZERO=0\n")
- .queryContains(
- mongoChecker(
- "{$project: {CITY: '$city', STATE: '$state'}}",
- "{$sort: {STATE: 1, CITY: 1}}",
- "{$project: {STATE: 1, CITY: 1, ZERO: {$literal: 0}}}"));
+ .query("select state, city, 0 as zero from zips order by state, city")
+ .limit(2)
+ .returns("STATE=AK; CITY=AKHIOK; ZERO=0\n"
+ + "STATE=AK; CITY=AKIACHAK; ZERO=0\n")
+ .queryContains(
+ mongoChecker(
+ "{$project: {CITY: '$city', STATE: '$state'}}",
+ "{$sort: {STATE: 1, CITY: 1}}",
+ "{$project: {STATE: 1, CITY: 1, ZERO: {$literal: 0}}}"));
}
@Test public void testFilter() {
assertModel(MODEL)
- .query("select state, city from zips where state = 'CA'")
- .limit(3)
- .returnsUnordered("STATE=CA; CITY=LOS ANGELES",
- "STATE=CA; CITY=BELL GARDENS",
- "STATE=CA; CITY=NORWALK")
- .explainContains("PLAN=MongoToEnumerableConverter\n"
- + " MongoProject(STATE=[CAST(ITEM($0, 'state')):VARCHAR(2) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\"], CITY=[CAST(ITEM($0, 'city')):VARCHAR(20) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\"])\n"
- + " MongoFilter(condition=[=(CAST(ITEM($0, 'state')):VARCHAR(2) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\", 'CA')])\n"
- + " MongoTableScan(table=[[mongo_raw, zips]])");
+ .query("select state, city from zips where state = 'CA'")
+ .limit(3)
+ .returnsUnordered("STATE=CA; CITY=LOS ANGELES",
+ "STATE=CA; CITY=BELL GARDENS",
+ "STATE=CA; CITY=NORWALK")
+ .explainContains("PLAN=MongoToEnumerableConverter\n"
+ + " MongoProject(STATE=[CAST(ITEM($0, 'state')):VARCHAR(2) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\"], CITY=[CAST(ITEM($0, 'city')):VARCHAR(20) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\"])\n"
+ + " MongoFilter(condition=[=(CAST(ITEM($0, 'state')):VARCHAR(2) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\", 'CA')])\n"
+ + " MongoTableScan(table=[[mongo_raw, zips]])");
}
/** MongoDB's predicates are handed (they can only accept literals on the
@@ -645,18 +645,18 @@ public class MongoAdapterTest implements SchemaFactory {
* ways around. */
@Test public void testFilterReversed() {
assertModel(MODEL)
- .query("select state, city from zips where 'WI' < state order by state, city")
- .limit(3)
- .returnsOrdered("STATE=WV; CITY=BECKLEY",
- "STATE=WV; CITY=ELM GROVE",
- "STATE=WV; CITY=STAR CITY");
+ .query("select state, city from zips where 'WI' < state order by state, city")
+ .limit(3)
+ .returnsOrdered("STATE=WV; CITY=BECKLEY",
+ "STATE=WV; CITY=ELM GROVE",
+ "STATE=WV; CITY=STAR CITY");
assertModel(MODEL)
- .query("select state, city from zips where state > 'WI' order by state, city")
- .limit(3)
- .returnsOrdered("STATE=WV; CITY=BECKLEY",
- "STATE=WV; CITY=ELM GROVE",
- "STATE=WV; CITY=STAR CITY");
+ .query("select state, city from zips where state > 'WI' order by state, city")
+ .limit(3)
+ .returnsOrdered("STATE=WV; CITY=BECKLEY",
+ "STATE=WV; CITY=ELM GROVE",
+ "STATE=WV; CITY=STAR CITY");
}
/** MongoDB's predicates are handed (they can only accept literals on the
@@ -684,13 +684,13 @@ public class MongoAdapterTest implements SchemaFactory {
private void checkPredicate(int expected, String q) {
assertModel(MODEL)
- .query("select count(*) as c from zips\n"
- + q)
- .returns("C=" + expected + "\n");
+ .query("select count(*) as c from zips\n"
+ + q)
+ .returns("C=" + expected + "\n");
assertModel(MODEL)
- .query("select * from zips\n"
- + q)
- .returnsCount(expected);
+ .query("select * from zips\n"
+ + q)
+ .returnsCount(expected);
}
/** Test case for
@@ -713,22 +713,22 @@ public class MongoAdapterTest implements SchemaFactory {
// "ownerId" : "531e7789e4b0853ddb861313"
// } )
assertModel("{\n"
- + " version: '1.0',\n"
- + " defaultSchema: 'test',\n"
- + " schemas: [\n"
- + " {\n"
- + " type: 'custom',\n"
- + " name: 'test',\n"
- + " factory: 'org.apache.calcite.adapter.mongodb.MongoSchemaFactory',\n"
- + " operand: {\n"
- + " host: 'localhost',\n"
- + " database: 'test'\n"
- + " }\n"
- + " }\n"
- + " ]\n"
- + "}")
- .query("select cast(_MAP['date'] as DATE) from \"datatypes\"")
- .returnsUnordered("EXPR$0=2012-09-05");
+ + " version: '1.0',\n"
+ + " defaultSchema: 'test',\n"
+ + " schemas: [\n"
+ + " {\n"
+ + " type: 'custom',\n"
+ + " name: 'test',\n"
+ + " factory: 'org.apache.calcite.adapter.mongodb.MongoSchemaFactory',\n"
+ + " operand: {\n"
+ + " host: 'localhost',\n"
+ + " database: 'test'\n"
+ + " }\n"
+ + " }\n"
+ + " ]\n"
+ + "}")
+ .query("select cast(_MAP['date'] as DATE) from \"datatypes\"")
+ .returnsUnordered("EXPR$0=2012-09-05");
}
/** Test case for
@@ -762,11 +762,11 @@ public class MongoAdapterTest implements SchemaFactory {
return new Function<List, Void>() {
public Void apply(List actual) {
Object[] actualArray =
- actual == null || actual.isEmpty()
- ? null
- : ((List) actual.get(0)).toArray();
+ actual == null || actual.isEmpty()
+ ? null
+ : ((List) actual.get(0)).toArray();
CalciteAssert.assertArrayEqual("expected MongoDB query not found",
- strings, actualArray);
+ strings, actualArray);
return null;
}
};
http://git-wip-us.apache.org/repos/asf/calcite/blob/6e8bb5a1/mongodb/src/test/java/org/apache/calcite/adapter/mongodb/MongoDatabasePolicy.java
----------------------------------------------------------------------
diff --git a/mongodb/src/test/java/org/apache/calcite/adapter/mongodb/MongoDatabasePolicy.java b/mongodb/src/test/java/org/apache/calcite/adapter/mongodb/MongoDatabasePolicy.java
new file mode 100644
index 0000000..52a0715
--- /dev/null
+++ b/mongodb/src/test/java/org/apache/calcite/adapter/mongodb/MongoDatabasePolicy.java
@@ -0,0 +1,84 @@
+/*
+ * 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.adapter.mongodb;
+
+import org.apache.calcite.test.MongoAssertions;
+
+import com.github.fakemongo.Fongo;
+
+import com.google.common.base.Preconditions;
+
+import com.mongodb.MongoClient;
+import com.mongodb.client.MongoDatabase;
+
+import org.junit.rules.ExternalResource;
+
+/**
+ * Instantiates a new connection to Fongo (or Mongo) database depending on the
+ * current profile (unit or integration tests).
+ *
+ * <p>By default, this rule is executed as part of a unit test and in-memory database
+ * <a href="https://github.com/fakemongo/fongo">Fongo</a> is used.
+ *
+ * <p>However, if the maven profile is set to {@code IT} (eg. via command line
+ * {@code $ mvn -Pit install}) this rule will connect to an existing (external)
+ * Mongo instance ({@code localhost}).
+ */
+class MongoDatabasePolicy extends ExternalResource {
+
+ private static final String DB_NAME = "test";
+
+ private final MongoDatabase database;
+ private final MongoClient client;
+
+ private MongoDatabasePolicy(MongoClient client) {
+ this.client = Preconditions.checkNotNull(client, "client");
+ this.database = client.getDatabase(DB_NAME);
+ }
+
+ /**
+ * Creates an instance based on current maven profile (as defined by {@code -Pit}).
+ *
+ * @return new instance of the policy to be used by unit tests
+ */
+ static MongoDatabasePolicy create() {
+ final MongoClient client;
+ if (MongoAssertions.useMongo()) {
+ // use to real client (connects to mongo)
+ client = new MongoClient();
+ } else if (MongoAssertions.useFongo()) {
+ // in-memory DB (fake Mongo)
+ client = new Fongo(MongoDatabasePolicy.class.getSimpleName()).getMongo();
+ } else {
+ throw new UnsupportedOperationException("I can only connect to Mongo or Fongo instances");
+ }
+
+ return new MongoDatabasePolicy(client);
+ }
+
+
+ MongoDatabase database() {
+ return database;
+ }
+
+ @Override protected void after() {
+ client.close();
+ }
+
+}
+
+// End MongoDatabasePolicy.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/6e8bb5a1/mongodb/src/test/java/org/apache/calcite/adapter/mongodb/MongoDatabaseRule.java
----------------------------------------------------------------------
diff --git a/mongodb/src/test/java/org/apache/calcite/adapter/mongodb/MongoDatabaseRule.java b/mongodb/src/test/java/org/apache/calcite/adapter/mongodb/MongoDatabaseRule.java
deleted file mode 100644
index d73f503..0000000
--- a/mongodb/src/test/java/org/apache/calcite/adapter/mongodb/MongoDatabaseRule.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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.adapter.mongodb;
-
-import org.apache.calcite.test.MongoAssertions;
-
-import com.github.fakemongo.Fongo;
-
-import com.google.common.base.Preconditions;
-
-import com.mongodb.MongoClient;
-import com.mongodb.client.MongoDatabase;
-
-import org.junit.rules.ExternalResource;
-
-/**
- * Instantiates new connection to fongo (or mongo) database depending on current profile
- * (unit or integration tests).
- *
- * By default, this rule is executed as part of a unit test and in-memory database
- * <a href="https://github.com/fakemongo/fongo">fongo</a> is used.
- *
- * <p>However, if maven profile is set to {@code IT} (eg. via command line
- * {@code $ mvn -Pit install}) this rule will connect to existing (external)
- * mongo instance ({@code localhost})</p>
- *
- */
-class MongoDatabaseRule extends ExternalResource {
-
- private static final String DB_NAME = "test";
-
- private final MongoDatabase database;
- private final MongoClient client;
-
- private MongoDatabaseRule(MongoClient client) {
- this.client = Preconditions.checkNotNull(client, "client");
- this.database = client.getDatabase(DB_NAME);
- }
-
- /**
- * Create an instance based on current maven profile (as defined by {@code -Pit}).
- * @return new instance of the rule to be used by unit tests
- */
- static MongoDatabaseRule create() {
- final MongoClient client;
- if (MongoAssertions.useMongo()) {
- // use to real client (connects to mongo)
- client = new MongoClient();
- } else if (MongoAssertions.useFongo()) {
- // in-memory DB (fake Mongo)
- client = new Fongo(MongoDatabaseRule.class.getSimpleName()).getMongo();
- } else {
- throw new UnsupportedOperationException("I can only connect to Mongo or Fongo instances");
- }
-
- return new MongoDatabaseRule(client);
- }
-
-
- MongoDatabase database() {
- return database;
- }
-
- @Override protected void after() {
- client.close();
- }
-
-}
-
-// End MongoDatabaseRule.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/6e8bb5a1/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 207a3b9..218dba3 100644
--- a/mongodb/src/test/java/org/apache/calcite/test/MongoAdapterIT.java
+++ b/mongodb/src/test/java/org/apache/calcite/test/MongoAdapterIT.java
@@ -25,10 +25,10 @@ import static org.junit.Assume.assumeTrue;
/**
* Used to trigger integration tests from maven (thus class name is suffixed with {@code IT}).
*
- * If you want to run integration tests from IDE manually set
+ * <p>If you want to run integration tests from the, IDE manually set the
* {@code -Dcalcite.integrationTest=true} system property.
- * <br>
- * For command line use:
+ *
+ * <p>For command line use:
* <pre>
* $ mvn install -Pit
* </pre>
http://git-wip-us.apache.org/repos/asf/calcite/blob/6e8bb5a1/mongodb/src/test/resources/zips-mini.json
----------------------------------------------------------------------
diff --git a/mongodb/src/test/resources/zips-mini.json b/mongodb/src/test/resources/zips-mini.json
index d70eadc..858117a 100644
--- a/mongodb/src/test/resources/zips-mini.json
+++ b/mongodb/src/test/resources/zips-mini.json
@@ -146,4 +146,4 @@
{ "_id" : "98310", "city" : "BREMERTON", "loc" : [ -122.629913, 47.601916 ], "pop" : 49057, "state" : "WA" }
{ "_id" : "99504", "city" : "ANCHORAGE", "loc" : [ -149.74467, 61.203696 ], "pop" : 32383, "state" : "AK" }
{ "_id" : "99709", "city" : "FAIRBANKS", "loc" : [ -147.846917, 64.85437 ], "pop" : 23238, "state" : "AK" }
-{ "_id" : "99801", "city" : "JUNEAU", "loc" : [ -134.529429, 58.362767 ], "pop" : 24947, "state" : "AK" }
\ No newline at end of file
+{ "_id" : "99801", "city" : "JUNEAU", "loc" : [ -134.529429, 58.362767 ], "pop" : 24947, "state" : "AK" }