From e91a810df8c8a127510c178def297fe732173428 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 19 Dec 2024 20:01:40 +0800 Subject: [PATCH] branch-2.1: [fix](sql cache) fix prepare statement with sql cache throw NullPointerException #45640 (#45650) fix prepare statement with sql cache throw NullPointerException: ```shell java.lang.NullPointerException: Cannot read field "originStmt" because the return value of "org.apache.doris.analysis.StatementBase.getOrigStmt()" is null ``` --- .../org/apache/doris/qe/StmtExecutor.java | 3 +- .../cache/prepare_stmt_with_sql_cache.groovy | 57 +++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 regression-test/suites/nereids_p0/cache/prepare_stmt_with_sql_cache.groovy diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java b/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java index f314f3aa76ce14..97b967920ecde8 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java @@ -1805,7 +1805,8 @@ private void handleQueryStmt() throws Exception { // TODO support arrow flight sql // NOTE: If you want to add another condition about SessionVariable, please consider whether // add to CacheAnalyzer.commonCacheCondition - if (channel != null && !isOutfileQuery && CacheAnalyzer.canUseCache(context.getSessionVariable())) { + if (channel != null && !isOutfileQuery && CacheAnalyzer.canUseCache(context.getSessionVariable()) + && parsedStmt.getOrigStmt() != null && parsedStmt.getOrigStmt().originStmt != null) { if (queryStmt instanceof QueryStmt || queryStmt instanceof LogicalPlanAdapter) { handleCacheStmt(cacheAnalyzer, channel); LOG.info("Query {} finished", DebugUtil.printId(context.queryId)); diff --git a/regression-test/suites/nereids_p0/cache/prepare_stmt_with_sql_cache.groovy b/regression-test/suites/nereids_p0/cache/prepare_stmt_with_sql_cache.groovy new file mode 100644 index 00000000000000..7819a6ca09d719 --- /dev/null +++ b/regression-test/suites/nereids_p0/cache/prepare_stmt_with_sql_cache.groovy @@ -0,0 +1,57 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import com.mysql.cj.ServerPreparedQuery +import com.mysql.cj.jdbc.ConnectionImpl +import com.mysql.cj.jdbc.JdbcStatement +import com.mysql.cj.jdbc.ServerPreparedStatement +import com.mysql.cj.jdbc.StatementImpl +import org.apache.doris.regression.util.JdbcUtils + +import java.lang.reflect.Field +import java.sql.PreparedStatement +import java.sql.ResultSet +import java.util.concurrent.CopyOnWriteArrayList + +suite("prepare_stmt_with_sql_cache") { + + multi_sql """ + drop table if exists test_prepare_stmt_with_sql_cache; + create table test_prepare_stmt_with_sql_cache(id int) + distributed by hash(id) + properties('replication_num'='1'); + + insert into test_prepare_stmt_with_sql_cache select * from numbers('number'='100'); + """ + + def db = (sql "select database()")[0][0].toString() + + def url = getServerPrepareJdbcUrl(context.config.jdbcUrl, db) + + connect(context.config.jdbcUser, context.config.jdbcPassword, url) { + sql "set enable_sql_cache=true" + for (def i in 0..<10) { + try (PreparedStatement pstmt = prepareStatement("select * from test_prepare_stmt_with_sql_cache where id=?")) { + pstmt.setInt(1, i) + try (ResultSet rs = pstmt.executeQuery()) { + def result = JdbcUtils.toList(rs).v1 + logger.info("result: {}", result) + } + } + } + } +}