This is an automated email from the ASF dual-hosted git repository.
sereda pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/master by this push:
new e93522a [CALCITE-2863] ElasticSearch Adapter. "select *" may return
empty dictionary for document table
e93522a is described below
commit e93522a8f374d9269e6657cd23603377762b4bc1
Author: Andrei Sereda <[email protected]>
AuthorDate: Mon Feb 25 23:04:55 2019 -0500
[CALCITE-2863] ElasticSearch Adapter. "select *" may return empty
dictionary for document table
In some circumstances (eg. order by clause) `select *` would return `{}`.
---
.../elasticsearch/ElasticsearchConstants.java | 9 ++++++++
.../elasticsearch/ElasticsearchEnumerators.java | 8 +++----
.../adapter/elasticsearch/ElasticsearchJson.java | 6 +++++
.../elasticsearch/ElasticsearchProject.java | 2 +-
.../elasticsearch/ElasticSearchAdapterTest.java | 9 +++++---
.../adapter/elasticsearch/Projection2Test.java | 26 ++++++++++++++++++++--
6 files changed, 50 insertions(+), 10 deletions(-)
diff --git
a/elasticsearch/src/main/java/org/apache/calcite/adapter/elasticsearch/ElasticsearchConstants.java
b/elasticsearch/src/main/java/org/apache/calcite/adapter/elasticsearch/ElasticsearchConstants.java
index da875d5..678cab5 100644
---
a/elasticsearch/src/main/java/org/apache/calcite/adapter/elasticsearch/ElasticsearchConstants.java
+++
b/elasticsearch/src/main/java/org/apache/calcite/adapter/elasticsearch/ElasticsearchConstants.java
@@ -40,6 +40,15 @@ interface ElasticsearchConstants {
Set<String> META_COLUMNS = ImmutableSet.of(UID, ID, TYPE, INDEX);
+ /**
+ * Detects {@code select * from elastic} types of field name (select star).
+ * @param name name of the field
+ * @return {@code true} if this field represents whole raw, {@code false}
otherwise
+ */
+ static boolean isSelectAll(String name) {
+ return "_MAP".equals(name);
+ }
+
}
// End ElasticsearchConstants.java
diff --git
a/elasticsearch/src/main/java/org/apache/calcite/adapter/elasticsearch/ElasticsearchEnumerators.java
b/elasticsearch/src/main/java/org/apache/calcite/adapter/elasticsearch/ElasticsearchEnumerators.java
index 054d85c..16da626 100644
---
a/elasticsearch/src/main/java/org/apache/calcite/adapter/elasticsearch/ElasticsearchEnumerators.java
+++
b/elasticsearch/src/main/java/org/apache/calcite/adapter/elasticsearch/ElasticsearchEnumerators.java
@@ -23,6 +23,7 @@ import org.apache.calcite.linq4j.tree.Primitive;
import java.util.Date;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
/**
* Util functions which convert
@@ -101,13 +102,12 @@ class ElasticsearchEnumerators {
static Function1<ElasticsearchJson.SearchHit, Object> getter(
List<Map.Entry<String, Class>> fields, Map<String, String> mapping) {
+ Objects.requireNonNull(fields, "fields");
//noinspection unchecked
final Function1 getter;
- if (fields == null || fields.size() == 1 &&
"_MAP".equals(fields.get(0).getKey())) {
- // select * from table
- getter = mapGetter();
- } else if (fields.size() == 1) {
+ if (fields.size() == 1) {
// select foo from table
+ // select * from table
getter = singletonGetter(fields.get(0).getKey(),
fields.get(0).getValue(), mapping);
} else {
// select a, b, c from table
diff --git
a/elasticsearch/src/main/java/org/apache/calcite/adapter/elasticsearch/ElasticsearchJson.java
b/elasticsearch/src/main/java/org/apache/calcite/adapter/elasticsearch/ElasticsearchJson.java
index eb9c011..320a32b 100644
---
a/elasticsearch/src/main/java/org/apache/calcite/adapter/elasticsearch/ElasticsearchJson.java
+++
b/elasticsearch/src/main/java/org/apache/calcite/adapter/elasticsearch/ElasticsearchJson.java
@@ -318,6 +318,12 @@ final class ElasticsearchJson {
Object valueOrNull(String name) {
Objects.requireNonNull(name, "name");
+
+ // for "select *" return whole document
+ if (ElasticsearchConstants.isSelectAll(name)) {
+ return sourceOrFields();
+ }
+
if (fields != null && fields.containsKey(name)) {
Object field = fields.get(name);
if (field instanceof Iterable) {
diff --git
a/elasticsearch/src/main/java/org/apache/calcite/adapter/elasticsearch/ElasticsearchProject.java
b/elasticsearch/src/main/java/org/apache/calcite/adapter/elasticsearch/ElasticsearchProject.java
index 82aff25..0fffd49 100644
---
a/elasticsearch/src/main/java/org/apache/calcite/adapter/elasticsearch/ElasticsearchProject.java
+++
b/elasticsearch/src/main/java/org/apache/calcite/adapter/elasticsearch/ElasticsearchProject.java
@@ -73,7 +73,7 @@ public class ElasticsearchProject extends Project implements
ElasticsearchRel {
implementor.addExpressionItemMapping(name,
ElasticsearchRules.stripQuotes(expr));
}
- hasSelectStar |= "_MAP".equals(name);
+ hasSelectStar |= ElasticsearchConstants.isSelectAll(name);
if (expr.equals(name)) {
fields.add(name);
diff --git
a/elasticsearch/src/test/java/org/apache/calcite/adapter/elasticsearch/ElasticSearchAdapterTest.java
b/elasticsearch/src/test/java/org/apache/calcite/adapter/elasticsearch/ElasticSearchAdapterTest.java
index 794cbe0..26812cb 100644
---
a/elasticsearch/src/test/java/org/apache/calcite/adapter/elasticsearch/ElasticSearchAdapterTest.java
+++
b/elasticsearch/src/test/java/org/apache/calcite/adapter/elasticsearch/ElasticSearchAdapterTest.java
@@ -263,7 +263,7 @@ public class ElasticSearchAdapterTest {
}
/**
- * Sorting directly on items without a view.
+ * Sorting (and aggregating) directly on items without a view.
*
* Queries of type: {@code select _MAP['a'] from elastic order by _MAP['b']}
*/
@@ -281,7 +281,10 @@ public class ElasticSearchAdapterTest {
"query:{'constant_score':{filter:{term:{state:'NY'}}}}",
"sort:[{city:'asc'}]",
String.format(Locale.ROOT, "size:%s",
ElasticsearchTransport.DEFAULT_FETCH_SIZE)))
- .returnsCount(3);
+ .returnsOrdered(
+ "_MAP={id=11226, city=BROOKLYN, loc=[-73.956985, 40.646694],
pop=111396, state=NY}",
+ "_MAP={id=11373, city=JACKSON HEIGHTS, loc=[-73.878551, 40.740388],
pop=88241, state=NY}",
+ "_MAP={id=10021, city=NEW YORK, loc=[-73.958805, 40.768476],
pop=106564, state=NY}");
CalciteAssert.that()
.with(newConnectionFactory())
@@ -322,7 +325,7 @@ public class ElasticSearchAdapterTest {
.with(newConnectionFactory())
.query("select max(_MAP['pop']), min(_MAP['pop']), _MAP['state'] from
elastic.zips "
+ "where _MAP['state'] = 'NY' group by _MAP['state'] order by
_MAP['state'] limit 3")
- .returnsCount(1);
+ .returns("EXPR$0=111396.0; EXPR$1=88241.0; EXPR$2=NY\n");
}
/**
diff --git
a/elasticsearch/src/test/java/org/apache/calcite/adapter/elasticsearch/Projection2Test.java
b/elasticsearch/src/test/java/org/apache/calcite/adapter/elasticsearch/Projection2Test.java
index ddbadc2..7731f2c 100644
---
a/elasticsearch/src/test/java/org/apache/calcite/adapter/elasticsearch/Projection2Test.java
+++
b/elasticsearch/src/test/java/org/apache/calcite/adapter/elasticsearch/Projection2Test.java
@@ -109,6 +109,21 @@ public class Projection2Test {
.returns("EXPR$0=1; EXPR$1=2; EXPR$2=3; EXPR$3=foo; EXPR$4=null;
EXPR$5=null\n");
}
+ @Test
+ public void projection3() {
+ CalciteAssert.that()
+ .with(newConnectionFactory())
+ .query(
+ String.format(Locale.ROOT, "select * from \"elastic\".\"%s\"",
NAME))
+ .returns("_MAP={a=1, b={a=2, b=3, c={a=foo}}}\n");
+
+ CalciteAssert.that()
+ .with(newConnectionFactory())
+ .query(
+ String.format(Locale.ROOT, "select *, _MAP['a'] from
\"elastic\".\"%s\"", NAME))
+ .returns("_MAP={a=1, b={a=2, b=3, c={a=foo}}}; EXPR$1=1\n");
+ }
+
/**
* Test that {@code _id} field is available when queried explicitly.
* @see <a
href="https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-id-field.html">ID
Field</a>
@@ -163,10 +178,17 @@ public class Projection2Test {
.returns(regexMatch("_id=\\p{Graph}+"));
// _id field not available implicitly
- final String sql5 = String.format(Locale.ROOT, "select * from
\"elastic\".\"%s\"", NAME);
factory
- .query(sql5)
+ .query(
+ String.format(Locale.ROOT, "select * from \"elastic\".\"%s\"",
NAME)
+ )
.returns(regexMatch("_MAP={a=1, b={a=2, b=3, c={a=foo}}}"));
+
+ factory
+ .query(
+ String.format(Locale.ROOT, "select *, _MAP['_id'] from
\"elastic\".\"%s\"", NAME)
+ )
+ .returns(regexMatch("_MAP={a=1, b={a=2, b=3, c={a=foo}}};
EXPR$1=\\p{Graph}+"));
}
/**