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

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

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: None
    • Labels:

      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

        Activity

        Hide
        github-import GitHub Import added a comment -

        [Date: Sun Mar 09 23:47:35 CET 2014, Author: julianhyde]

        I'm using TreeMap(String.CASE_INSENSITIVE_ORDER). I believe that will work even for Georgian. If I'm wrong log another bug.

        Show
        github-import GitHub Import added a comment - [Date: Sun Mar 09 23:47:35 CET 2014, Author: julianhyde ] I'm using TreeMap(String.CASE_INSENSITIVE_ORDER). I believe that will work even for Georgian. If I'm wrong log another bug.

          People

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

            Dates

            • Created:
              Updated:
              Resolved:

              Development