This is an automated email from the ASF dual-hosted git repository.

morrySnow pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 305e88540f7 [fix](parser) isNull should under primaryExpression 
(#63619)
305e88540f7 is described below

commit 305e88540f7623dda261f491fabdd68af27ad0e9
Author: morrySnow <[email protected]>
AuthorDate: Tue May 26 15:35:51 2026 +0800

    [fix](parser) isNull should under primaryExpression (#63619)
    
    ### What problem does this PR solve?
    
    related PR #14967 #15163
    
    Problem Summary:
    
    The following SQL should have been executable, but it resulted in an
    unexpected error.
    
    ```sql
    select * from t
    where
    isNull(c1) = 1;
    ```
    
    the error message is
    ```
    Can not found function 'isNull'
    ```
---
 .../antlr4/org/apache/doris/nereids/DorisParser.g4 |  8 ++++----
 .../doris/nereids/parser/LogicalPlanBuilder.java   |  4 ++--
 .../doris/nereids/parser/NereidsParserTest.java    | 24 ++++++++++++++++++++++
 3 files changed, 30 insertions(+), 6 deletions(-)

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 26a159c167b..feb1f607477 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
@@ -1634,8 +1634,6 @@ lambdaExpression
 booleanExpression
     : LOGICALNOT booleanExpression                                             
     #logicalNot
     | EXISTS LEFT_PAREN query RIGHT_PAREN                                      
     #exist
-    | (ISNULL | IS_NULL_PRED) LEFT_PAREN valueExpression RIGHT_PAREN           
     #isnull
-    | IS_NOT_NULL_PRED LEFT_PAREN valueExpression RIGHT_PAREN                  
     #is_not_null_pred
     | valueExpression predicate?                                               
     #predicated
     | NOT booleanExpression                                                    
     #logicalNot
     | left=booleanExpression operator=(AND | LOGICALAND) 
right=booleanExpression    #logicalBinary
@@ -1689,8 +1687,8 @@ primaryExpression
     | CASE whenClause+ (ELSE elseExpression=expression)? END                   
                #searchedCase
     | CASE value=expression whenClause+ (ELSE elseExpression=expression)? END  
                #simpleCase
     | name=CAST LEFT_PAREN expression AS castDataType RIGHT_PAREN              
                #cast
-    | name=TRY_CAST LEFT_PAREN expression AS castDataType RIGHT_PAREN          
                 #tryCast
-    | DEFAULT LEFT_PAREN qualifiedName RIGHT_PAREN                             
                    #defaultValue
+    | name=TRY_CAST LEFT_PAREN expression AS castDataType RIGHT_PAREN          
                #tryCast
+    | DEFAULT LEFT_PAREN qualifiedName RIGHT_PAREN                             
                #defaultValue
     | constant                                                                 
                #constantDefault
     | interval                                                                 
                #intervalLiteral
     | ASTERISK (exceptOrReplace)*                                              
                #star
@@ -1712,6 +1710,8 @@ primaryExpression
     | (SUBSTR | SUBSTRING | MID) LEFT_PAREN
         expression FROM expression (FOR expression)? RIGHT_PAREN               
                #substring
     | POSITION LEFT_PAREN expression IN expression RIGHT_PAREN                 
                #position
+    | (ISNULL | IS_NULL_PRED) LEFT_PAREN expression RIGHT_PAREN                
                #isnull
+    | IS_NOT_NULL_PRED LEFT_PAREN expression RIGHT_PAREN                       
                #is_not_null_pred
     | functionCallExpression                                                   
                #functionCall
     | value=primaryExpression LEFT_BRACKET index=valueExpression RIGHT_BRACKET 
                #elementAt
     | value=primaryExpression LEFT_BRACKET begin=valueExpression
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 94aaadbb10a..53c3f09c46f 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
@@ -5139,12 +5139,12 @@ public class LogicalPlanBuilder extends 
DorisParserBaseVisitor<Object> {
 
     @Override
     public Expression visitIsnull(IsnullContext context) {
-        return ParserUtils.withOrigin(context, () -> new 
IsNull(typedVisit(context.valueExpression())));
+        return ParserUtils.withOrigin(context, () -> new 
IsNull(typedVisit(context.expression())));
     }
 
     @Override
     public Expression visitIs_not_null_pred(Is_not_null_predContext context) {
-        return ParserUtils.withOrigin(context, () -> new Not(new 
IsNull(typedVisit(context.valueExpression()))));
+        return ParserUtils.withOrigin(context, () -> new Not(new 
IsNull(typedVisit(context.expression()))));
     }
 
     public List<Expression> withInList(PredicateContext ctx) {
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/NereidsParserTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/NereidsParserTest.java
index 0a8abb2c356..247facf6b64 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/NereidsParserTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/NereidsParserTest.java
@@ -30,7 +30,10 @@ import org.apache.doris.nereids.exceptions.ParseException;
 import org.apache.doris.nereids.exceptions.SyntaxParseException;
 import org.apache.doris.nereids.glue.LogicalPlanAdapter;
 import org.apache.doris.nereids.trees.expressions.Cast;
+import org.apache.doris.nereids.trees.expressions.EqualTo;
 import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.IsNull;
+import org.apache.doris.nereids.trees.expressions.Not;
 import org.apache.doris.nereids.trees.expressions.OrderExpression;
 import org.apache.doris.nereids.trees.expressions.functions.generator.Unnest;
 import org.apache.doris.nereids.trees.expressions.literal.DecimalLiteral;
@@ -1631,4 +1634,25 @@ public class NereidsParserTest extends ParserTestBase {
         plan = nereidsParser.parseSingle(sql);
         Assertions.assertInstanceOf(UpdateCommand.class, plan);
     }
+
+    @Test
+    public void testIsNullAndIsNotNullExpression() {
+        NereidsParser nereidsParser = new NereidsParser();
+        String sql = "ISNULL(X) = 1";
+        Expression expression = nereidsParser.parseExpression(sql);
+
+        Assertions.assertInstanceOf(EqualTo.class, expression);
+        Assertions.assertInstanceOf(IsNull.class, expression.child(0));
+
+        sql = "IS_NULL_PRED(X) = 1";
+        expression = nereidsParser.parseExpression(sql);
+        Assertions.assertInstanceOf(EqualTo.class, expression);
+        Assertions.assertInstanceOf(IsNull.class, expression.child(0));
+
+        sql = "IS_NOT_NULL_PRED(X) = 1";
+        expression = nereidsParser.parseExpression(sql);
+        Assertions.assertInstanceOf(EqualTo.class, expression);
+        Assertions.assertInstanceOf(Not.class, expression.child(0));
+        Assertions.assertInstanceOf(IsNull.class, 
expression.child(0).child(0));
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to