You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by fe...@apache.org on 2021/07/08 02:51:14 UTC

[calcite] branch master updated: [CALCITE-3775] Implicit lookup methods in SimpleCalciteSchema ignore case sensitivity parameter (Alon Eldar)

This is an automated email from the ASF dual-hosted git repository.

fengzhu 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 138c2bc  [CALCITE-3775] Implicit lookup methods in SimpleCalciteSchema ignore case sensitivity parameter (Alon Eldar)
138c2bc is described below

commit 138c2bc4c5cf6a957b7ba66c8e166288e28a7a81
Author: Alon Eldar <al...@neuroblade.ai>
AuthorDate: Mon Jul 5 18:33:18 2021 +0300

    [CALCITE-3775] Implicit lookup methods in SimpleCalciteSchema ignore
    case sensitivity parameter (Alon Eldar)
    
    rebased original  PR #1792 from Feb2020.
---
 .../apache/calcite/jdbc/SimpleCalciteSchema.java   | 65 ++++++++++++++++++----
 .../java/org/apache/calcite/test/JdbcTest.java     | 44 +++++++++++++++
 2 files changed, 97 insertions(+), 12 deletions(-)

diff --git a/core/src/main/java/org/apache/calcite/jdbc/SimpleCalciteSchema.java b/core/src/main/java/org/apache/calcite/jdbc/SimpleCalciteSchema.java
index 564240e..dc67c2a 100644
--- a/core/src/main/java/org/apache/calcite/jdbc/SimpleCalciteSchema.java
+++ b/core/src/main/java/org/apache/calcite/jdbc/SimpleCalciteSchema.java
@@ -34,6 +34,8 @@ import org.checkerframework.checker.nullness.qual.Nullable;
 
 import java.util.Collection;
 import java.util.List;
