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. */