This is an automated email from the ASF dual-hosted git repository. jhyde pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/calcite.git
commit abb4cf00254ce2f4d7580b285a6e2226e8d50192 Author: TJ Banghart <[email protected]> AuthorDate: Tue Sep 20 03:47:57 2022 +0000 [CALCITE-5291] Make lexical policy for BigQuery case-insensitive Close apache/calcite#2914 --- .../main/java/org/apache/calcite/config/Lex.java | 2 +- .../calcite/sql/validate/LexCaseSensitiveTest.java | 69 +++++++++++++--------- .../java/org/apache/calcite/test/JdbcTest.java | 8 +-- 3 files changed, 45 insertions(+), 34 deletions(-) diff --git a/core/src/main/java/org/apache/calcite/config/Lex.java b/core/src/main/java/org/apache/calcite/config/Lex.java index 172b6b8c5c..e486c1a94e 100644 --- a/core/src/main/java/org/apache/calcite/config/Lex.java +++ b/core/src/main/java/org/apache/calcite/config/Lex.java @@ -36,7 +36,7 @@ public enum Lex { * a back-tick is escaped using a backslash. * Character literals may be enclosed in single or double quotes. */ BIG_QUERY(Quoting.BACK_TICK_BACKSLASH, Casing.UNCHANGED, Casing.UNCHANGED, - true, CharLiteralStyle.BQ_SINGLE, CharLiteralStyle.BQ_DOUBLE), + false, CharLiteralStyle.BQ_SINGLE, CharLiteralStyle.BQ_DOUBLE), /** Lexical policy similar to Oracle. The case of identifiers enclosed in * double-quotes is preserved; unquoted identifiers are converted to diff --git a/core/src/test/java/org/apache/calcite/sql/validate/LexCaseSensitiveTest.java b/core/src/test/java/org/apache/calcite/sql/validate/LexCaseSensitiveTest.java index 0c9d82aaa7..68937790ae 100644 --- a/core/src/test/java/org/apache/calcite/sql/validate/LexCaseSensitiveTest.java +++ b/core/src/test/java/org/apache/calcite/sql/validate/LexCaseSensitiveTest.java @@ -24,7 +24,6 @@ import org.apache.calcite.plan.RelTraitSet; import org.apache.calcite.rel.RelNode; import org.apache.calcite.schema.SchemaPlus; import org.apache.calcite.sql.SqlNode; -import org.apache.calcite.sql.parser.SqlParseException; import org.apache.calcite.sql.parser.SqlParser; import org.apache.calcite.sql.parser.SqlParser.Config; import org.apache.calcite.test.CalciteAssert; @@ -33,7 +32,6 @@ import org.apache.calcite.tools.Frameworks; import org.apache.calcite.tools.Planner; import org.apache.calcite.tools.Program; import org.apache.calcite.tools.Programs; -import org.apache.calcite.tools.RelConversionException; import org.apache.calcite.tools.ValidationException; import org.junit.jupiter.api.Test; @@ -64,7 +62,7 @@ class LexCaseSensitiveTest { } private static void runProjectQueryWithLex(Lex lex, String sql) - throws SqlParseException, ValidationException, RelConversionException { + throws Exception { Config javaLex = SqlParser.config().withLex(lex); Planner planner = getPlanner(null, javaLex, Programs.ofRules(Programs.RULE_SET)); SqlNode parse = planner.parse(sql); @@ -85,8 +83,7 @@ class LexCaseSensitiveTest { } } - @Test void testCalciteCaseOracle() - throws SqlParseException, ValidationException, RelConversionException { + @Test void testCalciteCaseOracle() throws Exception { String sql = "select \"empid\" as EMPID, \"empid\" from\n" + " (select \"empid\" from \"emps\" order by \"emps\".\"deptno\")"; runProjectQueryWithLex(Lex.ORACLE, sql); @@ -101,50 +98,43 @@ class LexCaseSensitiveTest { }); } - @Test void testCalciteCaseMySql() - throws SqlParseException, ValidationException, RelConversionException { + @Test void testCalciteCaseMySql() throws Exception { String sql = "select empid as EMPID, empid from (\n" + " select empid from emps order by `EMPS`.DEPTNO)"; runProjectQueryWithLex(Lex.MYSQL, sql); } - @Test void testCalciteCaseMySqlNoException() - throws SqlParseException, ValidationException, RelConversionException { + @Test void testCalciteCaseMySqlNoException() throws Exception { String sql = "select EMPID, empid from\n" + " (select empid from emps order by emps.deptno)"; runProjectQueryWithLex(Lex.MYSQL, sql); } - @Test void testCalciteCaseMySqlAnsi() - throws SqlParseException, ValidationException, RelConversionException { + @Test void testCalciteCaseMySqlAnsi() throws Exception { String sql = "select empid as EMPID, empid from (\n" + " select empid from emps order by EMPS.DEPTNO)"; runProjectQueryWithLex(Lex.MYSQL_ANSI, sql); } - @Test void testCalciteCaseMySqlAnsiNoException() - throws SqlParseException, ValidationException, RelConversionException { + @Test void testCalciteCaseMySqlAnsiNoException() throws Exception { String sql = "select EMPID, empid from\n" + " (select empid from emps order by emps.deptno)"; runProjectQueryWithLex(Lex.MYSQL_ANSI, sql); } - @Test void testCalciteCaseSqlServer() - throws SqlParseException, ValidationException, RelConversionException { + @Test void testCalciteCaseSqlServer() throws Exception { String sql = "select empid as EMPID, empid from (\n" + " select empid from emps order by EMPS.DEPTNO)"; runProjectQueryWithLex(Lex.SQL_SERVER, sql); } - @Test void testCalciteCaseSqlServerNoException() - throws SqlParseException, ValidationException, RelConversionException { + @Test void testCalciteCaseSqlServerNoException() throws Exception { String sql = "select EMPID, empid from\n" + " (select empid from emps order by emps.deptno)"; runProjectQueryWithLex(Lex.SQL_SERVER, sql); } - @Test void testCalciteCaseJava() - throws SqlParseException, ValidationException, RelConversionException { + @Test void testCalciteCaseJava() throws Exception { String sql = "select empid as EMPID, empid from (\n" + " select empid from emps order by emps.deptno)"; runProjectQueryWithLex(Lex.JAVA, sql); @@ -159,8 +149,7 @@ class LexCaseSensitiveTest { }); } - @Test void testCalciteCaseJoinOracle() - throws SqlParseException, ValidationException, RelConversionException { + @Test void testCalciteCaseJoinOracle() throws Exception { String sql = "select t.\"empid\" as EMPID, s.\"empid\" from\n" + "(select * from \"emps\" where \"emps\".\"deptno\" > 100) t join\n" + "(select * from \"emps\" where \"emps\".\"deptno\" < 200) s\n" @@ -168,35 +157,57 @@ class LexCaseSensitiveTest { runProjectQueryWithLex(Lex.ORACLE, sql); } - @Test void testCalciteCaseJoinMySql() - throws SqlParseException, ValidationException, RelConversionException { + @Test void testCalciteCaseJoinMySql() throws Exception { String sql = "select t.empid as EMPID, s.empid from\n" + "(select * from emps where emps.deptno > 100) t join\n" + "(select * from emps where emps.deptno < 200) s on t.empid = s.empid"; runProjectQueryWithLex(Lex.MYSQL, sql); } - @Test void testCalciteCaseJoinMySqlAnsi() - throws SqlParseException, ValidationException, RelConversionException { + @Test void testCalciteCaseJoinMySqlAnsi() throws Exception { String sql = "select t.empid as EMPID, s.empid from\n" + "(select * from emps where emps.deptno > 100) t join\n" + "(select * from emps where emps.deptno < 200) s on t.empid = s.empid"; runProjectQueryWithLex(Lex.MYSQL_ANSI, sql); } - @Test void testCalciteCaseJoinSqlServer() - throws SqlParseException, ValidationException, RelConversionException { + @Test void testCalciteCaseJoinSqlServer() throws Exception { String sql = "select t.empid as EMPID, s.empid from\n" + "(select * from emps where emps.deptno > 100) t join\n" + "(select * from emps where emps.deptno < 200) s on t.empid = s.empid"; runProjectQueryWithLex(Lex.SQL_SERVER, sql); } - @Test void testCalciteCaseJoinJava() - throws SqlParseException, ValidationException, RelConversionException { + @Test void testCalciteCaseJoinJava() throws Exception { String sql = "select t.empid as EMPID, s.empid from\n" + "(select * from emps where emps.deptno > 100) t join\n" + "(select * from emps where emps.deptno < 200) s on t.empid = s.empid"; runProjectQueryWithLex(Lex.JAVA, sql); } + + @Test void testCalciteCaseBigQuery() throws Exception { + String sql = "select empid as EMPID, empid from (\n" + + " select empid from emps order by EMPS.DEPTNO)"; + runProjectQueryWithLex(Lex.BIG_QUERY, sql); + } + + @Test void testCalciteCaseBigQueryNoException() throws Exception { + String sql = "select EMPID, empid from\n" + + " (select empid from emps order by emps.deptno)"; + runProjectQueryWithLex(Lex.BIG_QUERY, sql); + } + + /** Test case for + * <a href="https://issues.apache.org/jira/browse/CALCITE-5291">[CALCITE-5291] + * Make BigQuery lexical policy case insensitive</a>. + * + * <p>In reality, BigQuery treats table names as case-sensitive, column names + * and aliases as case-insensitive. Calcite cannot currently support a hybrid + * policy, so it treats table names as case-insensitive. */ + @Test void testCalciteCaseJoinBigQuery() throws Exception { + String sql = "select t.empid as EMPID, s.empid from\n" + + "(select * from emps where emps.deptno > 100) t join\n" + + "(select * from emps where emps.deptno < 200) s on t.empid = s.empid"; + runProjectQueryWithLex(Lex.BIG_QUERY, sql); + } } 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 7aa4790955..c7033255c8 100644 --- a/core/src/test/java/org/apache/calcite/test/JdbcTest.java +++ b/core/src/test/java/org/apache/calcite/test/JdbcTest.java @@ -6842,17 +6842,17 @@ public class JdbcTest { DatabaseMetaData metaData = connection.getMetaData(); assertThat(metaData.getIdentifierQuoteString(), equalTo("`")); assertThat(metaData.supportsMixedCaseIdentifiers(), - equalTo(true)); - assertThat(metaData.storesMixedCaseIdentifiers(), equalTo(false)); + assertThat(metaData.storesMixedCaseIdentifiers(), + equalTo(true)); assertThat(metaData.storesUpperCaseIdentifiers(), equalTo(false)); assertThat(metaData.storesLowerCaseIdentifiers(), equalTo(false)); assertThat(metaData.supportsMixedCaseQuotedIdentifiers(), - equalTo(true)); - assertThat(metaData.storesMixedCaseQuotedIdentifiers(), equalTo(false)); + assertThat(metaData.storesMixedCaseQuotedIdentifiers(), + equalTo(true)); assertThat(metaData.storesUpperCaseIdentifiers(), equalTo(false)); assertThat(metaData.storesLowerCaseQuotedIdentifiers(),