+import java.util.Locale;
+import java.util.Set;
 
 /**
  * A concrete implementation of {@link org.apache.calcite.jdbc.CalciteSchema}
@@ -74,33 +76,72 @@ class SimpleCalciteSchema extends CalciteSchema {
     return calciteSchema;
   }
 
+  private @Nullable String caseInsensitiveLookup(Set<String> candidates, String name) {
+    // Exact string lookup
+    if (candidates.contains(name)) {
+      return name;
+    }
+    // Upper case string lookup
+    final String upperCaseName = name.toUpperCase(Locale.ROOT);
+    if (candidates.contains(upperCaseName)) {
+      return upperCaseName;
+    }
+    // Lower case string lookup
+    final String lowerCaseName = name.toLowerCase(Locale.ROOT);
+    if (candidates.contains(lowerCaseName)) {
+      return lowerCaseName;
+    }
+    // Fall through: Set iteration
+    for (String candidate: candidates) {
+      if (candidate.equalsIgnoreCase(name)) {
+        return candidate;
+      }
+    }
+    return null;
+  }
+
   @Override protected @Nullable CalciteSchema getImplicitSubSchema(String schemaName,
       boolean caseSensitive) {
     // Check implicit schemas.
-    Schema s = schema.getSubSchema(schemaName);
-    if (s != null) {
-      return new SimpleCalciteSchema(this, s, schemaName);
+    final String schemaName2 = caseSensitive ? schemaName : caseInsensitiveLookup(
+        schema.getSubSchemaNames(), schemaName);
+    if (schemaName2 == null) {
+      return null;
     }
-    return null;
+    final Schema s = schema.getSubSchema(schemaName2);
+    if (s == null) {
+      return null;
+    }
+    return new SimpleCalciteSchema(this, s, schemaName2);
   }
 
   @Override protected @Nullable TableEntry getImplicitTable(String tableName,
       boolean caseSensitive) {
     // Check implicit tables.
-    Table table = schema.getTable(tableName);
-    if (table != null) {
-      return tableEntry(tableName, table);
+    final String tableName2 = caseSensitive ? tableName : caseInsensitiveLookup(
+        schema.getTableNames(), tableName);
+    if (tableName2 == null) {
+      return null;
     }
-    return null;
+    final Table table = schema.getTable(tableName2);
+    if (table == null) {
+      return null;
+    }
+    return tableEntry(tableName2, table);
   }
 
   @Override protected @Nullable TypeEntry getImplicitType(String name, boolean caseSensitive) {
     // Check implicit types.
-    RelProtoDataType type = schema.getType(name);
-    if (type != null) {
-      return typeEntry(name, type);
+    final String name2 = caseSensitive ? name : caseInsensitiveLookup(
+        schema.getTypeNames(), name);
+    if (name2 == null) {
+      return null;
     }
-    return null;
+    final RelProtoDataType type = schema.getType(name2);
+    if (type == null) {
+      return null;
+    }
+    return typeEntry(name2, type);
   }
 
   @Override protected void addImplicitSubSchemaToBuilder(
diff --git a/core/src/test/java/org/apache/calcite/test/JdbcTest.java b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
index a84c197..a51896d 100644
--- a/core/src/test/java/org/apache/calcite/test/JdbcTest.java
+++ b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
@@ -60,6 +60,7 @@ import org.apache.calcite.rel.logical.LogicalTableModify;
 import org.apache.calcite.rel.rules.CoreRules;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeFactory;
+import org.apache.calcite.rel.type.RelProtoDataType;
 import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.runtime.FlatLists;
 import org.apache.calcite.runtime.Hook;
@@ -6912,6 +6913,49 @@ public class JdbcTest {
     assertThat(aSchema.getSubSchemaNames().size(), is(2));
   }
 
+  @Test public void testCaseSensitiveConfigurableSimpleCalciteSchema() throws Exception {
+    final SchemaPlus rootSchema = CalciteSchema.createRootSchema(false, false).plus();
+    // create schema "/a"
+    final Map<String, Schema> dummySubSchemaMap = new HashMap<>();
+    final Map<String, Table> dummyTableMap = new HashMap<>();
+    final Map<String, RelProtoDataType> dummyTypeMap = new HashMap<>();
+    final SchemaPlus dummySchema = rootSchema.add("dummy",
+        new AbstractSchema() {
+          @Override protected Map<String, Schema> getSubSchemaMap() {
+            return dummySubSchemaMap;
+          }
+
+          @Override protected Map<String, Table> getTableMap() {
+            return dummyTableMap;
+          }
+
+          @Override protected Map<String, RelProtoDataType> getTypeMap() {
+            return dummyTypeMap;
+          }
+        });
+    // add implicit schema "/dummy/abc"
+    dummySubSchemaMap.put("abc", new AbstractSchema());
+    // add implicit table "/dummy/xyz"
+    dummyTableMap.put("xyz", new AbstractTable() {
+      @Override public RelDataType getRowType(RelDataTypeFactory typeFactory) {
+        return null;
+      }
+    });
+    // add implicit table "/dummy/myType"
+    dummyTypeMap.put("myType", factory -> factory.builder().build());
+
+    final CalciteSchema dummyCalciteSchema = CalciteSchema.from(dummySchema);
+    assertThat(dummyCalciteSchema.getSubSchema("abc", true), notNullValue());
+    assertThat(dummyCalciteSchema.getSubSchema("aBC", false), notNullValue());
+    assertThat(dummyCalciteSchema.getSubSchema("aBC", true), nullValue());
+    assertThat(dummyCalciteSchema.getTable("xyz", true), notNullValue());
+    assertThat(dummyCalciteSchema.getTable("XyZ", false), notNullValue());
+    assertThat(dummyCalciteSchema.getTable("XyZ", true), nullValue());
+    assertThat(dummyCalciteSchema.getType("myType", true), notNullValue());
+    assertThat(dummyCalciteSchema.getType("MytYpE", false), notNullValue());
+    assertThat(dummyCalciteSchema.getType("MytYpE", true), nullValue());
+  }
+
   @Test void testSimpleCalciteSchemaWithView() throws Exception {
     final SchemaPlus rootSchema = CalciteSchema.createRootSchema(false, false).plus();