From 0c755fab5d58615cf37a711eb687bab0cf0ad9f5 Mon Sep 17 00:00:00 2001 From: wangdiao Date: Tue, 4 Mar 2025 16:58:58 +0800 Subject: [PATCH] [CALCITE-6825] Add support for ALL, SOME, ANY in RelToSqlConverter --- .../calcite/rel/rel2sql/SqlImplementor.java | 2 + .../calcite/sql/fun/SqlQuantifyOperator.java | 39 +++++++++++++++++++ .../rel/rel2sql/RelToSqlConverterTest.java | 18 +++++++++ 3 files changed, 59 insertions(+) diff --git a/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java b/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java index 470c9ada2e43..a0733b69244d 100644 --- a/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java +++ b/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java @@ -776,6 +776,8 @@ public SqlNode toSql(@Nullable RexProgram program, RexNode rex) { return new SqlDynamicParam(caseParam.getIndex(), POS); case IN: + case SOME: + case ALL: subQuery = (RexSubQuery) rex; sqlSubQuery = implementor().visitRoot(subQuery.rel).asQueryOrValues(); final List operands = subQuery.operands; diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlQuantifyOperator.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlQuantifyOperator.java index c8409377a612..55bc0f8d4171 100644 --- a/core/src/main/java/org/apache/calcite/sql/fun/SqlQuantifyOperator.java +++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlQuantifyOperator.java @@ -21,6 +21,7 @@ import org.apache.calcite.sql.SqlKind; import org.apache.calcite.sql.SqlNode; import org.apache.calcite.sql.SqlNodeList; +import org.apache.calcite.sql.SqlOperator; import org.apache.calcite.sql.type.SqlTypeName; import org.apache.calcite.sql.type.SqlTypeUtil; import org.apache.calcite.sql.validate.SqlValidator; @@ -118,4 +119,42 @@ public class SqlQuantifyOperator extends SqlInOperator { } return null; } + + @Override public SqlOperator not() { + if (kind == SqlKind.SOME) { + switch (comparisonKind) { + case EQUALS: + return SqlStdOperatorTable.ALL_NE; + case NOT_EQUALS: + return SqlStdOperatorTable.ALL_EQ; + case LESS_THAN_OR_EQUAL: + return SqlStdOperatorTable.ALL_GT; + case LESS_THAN: + return SqlStdOperatorTable.ALL_GE; + case GREATER_THAN_OR_EQUAL: + return SqlStdOperatorTable.ALL_LT; + case GREATER_THAN: + return SqlStdOperatorTable.ALL_LE; + default: + throw new AssertionError("unexpected SOME comparisonKind " + kind); + } + } else { + switch (comparisonKind) { + case EQUALS: + return SqlStdOperatorTable.SOME_NE; + case NOT_EQUALS: + return SqlStdOperatorTable.SOME_EQ; + case LESS_THAN_OR_EQUAL: + return SqlStdOperatorTable.SOME_GT; + case LESS_THAN: + return SqlStdOperatorTable.SOME_GE; + case GREATER_THAN_OR_EQUAL: + return SqlStdOperatorTable.SOME_LT; + case GREATER_THAN: + return SqlStdOperatorTable.SOME_LE; + default: + throw new AssertionError("unexpected ALL comparisonKind " + kind); + } + } + } } 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 6d59536d231a..06eb644d7492 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 @@ -9307,6 +9307,24 @@ private void checkLiteral2(String expression, String expected) { } + @Test void testSome() { + final String sql = "SELECT 1, \"gross_weight\" < SOME(SELECT \"gross_weight\" " + + "FROM \"foodmart\".\"product\") AS \"t\" " + + "FROM \"foodmart\".\"product\""; + final String expected = "SELECT 1, \"gross_weight\" < SOME (SELECT \"gross_weight\"\n" + + "FROM \"foodmart\".\"product\") AS \"t\"\nFROM \"foodmart\".\"product\""; + sql(sql).ok(expected); + } + + @Test void testAll() { + final String sql = "SELECT 1, \"gross_weight\" < ALL(SELECT \"gross_weight\" " + + "FROM \"foodmart\".\"product\") AS \"t\" " + + "FROM \"foodmart\".\"product\""; + final String expected = "SELECT 1, \"gross_weight\" < ALL (SELECT \"gross_weight\"\n" + + "FROM \"foodmart\".\"product\") AS \"t\"\nFROM \"foodmart\".\"product\""; + sql(sql).ok(expected); + } + /** Fluid interface to run tests. */ static class Sql { private final CalciteAssert.SchemaSpec schemaSpec;