From 91e9984efa944ac7a2168d35eb4ba1e9266d0b50 Mon Sep 17 00:00:00 2001 From: xiaohei <1597226206@qq.com> Date: Sat, 20 Jul 2024 11:51:34 +0800 Subject: [PATCH] [CALCITE-6482] OracleSqlDialect support bool literal as predicate --- .../org/apache/calcite/sql/SqlDialect.java | 7 +++++++ .../org/apache/calcite/sql/SqlLiteral.java | 3 +-- .../calcite/sql/dialect/OracleSqlDialect.java | 15 +++++++++++++ .../rel/rel2sql/RelToSqlConverterTest.java | 21 +++++++++++++++++++ 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/apache/calcite/sql/SqlDialect.java b/core/src/main/java/org/apache/calcite/sql/SqlDialect.java index b8877fdaf4d4..b51b564e52be 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlDialect.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlDialect.java @@ -466,6 +466,13 @@ public void unparseCall(SqlWriter writer, SqlCall call, int leftPrec, } } + public void unparseBoolLiteral(SqlWriter writer, + SqlLiteral literal, int leftPrec, int rightPrec) { + Object value = literal.getValue(); + writer.keyword( + !(value instanceof Boolean) ? "UNKNOWN" : (Boolean) value ? "TRUE" : "FALSE"); + } + public void unparseDateTimeLiteral(SqlWriter writer, SqlAbstractDateTimeLiteral literal, int leftPrec, int rightPrec) { writer.literal(literal.toString()); diff --git a/core/src/main/java/org/apache/calcite/sql/SqlLiteral.java b/core/src/main/java/org/apache/calcite/sql/SqlLiteral.java index ae41cbe54e96..272c0d135c62 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlLiteral.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlLiteral.java @@ -754,8 +754,7 @@ public String getStringValue() { int rightPrec) { switch (typeName) { case BOOLEAN: - writer.keyword( - value == null ? "UNKNOWN" : (Boolean) value ? "TRUE" : "FALSE"); + writer.getDialect().unparseBoolLiteral(writer, this, leftPrec, rightPrec); break; case NULL: writer.keyword("NULL"); diff --git a/core/src/main/java/org/apache/calcite/sql/dialect/OracleSqlDialect.java b/core/src/main/java/org/apache/calcite/sql/dialect/OracleSqlDialect.java index e99ab2a44fc2..4314438d6cb1 100644 --- a/core/src/main/java/org/apache/calcite/sql/dialect/OracleSqlDialect.java +++ b/core/src/main/java/org/apache/calcite/sql/dialect/OracleSqlDialect.java @@ -126,6 +126,21 @@ public OracleSqlDialect(Context context) { return false; } + @Override public void unparseBoolLiteral(SqlWriter writer, + SqlLiteral literal, int leftPrec, int rightPrec) { + Boolean value = (Boolean) literal.getValue(); + if (value == null || majorVersion >= 23) { + super.unparseBoolLiteral(writer, literal, leftPrec, rightPrec); + return; + } + // low version oracle not support bool literal + final SqlWriter.Frame frame = writer.startList("(", ")"); + writer.literal("1"); + writer.sep(SqlStdOperatorTable.EQUALS.getName()); + writer.literal(value ? "1" : "0"); + writer.endList(frame); + } + @Override public void unparseDateTimeLiteral(SqlWriter writer, SqlAbstractDateTimeLiteral literal, int leftPrec, int rightPrec) { if (literal instanceof SqlTimestampLiteral) { diff --git a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java index 7d59542b73c4..03916bf7e94a 100644 --- a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java +++ b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java @@ -7700,6 +7700,27 @@ private void checkLiteral2(String expression, String expected) { .withOracle(11).throws_("Lower Oracle version(<12) doesn't support offset/fetch syntax!"); } + /** Test case for + * [CALCITE-6482] + * Oracle dialect convert bool literal when version < 23.*/ + @Test void testBoolLiteralOracle() { + String query = "SELECT \"e1\".\"department_id\" " + + "FROM \"employee\" \"e1\"" + + "LEFT JOIN \"employee\" \"e2\"" + + "ON TRUE"; + String expectedVersionLow = "SELECT \"employee\".\"department_id\"\n" + + "FROM \"foodmart\".\"employee\"\n" + + "LEFT JOIN \"foodmart\".\"employee\" \"employee0\" " + + "ON (1 = 1)"; + String expectedVersionHigh = "SELECT \"employee\".\"department_id\"\n" + + "FROM \"foodmart\".\"employee\"\n" + + "LEFT JOIN \"foodmart\".\"employee\" \"employee0\" " + + "ON TRUE"; + sql(query) + .withOracle(23).ok(expectedVersionHigh) + .withOracle(11).ok(expectedVersionLow); + } + /** Test case for * [CALCITE-5265] * JDBC adapter sometimes adds unnecessary parentheses around SELECT in INSERT. */