From 74e831d57565b620dd3347a1188fd614dfa235cb Mon Sep 17 00:00:00 2001 From: zhangyuan Date: Fri, 2 Aug 2024 10:50:52 +0800 Subject: [PATCH] [feature] (expr) support expression IS [NOT] TURE/FALSE (#38623) support expression IS [NOT] TURE/FALSE ``` mysql> select 1 is true, 1 is not true, 0 is true, 0 is not true; +--------------------+---------------------------+--------------------+---------------------------+ | cast(1 as BOOLEAN) | ( not cast(1 as BOOLEAN)) | cast(0 as BOOLEAN) | ( not cast(0 as BOOLEAN)) | +--------------------+---------------------------+--------------------+---------------------------+ | 1 | 0 | 0 | 1 | +--------------------+---------------------------+--------------------+---------------------------+ ``` --- .../org/apache/doris/nereids/DorisParser.g4 | 1 + fe/fe-core/src/main/cup/sql_parser.cup | 14 ++++++++++++++ .../nereids/parser/LogicalPlanBuilder.java | 9 +++++++++ .../expressions/ExpressionParserTest.java | 18 ++++++++++++++++++ .../sql/test_compare_expression.out | 18 ++++++++++++++++++ .../sql/test_compare_expression.sql | 6 ++++++ 6 files changed, 66 insertions(+) diff --git a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4 b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4 index 9b562a6c01aebe..473f7dafe7a7c0 100644 --- a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4 +++ b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4 @@ -894,6 +894,7 @@ predicate | NOT? kind=IN LEFT_PAREN query RIGHT_PAREN | NOT? kind=IN LEFT_PAREN expression (COMMA expression)* RIGHT_PAREN | IS NOT? kind=NULL + | IS NOT? kind=(TRUE | FALSE) ; valueExpression diff --git a/fe/fe-core/src/main/cup/sql_parser.cup b/fe/fe-core/src/main/cup/sql_parser.cup index dda8ccb1862ec6..f19b9f4f531c2f 100644 --- a/fe/fe-core/src/main/cup/sql_parser.cup +++ b/fe/fe-core/src/main/cup/sql_parser.cup @@ -7300,6 +7300,20 @@ non_pred_expr ::= {: RESULT = new CastExpr(targetType, e); :} | KW_KEY encryptkey_name:name {: RESULT = new EncryptKeyRef(name); :} + | expr:e KW_IS KW_TRUE + {: RESULT = new CastExpr(TypeDef.create(PrimitiveType.BOOLEAN), e); :} + | expr:e KW_IS KW_NOT KW_TRUE + {: + e = new CastExpr(TypeDef.create(PrimitiveType.BOOLEAN), e); + RESULT = new CompoundPredicate(CompoundPredicate.Operator.NOT, e, null); + :} + | expr:e KW_IS KW_FALSE + {: + e = new CastExpr(TypeDef.create(PrimitiveType.BOOLEAN), e); + RESULT = new CompoundPredicate(CompoundPredicate.Operator.NOT, e, null); + :} + | expr:e KW_IS KW_NOT KW_FALSE + {: RESULT = new CastExpr(TypeDef.create(PrimitiveType.BOOLEAN), e); :} | KW_CONVERT LPAREN expr:e KW_USING ident:character RPAREN {: ArrayList exprs = new ArrayList<>(); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java index e6b00e148a6e22..2ff714d0a6ac90 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java @@ -455,6 +455,7 @@ import org.apache.doris.nereids.types.AggStateType; import org.apache.doris.nereids.types.ArrayType; import org.apache.doris.nereids.types.BigIntType; +import org.apache.doris.nereids.types.BooleanType; import org.apache.doris.nereids.types.DataType; import org.apache.doris.nereids.types.LargeIntType; import org.apache.doris.nereids.types.MapType; @@ -3334,6 +3335,14 @@ private Expression withPredicate(Expression valueExpression, PredicateContext ct case DorisParser.NULL: outExpression = new IsNull(valueExpression); break; + case DorisParser.TRUE: + outExpression = new Cast(valueExpression, + BooleanType.INSTANCE, true); + break; + case DorisParser.FALSE: + outExpression = new Not(new Cast(valueExpression, + BooleanType.INSTANCE, true)); + break; case DorisParser.MATCH: case DorisParser.MATCH_ANY: outExpression = new MatchAny( diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/ExpressionParserTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/ExpressionParserTest.java index 3fbd3787249949..cd0e21bb71d7d4 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/ExpressionParserTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/ExpressionParserTest.java @@ -305,6 +305,24 @@ public void testIsNull() { assertExpr(e2); } + @Test + public void testIsTrue() { + String e1 = "a is true"; + assertExpr(e1); + + String e2 = "a is not true"; + assertExpr(e2); + } + + @Test + public void testIsFalse() { + String e1 = "a is false"; + assertExpr(e1); + + String e2 = "a is not false"; + assertExpr(e2); + } + @Test public void testMatch() { String sql = "select * from test " diff --git a/regression-test/data/nereids_syntax_p0/sql/test_compare_expression.out b/regression-test/data/nereids_syntax_p0/sql/test_compare_expression.out index 09f263148b47b7..89dd2607f7a93d 100644 --- a/regression-test/data/nereids_syntax_p0/sql/test_compare_expression.out +++ b/regression-test/data/nereids_syntax_p0/sql/test_compare_expression.out @@ -35,3 +35,21 @@ true -- !test_compare_expression_12 -- 2008-08-08 00:00:00 +-- !test_compare_expression_13 -- +true false true false + +-- !test_compare_expression_14 -- +true false true true + +-- !test_compare_expression_15 -- +true false false true + +-- !test_compare_expression_16 -- +\N \N \N \N + +-- !test_compare_expression_17 -- +true false false true + +-- !test_compare_expression_18 -- +true false false true + diff --git a/regression-test/suites/nereids_syntax_p0/sql/test_compare_expression.sql b/regression-test/suites/nereids_syntax_p0/sql/test_compare_expression.sql index 020af0a2ce2a6f..e52f37f276c563 100644 --- a/regression-test/suites/nereids_syntax_p0/sql/test_compare_expression.sql +++ b/regression-test/suites/nereids_syntax_p0/sql/test_compare_expression.sql @@ -34,3 +34,9 @@ select 1 not in (null, 2); select timestamp '2008-08-08 00:00:00' in ('2008-08-08'); select case when true then timestamp '2008-08-08 00:00:00' else '2008-08-08' end; +select 1 is true, 1 is not true, 0 is false, 0 is not false; +select -1 is true, -1 is not true, -0 is false, -1 is not false; +select 1.1 is true, 1.1 is not true, 1.1 is false, 1.1 is not false; +select 'ab' is true, 'ab' is not true, 'ab' is false, 'ab' is not false; +select cast('2028-01-01' as date) is true, cast('2028-01-01' as date) is not true, cast('2028-01-01' as date) is false, cast('2028-01-01' as date) is not false; +select cast('2028-01-01 01:00:00' as datetime) is true, cast('2028-01-01 01:00:00' as datetime) is not true, cast('2028-01-01 01:00:00' as datetime) is false, cast('2028-01-01 01:00:00' as datetime) is not false; \ No newline at end of file