[Feature](Prepared Statement) fix and enable enable_server_side_prepared_statement by default #36581 (#36818)

picked from #36581
This commit is contained in:
lihangyu
2024-07-01 14:35:17 +08:00
committed by GitHub
parent 62c4451c97
commit 14c991f09b
13 changed files with 192 additions and 36 deletions

View File

@ -20,6 +20,7 @@ package org.apache.doris.nereids.trees.plans.commands;
import org.apache.doris.mysql.MysqlCommand;
import org.apache.doris.nereids.trees.expressions.Placeholder;
import org.apache.doris.nereids.trees.plans.PlanType;
import org.apache.doris.nereids.trees.plans.commands.insert.InsertIntoTableCommand;
import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor;
import org.apache.doris.qe.ConnectContext;
@ -102,6 +103,10 @@ public class PrepareCommand extends Command {
LOG.debug("add prepared statement {}, isBinaryProtocol {}",
name, ctx.getCommand() == MysqlCommand.COM_STMT_PREPARE);
}
if (logicalPlan instanceof InsertIntoTableCommand
&& ((InsertIntoTableCommand) logicalPlan).getLabelName().isPresent()) {
throw new org.apache.doris.common.UserException("Only support prepare InsertStmt without label now");
}
ctx.addPreparedStatementContext(name,
new PreparedStatementContext(this, ctx, ctx.getStatementContext(), name));
if (ctx.getCommand() == MysqlCommand.COM_STMT_PREPARE) {

View File

@ -35,6 +35,7 @@ import org.apache.doris.catalog.TableIf;
import org.apache.doris.catalog.Type;
import org.apache.doris.cluster.ClusterNamespace;
import org.apache.doris.common.Config;
import org.apache.doris.common.UserException;
import org.apache.doris.common.util.DebugUtil;
import org.apache.doris.common.util.TimeUtils;
import org.apache.doris.datasource.CatalogIf;
@ -394,12 +395,18 @@ public class ConnectContext {
this.preparedStmtCtxs.put(stmtName, ctx);
}
public void addPreparedStatementContext(String stmtName, PreparedStatementContext ctx) {
public void addPreparedStatementContext(String stmtName, PreparedStatementContext ctx) throws UserException {
if (this.preparedStatementContextMap.size() > sessionVariable.maxPreparedStmtCount) {
throw new UserException("Failed to create a server prepared statement"
+ "possibly because there are too many active prepared statements on server already."
+ "set max_prepared_stmt_count with larger number than " + sessionVariable.maxPreparedStmtCount);
}
this.preparedStatementContextMap.put(stmtName, ctx);
}
public void removePrepareStmt(String stmtName) {
this.preparedStmtCtxs.remove(stmtName);
this.preparedStatementContextMap.remove(stmtName);
}
public PrepareStmtContext getPreparedStmt(String stmtName) {

View File

@ -227,7 +227,8 @@ public abstract class ConnectProcessor {
List<StatementBase> cachedStmts = null;
// Currently we add a config to decide whether using PREPARED/EXECUTE command for nereids
// TODO: after implemented full prepared, we could remove this flag
boolean nereidsUseServerPrep = sessionVariable.enableServeSidePreparedStatement
boolean nereidsUseServerPrep = (sessionVariable.enableServeSidePreparedStatement
&& !sessionVariable.isEnableInsertGroupCommit())
|| mysqlCommand == MysqlCommand.COM_QUERY;
if (nereidsUseServerPrep && sessionVariable.isEnableNereidsPlanner()) {
if (wantToParseSqlFromSqlCache) {

View File

@ -20,6 +20,8 @@ package org.apache.doris.qe;
import org.apache.doris.analysis.BinaryPredicate;
import org.apache.doris.analysis.Expr;
import org.apache.doris.analysis.LiteralExpr;
import org.apache.doris.analysis.SlotRef;
import org.apache.doris.catalog.Column;
import org.apache.doris.catalog.Env;
import org.apache.doris.common.Config;
import org.apache.doris.common.Status;
@ -149,7 +151,13 @@ public class PointQueryExecutor implements CoordInterface {
KeyTuple.Builder kBuilder = KeyTuple.newBuilder();
for (Expr expr : shortCircuitQueryContext.scanNode.getConjuncts()) {
BinaryPredicate predicate = (BinaryPredicate) expr;
kBuilder.addKeyColumnRep(predicate.getChild(1).getStringValue());
Expr left = predicate.getChild(0);
Expr right = predicate.getChild(1);
// ignore delete sign conjuncts only collect key conjuncts
if (left instanceof SlotRef && ((SlotRef) left).getColumnName().equalsIgnoreCase(Column.DELETE_SIGN)) {
continue;
}
kBuilder.addKeyColumnRep(right.getStringValue());
}
requestBuilder.addKeyTuples(kBuilder);
}

View File

@ -134,6 +134,7 @@ public class SessionVariable implements Serializable, Writable {
public static final String ENABLE_EXCHANGE_NODE_PARALLEL_MERGE = "enable_exchange_node_parallel_merge";
public static final String ENABLE_SERVER_SIDE_PREPARED_STATEMENT = "enable_server_side_prepared_statement";
public static final String MAX_PREPARED_STMT_COUNT = "max_prepared_stmt_count";
public static final String PREFER_JOIN_METHOD = "prefer_join_method";
public static final String ENABLE_FOLD_CONSTANT_BY_BE = "enable_fold_constant_by_be";
@ -1361,7 +1362,12 @@ public class SessionVariable implements Serializable, Writable {
@VariableMgr.VarAttr(name = ENABLE_SERVER_SIDE_PREPARED_STATEMENT, needForward = true, description = {
"是否启用开启服务端prepared statement", "Set whether to enable server side prepared statement."})
public boolean enableServeSidePreparedStatement = false;
public boolean enableServeSidePreparedStatement = true;
@VariableMgr.VarAttr(name = MAX_PREPARED_STMT_COUNT, flag = VariableMgr.GLOBAL,
needForward = true, description = {
"服务端prepared statement最大个数", "the maximum prepared statements server holds."})
public int maxPreparedStmtCount = 100000;
// Default value is false, which means the group by and having clause
// should first use column name not alias. According to mysql.

View File

@ -53,6 +53,21 @@
-- !select5 --
1
-- !select5 --
a
-- !select5 --
2
-- !select5 --
-2
-- !select5 --
6 MySQL Connector/J
-- !select5 --
0 0 0 0 0
-- !select6 --
2 1 user1 \N 1234.1111 xxxlalala
@ -66,3 +81,24 @@
-- !select9 --
2
-- !select13 --
1
-- !select14 --
1
-- !select15 --
1
-- !sql --
1231 119291.110000000 ddd Will we ignore LIMIT ?,? 2021-01-01 2020-01-01T12:36:38 \N 1022-01-01 ["2022-01-01 11:30:38", "2022-01-01 11:30:38", "2022-01-01 11:30:38"]
1232 12222.991211350 xxx Will we ignore LIMIT ?,? 2021-01-01 2020-01-01T12:36:38 522.762 2022-01-01 ["2023-01-01 11:30:38", "2023-01-01 11:30:38"]
1233 1.392932911 yyy Will we ignore LIMIT ?,? 2021-01-01 2020-01-01T12:36:38 52.862 3022-01-01 ["2024-01-01 11:30:38", "2024-01-01 11:30:38", "2024-01-01 11:30:38"]
1234 12919291.129191137 xxddd Will we ignore LIMIT ?,? 2021-01-01 2020-01-01T12:36:38 552.872 4022-01-01 ["2025-01-01 11:30:38", "2025-01-01 11:30:38", "2025-01-01 11:30:38"]
1235 991129292901.111380000 dd Will we ignore LIMIT ?,? 2021-01-01 2020-01-01T12:36:38 652.692 5022-01-01 []
1236 100320.111390000 laa ddd Will we ignore LIMIT ?,? 2021-01-01 2020-01-01T12:36:38 2.7692 6022-01-01 [null]
1237 120939.111300000 a ddd Will we ignore LIMIT ?,? 2021-01-01 2020-01-01T12:36:38 22.822 7022-01-01 ["2025-01-01 11:30:38"]
-- !select16 --
mytable1 CREATE TABLE `mytable1` (\n `siteid` INT NULL DEFAULT "10",\n `citycode` SMALLINT NULL,\n `username` VARCHAR(32) NULL DEFAULT "",\n `pv` BIGINT SUM NULL DEFAULT "0"\n) ENGINE=OLAP\nAGGREGATE KEY(`siteid`, `citycode`, `username`)\nDISTRIBUTED BY HASH(`siteid`) BUCKETS 10\nPROPERTIES (\n"replication_allocation" = "tag.location.default: 1",\n"min_load_replica_num" = "-1",\n"is_being_synced" = "false",\n"storage_medium" = "hdd",\n"storage_format" = "V2",\n"inverted_index_storage_format" = "V2",\n"light_schema_change" = "true",\n"disable_auto_compaction" = "false",\n"enable_single_replica_compaction" = "false",\n"group_commit_interval_ms" = "10000",\n"group_commit_data_bytes" = "134217728"\n);

View File

@ -36,8 +36,6 @@ suite("test_compaction_uniq_keys_row_store", "nonConcurrent") {
stmt.setInt(8, sex)
}
sql "set global enable_server_side_prepared_statement = true"
try {
String backend_id;
def backendId_to_backendIP = [:]
@ -213,5 +211,4 @@ suite("test_compaction_uniq_keys_row_store", "nonConcurrent") {
} finally {
// try_sql("DROP TABLE IF EXISTS ${tableName}")
}
sql "set global enable_server_side_prepared_statement = false"
}

View File

@ -20,9 +20,8 @@ import java.sql.DriverManager
import java.sql.Statement
import java.sql.PreparedStatement
suite("insert_group_commit_with_exception") {
suite("insert_group_commit_with_exception", "nonConcurrent") {
def table = "insert_group_commit_with_exception"
def getRowCount = { expectedRowCount ->
def retry = 0
while (retry < 30) {
@ -74,9 +73,10 @@ suite("insert_group_commit_with_exception") {
if (item == "nereids") {
sql """ set enable_nereids_dml = true; """
sql """ set enable_nereids_planner=true; """
//sql """ set enable_fallback_to_original_planner=false; """
sql "set global enable_server_side_prepared_statement = true"
} else {
sql """ set enable_nereids_dml = false; """
sql "set global enable_server_side_prepared_statement = false"
}
// insert into without column
@ -161,9 +161,11 @@ suite("insert_group_commit_with_exception") {
if (item == "nereids") {
statement.execute("set enable_nereids_dml = true;");
statement.execute("set enable_nereids_planner=true;");
//statement.execute("set enable_fallback_to_original_planner=false;");
statement.execute("set enable_fallback_to_original_planner=false;");
sql "set global enable_server_side_prepared_statement = true"
} else {
statement.execute("set enable_nereids_dml = false;");
sql "set global enable_server_side_prepared_statement = false"
}
// without column
try (PreparedStatement ps = connection.prepareStatement("insert into ${table} values(?, ?, ?, ?)")) {
@ -287,7 +289,13 @@ suite("insert_group_commit_with_exception") {
result = ps.executeBatch()
assertTrue(false)
} catch (Exception e) {
assertTrue(e.getMessage().contains("Column count doesn't match value count"))
logger.info("exception : " + e)
if (item == "legacy") {
assertTrue(e.getMessage().contains("Column count doesn't match value count"))
}
if (item == "nereids") {
assertTrue(e.getMessage().contains("insert into cols should be corresponding to the query output"))
}
}
}
getRowCount(14)
@ -317,4 +325,5 @@ suite("insert_group_commit_with_exception") {
// try_sql("DROP TABLE ${table}")
}
}
sql "set global enable_server_side_prepared_statement = true"
}

View File

@ -36,7 +36,6 @@ suite("insert_group_commit_with_prepare_stmt") {
def table = realDb + ".insert_group_commit_with_prepare_stmt"
sql "CREATE DATABASE IF NOT EXISTS ${realDb}"
def getRowCount = { expectedRowCount ->
def retry = 0
while (retry < 30) {
@ -89,7 +88,8 @@ suite("insert_group_commit_with_prepare_stmt") {
}
assertTrue(serverInfo.contains("'status':'PREPARE'"))
assertTrue(serverInfo.contains("'label':'group_commit_"))
assertEquals(reuse_plan, serverInfo.contains("reuse_group_commit_plan"))
// TODO: currently if enable_server_side_prepared_statement = true, will not reuse plan
// assertEquals(reuse_plan, serverInfo.contains("reuse_group_commit_plan"))
} else {
// for batch insert
ConnectionImpl connection = (ConnectionImpl) stmt.getConnection()

View File

@ -32,7 +32,6 @@ suite("test_point_query", "nonConcurrent") {
// nereids do not support point query now
sql "set global enable_fallback_to_original_planner = false"
sql """set global enable_nereids_planner=true"""
sql "set global enable_server_side_prepared_statement = true"
def user = context.config.jdbcUser
def password = context.config.jdbcPassword
def realDb = "regression_test_serving_p0"
@ -279,6 +278,5 @@ suite("test_point_query", "nonConcurrent") {
set_be_config.call("disable_storage_row_cache", "true")
sql """set global enable_nereids_planner=true"""
sql "set global enable_fallback_to_original_planner = true"
sql "set global enable_server_side_prepared_statement = false"
}
}

View File

@ -30,7 +30,7 @@ suite("test_point_query_cluster_key") {
try {
set_be_config.call("disable_storage_row_cache", "false")
// nereids do not support point query now
sql """set enable_nereids_planner=false"""
sql """set enable_nereids_planner=true"""
def user = context.config.jdbcUser
def password = context.config.jdbcPassword
@ -139,7 +139,7 @@ suite("test_point_query_cluster_key") {
sql """ INSERT INTO ${tableName} VALUES(298, 120939.11130, "${generateString(298)}", "laooq", "2030-01-02", "2020-01-01 12:36:38", 298, "7022-01-01 11:30:38", 1, 90696620686827832.374, [], []) """
def result1 = connect(user=user, password=password, url=prepare_url) {
def stmt = prepareStatement "select /*+ SET_VAR(enable_nereids_planner=false) */ * from ${tableName} where k1 = ? and k2 = ? and k3 = ?"
def stmt = prepareStatement "select /*+ SET_VAR(enable_nereids_planner=true) */ * from ${tableName} where k1 = ? and k2 = ? and k3 = ?"
assertEquals(stmt.class, com.mysql.cj.jdbc.ServerPreparedStatement);
stmt.setInt(1, 1231)
stmt.setBigDecimal(2, new BigDecimal("119291.11"))
@ -175,13 +175,14 @@ suite("test_point_query_cluster_key") {
qe_point_select stmt
stmt.close()
stmt = prepareStatement "select /*+ SET_VAR(enable_nereids_planner=false) */ * from ${tableName} where k1 = 1235 and k2 = ? and k3 = ?"
stmt = prepareStatement "select /*+ SET_VAR(enable_nereids_planner=true) */ * from ${tableName} where k1 = ? and k2 = ? and k3 = ?"
assertEquals(stmt.class, com.mysql.cj.jdbc.ServerPreparedStatement);
stmt.setBigDecimal(1, new BigDecimal("991129292901.11138"))
stmt.setString(2, "dd")
stmt.setInt(1, 1235)
stmt.setBigDecimal(2, new BigDecimal("991129292901.11138"))
stmt.setString(3, "dd")
qe_point_select stmt
def stmt_fn = prepareStatement "select /*+ SET_VAR(enable_nereids_planner=false) */ hex(k3), hex(k4) from ${tableName} where k1 = ? and k2 =? and k3 = ?"
def stmt_fn = prepareStatement "select /*+ SET_VAR(enable_nereids_planner=true) */ hex(k3), hex(k4) from ${tableName} where k1 = ? and k2 =? and k3 = ?"
assertEquals(stmt_fn.class, com.mysql.cj.jdbc.ServerPreparedStatement);
stmt_fn.setInt(1, 1231)
stmt_fn.setBigDecimal(2, new BigDecimal("119291.11"))
@ -195,8 +196,8 @@ suite("test_point_query_cluster_key") {
"""
sleep(1);
nprep_sql """ INSERT INTO ${tableName} VALUES(1235, 120939.11130, "a ddd", "laooq", "2030-01-02", "2020-01-01 12:36:38", 22.822, "7022-01-01 11:30:38", 1, 1.1111299, [119291.19291], ["111", "222", "333"], 1) """
stmt.setBigDecimal(1, new BigDecimal("120939.11130"))
stmt.setString(2, "a ddd")
stmt.setBigDecimal(2, new BigDecimal("120939.11130"))
stmt.setString(3, "a ddd")
qe_point_select stmt
qe_point_select stmt
// invalidate cache
@ -222,9 +223,9 @@ suite("test_point_query_cluster_key") {
}
// disable useServerPrepStmts
def result2 = connect(user=user, password=password, url=context.config.jdbcUrl) {
qt_sql """select /*+ SET_VAR(enable_nereids_planner=false) */ * from ${tableName} where k1 = 1231 and k2 = 119291.11 and k3 = 'ddd'"""
qt_sql """select /*+ SET_VAR(enable_nereids_planner=false) */ * from ${tableName} where k1 = 1237 and k2 = 120939.11130 and k3 = 'a ddd'"""
qt_sql """select /*+ SET_VAR(enable_nereids_planner=false) */ hex(k3), hex(k4), k7 + 10.1 from ${tableName} where k1 = 1237 and k2 = 120939.11130 and k3 = 'a ddd'"""
qt_sql """select /*+ SET_VAR(enable_nereids_planner=true) */ * from ${tableName} where k1 = 1231 and k2 = 119291.11 and k3 = 'ddd'"""
qt_sql """select /*+ SET_VAR(enable_nereids_planner=true) */ * from ${tableName} where k1 = 1237 and k2 = 120939.11130 and k3 = 'a ddd'"""
qt_sql """select /*+ SET_VAR(enable_nereids_planner=true) */ hex(k3), hex(k4), k7 + 10.1 from ${tableName} where k1 = 1237 and k2 = 120939.11130 and k3 = 'a ddd'"""
// prepared text
// sql """ prepare stmt1 from select * from ${tableName} where k1 = % and k2 = % and k3 = % """
// qt_sql """execute stmt1 using (1231, 119291.11, 'ddd')"""
@ -254,7 +255,7 @@ suite("test_point_query_cluster_key") {
"disable_auto_compaction" = "false"
);"""
sql """insert into ${tableName} values (0, "1", "2", "3")"""
qt_sql """select /*+ SET_VAR(enable_nereids_planner=false) */ * from ${tableName} where customer_key = 0"""
qt_sql """select /*+ SET_VAR(enable_nereids_planner=true) */ * from ${tableName} where customer_key = 0"""
}
}
} finally {

View File

@ -17,13 +17,12 @@
import java.math.BigDecimal;
suite("test_point_query_partition", "nonConcurrent") {
suite("test_point_query_partition") {
def user = context.config.jdbcUser
def password = context.config.jdbcPassword
def realDb = "regression_test_serving_p0"
def tableName = realDb + ".tbl_point_query_partition"
sql "CREATE DATABASE IF NOT EXISTS ${realDb}"
sql "set global enable_server_side_prepared_statement = true"
// Parse url
String jdbcUrl = context.config.jdbcUrl
String urlWithoutSchema = jdbcUrl.substring(jdbcUrl.indexOf("://") + 3)
@ -150,5 +149,4 @@ suite("test_point_query_partition", "nonConcurrent") {
qe_point_selectmmm stmt
qe_point_selecteee stmt
}
sql "set global enable_server_side_prepared_statement = false"
}

View File

@ -16,13 +16,13 @@
// under the License.
import java.math.BigDecimal;
import com.mysql.cj.MysqlType;
suite("test_prepared_stmt", "nonConcurrent") {
def tableName = "tbl_prepared_stmt"
def user = context.config.jdbcUser
def password = context.config.jdbcPassword
def url = context.config.jdbcUrl + "&useServerPrepStmts=true"
sql "set global enable_server_side_prepared_statement = true"
def url = context.config.jdbcUrl + "&useServerPrepStmts=true&useCursorFetch=true"
def result1 = connect(user=user, password=password, url=url) {
sql """DROP TABLE IF EXISTS ${tableName} """
sql """
@ -37,7 +37,7 @@ suite("test_prepared_stmt", "nonConcurrent") {
`k8` datev2 NULL COMMENT "",
`k9` array<datetime> NULL COMMENT ""
) ENGINE=OLAP
DUPLICATE KEY(`k1`, `k2`, `k3`)
UNIQUE KEY(`k1`, `k2`, `k3`)
DISTRIBUTED BY HASH(`k1`, k2, k3) BUCKETS 1
PROPERTIES (
"replication_allocation" = "tag.location.default: 1",
@ -74,6 +74,7 @@ suite("test_prepared_stmt", "nonConcurrent") {
stmt_read1.setInt(2, 1232)
qe_select1 stmt_read1
qe_select1 stmt_read1
stmt_read1.close()
def stmt_read2 = prepareStatement "select * from ${tableName} as t1 join ${tableName} as t2 on t1.`k1` = t2.`k1` where t1.`k1` >= ? and t1.`k2` >= ? and size(t1.`k9`) > ? order by 1, 2, 3"
assertEquals(stmt_read2.class, com.mysql.cj.jdbc.ServerPreparedStatement);
stmt_read2.setInt(1, 1237)
@ -82,6 +83,7 @@ suite("test_prepared_stmt", "nonConcurrent") {
qe_select2 stmt_read2
qe_select2 stmt_read2
qe_select2 stmt_read2
stmt_read2.close()
sql "DROP TABLE IF EXISTS mytable1"
sql """
@ -107,6 +109,7 @@ suite("test_prepared_stmt", "nonConcurrent") {
stmt_read.setInt(2, 1234)
stmt_read.setInt(3, 1)
qe_select3 stmt_read
stmt_read.close()
stmt_read = prepareStatement "SELECT 10"
assertEquals(stmt_read.class, com.mysql.cj.jdbc.ServerPreparedStatement);
@ -114,6 +117,34 @@ suite("test_prepared_stmt", "nonConcurrent") {
stmt_read = prepareStatement "SELECT 1"
assertEquals(stmt_read.class, com.mysql.cj.jdbc.ServerPreparedStatement);
qe_select5 stmt_read
stmt_read = prepareStatement "SELECT 'a' FROM mytable1"
assertEquals(stmt_read.class, com.mysql.cj.jdbc.ServerPreparedStatement);
qe_select5 stmt_read
stmt_read.close()
stmt_read = prepareStatement "SELECT 1-2 + ?"
assertEquals(stmt_read.class, com.mysql.cj.jdbc.ServerPreparedStatement);
stmt_read.setInt(1, 3);
qe_select5 stmt_read
stmt_read.setInt(1, -1);
qe_select5 stmt_read
stmt_read.close()
stmt_read = prepareStatement "SELECT 1 + ? AS c1, 'MySQL' AS c2, ? AS c3"
assertEquals(stmt_read.class, com.mysql.cj.jdbc.ServerPreparedStatement);
stmt_read.setInt(1, 5)
stmt_read.setString(2, "Connector/J")
qe_select5 stmt_read
stmt_read = prepareStatement "SELECT ?, ?, ?, ?, ?"
assertEquals(stmt_read.class, com.mysql.cj.jdbc.ServerPreparedStatement);
boolean value = false;
stmt_read.setBoolean(1, value);
stmt_read.setObject(2, value);
stmt_read.setObject(3, value, MysqlType.BOOLEAN);
stmt_read.setObject(4, value, MysqlType.TINYINT);
stmt_read.setObject(5, value, MysqlType.BIT);
qe_select5 stmt_read
sql """insert into mytable1 values(2,1,'user1',null);"""
stmt_read = prepareStatement "SELECT *, ? FROM (select *, ? from mytable1 where pv is null) AS `SpotfireCustomQuery1` WHERE 1 = 1"
@ -124,16 +155,75 @@ suite("test_prepared_stmt", "nonConcurrent") {
stmt_read.setString(1, "1111111")
stmt_read.setString(2, "1111111")
qe_select7 stmt_read
stmt_read.close()
stmt_read = prepareStatement "SELECT COUNT() from mytable1 WHERE citycode = ? GROUP BY siteid"
assertEquals(stmt_read.class, com.mysql.cj.jdbc.ServerPreparedStatement);
stmt_read.setString(1, "1")
qe_select8 stmt_read
stmt_read.close()
stmt_read = prepareStatement "SELECT COUNT() from mytable1 WHERE citycode = ? GROUP BY ?"
assertEquals(stmt_read.class, com.mysql.cj.jdbc.ServerPreparedStatement);
stmt_read.setString(1, "1")
stmt_read.setString(2, "1")
qe_select9 stmt_read
}
stmt_read.close()
sql "set global enable_server_side_prepared_statement = false"
// multi statements
// stmt_read = prepareStatement "SELECT 1 FROM mytable1;SELECT 1 FROM mytable1"
// assertEquals(stmt_read.class, com.mysql.cj.jdbc.ServerPreparedStatement);
// qe_select10 stmt_read
// stmt_read.close()
// stmt_read = prepareStatement "SELECT ? FROM mytable1;SELECT ? FROM mytable1 WHERE citycode = ?"
// assertEquals(stmt_read.class, com.mysql.cj.jdbc.ServerPreparedStatement);
// stmt_read.setString(1, "1")
// stmt_read.setString(2, "1")
// stmt_read.setString(3, "1")
// qe_select11 stmt_read
// stmt_read.close()
// prepared stmt outof limit
sql "set global max_prepared_stmt_count = 1"
stmt_read = prepareStatement "SELECT 1"
qe_select13 stmt_read
assertEquals(stmt_read.class, com.mysql.cj.jdbc.ClientPreparedStatement);
stmt_read = prepareStatement "SELECT 1"
assertEquals(stmt_read.class, com.mysql.cj.jdbc.ClientPreparedStatement);
// set back
sql "set global max_prepared_stmt_count = 1000000"
// limit
stmt_read = prepareStatement "SELECT 1 LIMIT ?"
assertEquals(stmt_read.class, com.mysql.cj.jdbc.ClientPreparedStatement);
stmt_read.setInt(1, 1)
qe_select14 stmt_read
stmt_read = prepareStatement "SELECT 1 LIMIT 1"
assertEquals(stmt_read.class, com.mysql.cj.jdbc.ServerPreparedStatement);
qe_select15 stmt_read
// insert with label
stmt_read = prepareStatement "insert into mytable1 with xxx_label 12222 values(?, ?, ?, ?)"
assertEquals(stmt_read.class, com.mysql.cj.jdbc.ClientPreparedStatement);
// alter stmt
stmt_read = prepareStatement "alter table mytable1 rename mytable2"
assertEquals(stmt_read.class, com.mysql.cj.jdbc.ClientPreparedStatement);
// update stmt
stmt_read = prepareStatement "update tbl_prepared_stmt set k5 = ?"
assertEquals(stmt_read.class, com.mysql.cj.jdbc.ServerPreparedStatement);
stmt_read.setString(1, "2021-01-01")
def result = stmt_read.execute()
logger.info("result: ${result}")
stmt_read = prepareStatement "update tbl_prepared_stmt set k4 = 'Will we ignore LIMIT ?,?'"
assertEquals(stmt_read.class, com.mysql.cj.jdbc.ServerPreparedStatement);
result = stmt_read.execute()
logger.info("result: ${result}")
qt_sql "select * from tbl_prepared_stmt where k4 = 'Will we ignore LIMIT ?,?' order by k1"
// show create table
stmt_read = prepareStatement "SHOW CREATE TABLE mytable1"
assertEquals(stmt_read.class, com.mysql.cj.jdbc.ClientPreparedStatement);
// not stable
// qe_select16 stmt_read
stmt_read.close()
}
}