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

xuyang pushed a commit to branch branch-2.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-2.1 by this push:
     new c5bb0e3a211 [bug](prepared statement) fix prepared statement throw 
exception when inserting null value (#36484)
c5bb0e3a211 is described below

commit c5bb0e3a211842d2e498834410cc3581ffe05cde
Author: xy720 <22125576+xy...@users.noreply.github.com>
AuthorDate: Thu Jun 20 11:31:59 2024 +0800

    [bug](prepared statement) fix prepared statement throw exception when 
inserting null value (#36484)
    
    ## Proposed changes
    
    bp #36426
    
    <!--Describe your changes.-->
---
 .../org/apache/doris/analysis/PlaceHolderExpr.java    | 19 ++++++++++++++-----
 .../java/org/apache/doris/analysis/PrepareStmt.java   |  1 +
 .../main/java/org/apache/doris/planner/ScanNode.java  |  4 +++-
 .../apache/doris/rewrite/RewriteInPredicateRule.java  |  7 ++++++-
 regression-test/data/insert_p0/prepare_insert.out     |  1 +
 .../suites/insert_p0/prepare_insert.groovy            | 18 ++++++++++++++++--
 6 files changed, 41 insertions(+), 9 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/PlaceHolderExpr.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/PlaceHolderExpr.java
index 28d4ce51d55..d6fc6e8e96e 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/PlaceHolderExpr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/PlaceHolderExpr.java
@@ -59,6 +59,20 @@ public class PlaceHolderExpr extends LiteralExpr {
         this.type = literal.getType();
     }
 
+    public LiteralExpr getLiteral() {
+        return lExpr;
+    }
+
+    @Override
+    protected void analysisDone() {
+        if (lExpr != null && !lExpr.isAnalyzed) {
+            lExpr.analysisDone();
+        }
+        if (!isAnalyzed) {
+            super.analysisDone();
+        }
+    }
+
     public LiteralExpr createLiteralFromType() throws AnalysisException {
         Preconditions.checkState(mysqlTypeCode > 0);
         return LiteralExpr.getLiteralByMysqlType(mysqlTypeCode, isUnsigned());
@@ -135,11 +149,6 @@ public class PlaceHolderExpr extends LiteralExpr {
         return "?";
     }
 
-    @Override
-    protected Expr uncheckedCastTo(Type targetType) throws AnalysisException {
-        return this.lExpr.uncheckedCastTo(targetType);
-    }
-
     // Swaps the sign of numeric literals.
     // Throws for non-numeric literals.
     public void swapSign() throws NotImplementedException {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/PrepareStmt.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/PrepareStmt.java
index 90da98c14f4..1c7b5459979 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/PrepareStmt.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/PrepareStmt.java
@@ -268,6 +268,7 @@ public class PrepareStmt extends StatementBase {
         }
         for (int i = 0; i < values.size(); ++i) {
             inner.getPlaceHolders().get(i).setLiteral(values.get(i));
+            inner.getPlaceHolders().get(i).analysisDone();
         }
         if (!values.isEmpty()) {
             if (LOG.isDebugEnabled()) {
diff --git a/fe/fe-core/src/main/java/org/apache/doris/planner/ScanNode.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/ScanNode.java
index a72b7328c33..8fc9da0260e 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/ScanNode.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/planner/ScanNode.java
@@ -29,6 +29,7 @@ import org.apache.doris.analysis.InPredicate;
 import org.apache.doris.analysis.IsNullPredicate;
 import org.apache.doris.analysis.LiteralExpr;
 import org.apache.doris.analysis.NullLiteral;
+import org.apache.doris.analysis.PlaceHolderExpr;
 import org.apache.doris.analysis.PredicateUtils;
 import org.apache.doris.analysis.SlotDescriptor;
 import org.apache.doris.analysis.SlotId;
@@ -399,7 +400,8 @@ public abstract class ScanNode extends PlanNode implements 
SplitGenerator {
                 if (null == partitionColumnFilter) {
                     partitionColumnFilter = new PartitionColumnFilter();
                 }
-                LiteralExpr literal = (LiteralExpr) slotBinding;
+                LiteralExpr literal = slotBinding instanceof PlaceHolderExpr
+                        ? ((PlaceHolderExpr) slotBinding).getLiteral() : 
(LiteralExpr) slotBinding;
                 BinaryPredicate.Operator op = binPredicate.getOp();
                 if (!binPredicate.slotIsLeft()) {
                     op = op.commutative();
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/rewrite/RewriteInPredicateRule.java 
b/fe/fe-core/src/main/java/org/apache/doris/rewrite/RewriteInPredicateRule.java
index c04ff432961..3541690d002 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/rewrite/RewriteInPredicateRule.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/rewrite/RewriteInPredicateRule.java
@@ -23,6 +23,7 @@ import org.apache.doris.analysis.CastExpr;
 import org.apache.doris.analysis.Expr;
 import org.apache.doris.analysis.InPredicate;
 import org.apache.doris.analysis.LiteralExpr;
+import org.apache.doris.analysis.PlaceHolderExpr;
 import org.apache.doris.analysis.SlotRef;
 import org.apache.doris.analysis.Subquery;
 import org.apache.doris.catalog.Type;
@@ -114,7 +115,11 @@ public class RewriteInPredicateRule implements 
ExprRewriteRule {
                 //   For example, 2.1 is converted to 2;
                 // 3. childExpr is precisely converted to column type. For 
example, 2.0 is converted to 2.
                 // In cases 1 and 2 above, childExpr should be discarded.
-                LiteralExpr newExpr = (LiteralExpr) 
childExpr.castTo(columnType);
+                Expr tmpExpr = childExpr.castTo(columnType);
+                if (tmpExpr instanceof CastExpr && tmpExpr.getChild(0) 
instanceof PlaceHolderExpr) {
+                    tmpExpr = ((PlaceHolderExpr) 
tmpExpr.getChild(0)).getLiteral().castTo(columnType);
+                }
+                LiteralExpr newExpr = (LiteralExpr) tmpExpr;
                 if (childExpr.compareLiteral(newExpr) == 0) {
                     isCast = true;
                     newInList.add(newExpr);
diff --git a/regression-test/data/insert_p0/prepare_insert.out 
b/regression-test/data/insert_p0/prepare_insert.out
index a84bd02040e..f535890c5b8 100644
--- a/regression-test/data/insert_p0/prepare_insert.out
+++ b/regression-test/data/insert_p0/prepare_insert.out
@@ -1,5 +1,6 @@
 -- This file is automatically generated. You should know what you did if you 
want to edit this
 -- !sql --
+\N     \N      \N
 1      a       90
 2      ab      91
 3      abc     92
diff --git a/regression-test/suites/insert_p0/prepare_insert.groovy 
b/regression-test/suites/insert_p0/prepare_insert.groovy
index 305758170d7..235adf03c1d 100644
--- a/regression-test/suites/insert_p0/prepare_insert.groovy
+++ b/regression-test/suites/insert_p0/prepare_insert.groovy
@@ -34,7 +34,7 @@ suite("prepare_insert") {
     sql """ DROP TABLE IF EXISTS ${tableName} """
     sql """
         CREATE TABLE ${tableName} (
-            `id` int(11) NOT NULL,
+            `id` int(11) NULL,
             `name` varchar(50) NULL,
             `score` int(11) NULL DEFAULT "-1"
         ) ENGINE=OLAP
@@ -141,6 +141,20 @@ suite("prepare_insert") {
         stmt.close()
     }
 
+    // insert with null
+    result1 = connect(user = user, password = password, url = url) {
+        def stmt = prepareStatement "insert into ${tableName} values(?, ?, ?)"
+        assertEquals(com.mysql.cj.jdbc.ServerPreparedStatement, stmt.class)
+        stmt.setNull(1, java.sql.Types.INTEGER)
+        stmt.setNull(2, java.sql.Types.VARCHAR)
+        stmt.setNull(3, java.sql.Types.INTEGER)
+        def result = stmt.execute()
+        logger.info("result: ${result}")
+        getServerInfo(stmt)
+
+        stmt.close()
+    }
+
     // insert with label
     def label = "insert_" + System.currentTimeMillis()
     result1 = connect(user = user, password = password, url = url) {
@@ -238,4 +252,4 @@ suite("prepare_insert") {
     }
 
     qt_sql """ select * from ${tableName} order by id, name, score """
-}
\ No newline at end of file
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to