Skip to content

Commit

Permalink
[bug](prepared statement) fix prepared statement throw exception when…
Browse files Browse the repository at this point in the history
… inserting null value (#36426)

## Proposed changes

Issue Number: close #xxx

When inserting a null value using jdbc prepared statement, Fe reports
the following error:

```
2024-06-18 00:01:41,381 WARN (mysql-nio-pool-0|287) [StmtExecutor.analyze():1336] Analyze failed. stmt[38, 857b9a4c512f48b5-89ee68afc32f1828]
java.lang.IllegalStateException: null
        at com.google.common.base.Preconditions.checkState(Preconditions.java:496) ~[guava-32.1.2-jre.jar:?]
        at org.apache.doris.analysis.Analyzer.materializeSlots(Analyzer.java:2624) ~[doris-fe.jar:1.2-SNAPSHOT]
        at org.apache.doris.planner.SingleNodePlanner.createSingleNodePlan(SingleNodePlanner.java:178) ~[doris-fe.jar:1.2-SNAPSHOT]
        at org.apache.doris.planner.OriginalPlanner.createPlanFragments(OriginalPlanner.java:171) ~[doris-fe.jar:1.2-SNAPSHOT]
        at org.apache.doris.planner.OriginalPlanner.plan(OriginalPlanner.java:102) ~[doris-fe.jar:1.2-SNAPSHOT]
        at org.apache.doris.qe.StmtExecutor.analyzeAndGenerateQueryPlan(StmtExecutor.java:1512) ~[doris-fe.jar:1.2-SNAPSHOT]
        at org.apache.doris.qe.StmtExecutor.analyze(StmtExecutor.java:1298) ~[doris-fe.jar:1.2-SNAPSHOT]
        at org.apache.doris.qe.StmtExecutor.executeByLegacy(StmtExecutor.java:930) ~[doris-fe.jar:1.2-SNAPSHOT]
        at org.apache.doris.qe.StmtExecutor.execute(StmtExecutor.java:618) ~[doris-fe.jar:1.2-SNAPSHOT]
        at org.apache.doris.qe.StmtExecutor.execute(StmtExecutor.java:536) ~[doris-fe.jar:1.2-SNAPSHOT]
        at org.apache.doris.qe.MysqlConnectProcessor.handleExecute(MysqlConnectProcessor.java:137) ~[doris-fe.jar:1.2-SNAPSHOT]
        at org.apache.doris.qe.MysqlConnectProcessor.handleExecute(MysqlConnectProcessor.java:231) ~[doris-fe.jar:1.2-SNAPSHOT]
        at org.apache.doris.qe.MysqlConnectProcessor.dispatch(MysqlConnectProcessor.java:288) ~[doris-fe.jar:1.2-SNAPSHOT]
        at org.apache.doris.qe.MysqlConnectProcessor.processOnce(MysqlConnectProcessor.java:339) ~[doris-fe.jar:1.2-SNAPSHOT]
        at org.apache.doris.mysql.ReadListener.lambda$handleEvent$0(ReadListener.java:52) ~[doris-fe.jar:1.2-SNAPSHOT]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[?:?]
        at java.lang.Thread.run(Thread.java:840) ~[?:?]
```

<!--Describe your changes.-->
  • Loading branch information
xy720 authored Jun 20, 2024
1 parent 24b1d3b commit a0201ac
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,20 @@ public void setLiteral(LiteralExpr literal) {
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());
Expand Down Expand Up @@ -134,11 +148,6 @@ public String toDigestImpl() {
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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ public void asignValues(List<LiteralExpr> values) throws UserException {
}
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()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
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;
Expand Down Expand Up @@ -407,7 +408,8 @@ private PartitionColumnFilter createPartitionFilter(SlotDescriptor desc, List<Ex
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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
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;
Expand Down Expand Up @@ -114,7 +115,11 @@ public Expr apply(Expr expr, Analyzer analyzer, ClauseType clauseType) throws An
// 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);
Expand Down
1 change: 1 addition & 0 deletions regression-test/data/insert_p0/prepare_insert.out
Original file line number Diff line number Diff line change
@@ -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
Expand Down
18 changes: 16 additions & 2 deletions regression-test/suites/insert_p0/prepare_insert.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -238,4 +252,4 @@ suite("prepare_insert") {
}

qt_sql """ select * from ${tableName} order by id, name, score """
}
}

0 comments on commit a0201ac

Please sign in to comment.