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 3755eb5  [CALCITE-3912] Incorrect mapping parsing when properties have 
same name as reserved keywords in ElasticSearch
3755eb5 is described below

commit 3755eb5871860f1fd5dc51990129784caa8ac0a4
Author: Andrei Sereda <[email protected]>
AuthorDate: Fri Apr 10 12:22:22 2020 -0400

    [CALCITE-3912] Incorrect mapping parsing when properties have same name as 
reserved keywords in ElasticSearch
    
    If a property has name `type` or `properties` ES adapter doesn't correctly 
process the mapping structure. It doesn't correctly identify the leafs 
(properties)
    in JSON mapping.
---
 .../adapter/elasticsearch/ElasticsearchJson.java     |  9 +++++++--
 .../adapter/elasticsearch/ElasticsearchJsonTest.java | 20 ++++++++++++++++++++
 2 files changed, 27 insertions(+), 2 deletions(-)

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 e12dcc6..7e1b35f 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
@@ -45,6 +45,7 @@ import java.util.Optional;
 import java.util.Set;
 import java.util.function.BiConsumer;
 import java.util.function.Consumer;
+import java.util.function.Predicate;
 import java.util.stream.StreamSupport;
 
 import static java.util.Collections.unmodifiableMap;
@@ -107,13 +108,17 @@ final class ElasticsearchJson {
       return;
     }
 
-    if (mapping.has("properties")) {
+    // check if we have reached actual field mapping (leaf of JSON tree)
+    Predicate<JsonNode> isLeaf = node -> node.path("type").isValueNode();
+
+    if (mapping.path("properties").isObject()
+        && !isLeaf.test(mapping.path("properties"))) {
       // recurse
       visitMappingProperties(path, (ObjectNode) mapping.get("properties"), 
consumer);
       return;
     }
 
-    if (mapping.has("type")) {
+    if (isLeaf.test(mapping)) {
       // this is leaf (register field / type mapping)
       consumer.accept(String.join(".", path), mapping.get("type").asText());
       return;
diff --git 
a/elasticsearch/src/test/java/org/apache/calcite/adapter/elasticsearch/ElasticsearchJsonTest.java
 
b/elasticsearch/src/test/java/org/apache/calcite/adapter/elasticsearch/ElasticsearchJsonTest.java
index 380a49b..10c6cd5 100644
--- 
a/elasticsearch/src/test/java/org/apache/calcite/adapter/elasticsearch/ElasticsearchJsonTest.java
+++ 
b/elasticsearch/src/test/java/org/apache/calcite/adapter/elasticsearch/ElasticsearchJsonTest.java
@@ -18,11 +18,13 @@ package org.apache.calcite.adapter.elasticsearch;
 
 import com.fasterxml.jackson.core.JsonParser;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
 
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -171,4 +173,22 @@ class ElasticsearchJsonTest {
     assertThat(rows.get(1).get("max"), is(42));
   }
 
+  /**
+   * Validate that property names which are reserved keywords ES
+   * are correctly mapped (eg. {@code type} or {@code properties})
+   */
+  @Test void reservedKeywordMapping() throws Exception {
+    // have special property names: type and properties
+    ObjectNode mapping = mapper.readValue("{properties:{"
+        + "type:{type:'text'},"
+        + "keyword:{type:'keyword'},"
+        + "properties:{type:'long'}"
+        + "}}", ObjectNode.class);
+    Map<String, String> result = new HashMap<>();
+    ElasticsearchJson.visitMappingProperties(mapping, result::put);
+
+    assertThat(result.get("type"), is("text"));
+    assertThat(result.get("keyword"), is("keyword"));
+    assertThat(result.get("properties"), is("long"));
+  }
 }

Reply via email to