Uploaded image for project: 'Calcite'
  1. Calcite
  2. CALCITE-173

Case-insensitive table names are not supported for Casing.UNCHANGED

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • None
    • None
    • None

    Description

      While fixing (#168 | FLINK-168)/([#169|https://github.com/JulianHyde/optiq/issues/169] | FLINK-169) I realized `optiq` does not support case-insensitive table names for `Casing.UNCHANGED`.

      Here is the failing case (it does not yet exists in `optiq` test suite):

      ```java
      /** Tests using case-insensitive matching of table names */
      @Test public void testCaseInsensitiveTables() {
      final SqlTester tester1 = tester
      .withLex(ConnectionConfig.Lex.SQL_SERVER);
      tester1.checkQuery("select eMp.* from (select * from emp as EmP)");
      }
      ```

      ```
      Validator threw unexpected exception; query [select eMp.* from (select * from emp as EmP)]; exception [Unknown identifier 'eMp']; pos [line 1 col 8 thru line 1 col 8]
      ```

      I guess the cause is `OptiqCatalogReader` that tries to use `map.get`: `schema.compositeTableMap.get(name)`

      I see several possible solutions, however I do not have performance tests, thus I am not sure how to measure the impact.

      1) Add one more map that maps `name.toUpper() -> Table`. The problem is `equalsIgnoreCase` is not the same as comparing two strings converted to upper (or lower) case.
      See relevant comment in `String#equalsIgnoreCase`:

      ```
      // If characters don't match but case may be ignored,
      // try converting both characters to uppercase.
      // If the results match, then the comparison scan should
      // continue.
      char u1 = Character.toUpperCase(c1);
      char u2 = Character.toUpperCase(c2);
      if (u1 == u2) {
      continue;
      }
      // Unfortunately, conversion to uppercase does not work properly
      // for the Georgian alphabet, which has strange rules about case
      // conversion. So we need to make one last check before
      // exiting.
      if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
      continue;
      }
      ```

      2) Use `TreeMap` + `java.text.CollationKey`. This will provide locale-dependent case-insensitive map, however the performance will degrade

      3) Use both approaches: use special `HashMap` of previously resolved tables. When no table is found there, look into `TreeMap` as a source-of-case-insensitive-truth.

      The same might be relevant for wide types (e.g. types with 1000 columns)

      ---------------- Imported from GitHub ----------------
      Url: https://github.com/julianhyde/optiq/issues/173
      Created by: vlsi
      Labels:
      Created at: Sat Mar 08 19:29:38 CET 2014
      State: closed

      Attachments

        Activity

          People

            Unassigned Unassigned
            github-import GitHub Import
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: