Skip to content

Commit 33e0796

Browse files
committed
MDEV-36080: Assertion on 2nd PS execution with error and Array Binding
The fix for MDEV-35318 has introduced LEX::needs_reprepare and logic in Prepared_statement::execute_loop() and sp_lex_keeper:: validate_lex_and_exec_core() to re-prepare the statement if it has hit an error when doing once-per-statement-life optimizations. But there is also third code path: PS with Array Binding is handled in Prepared_statement::execute_bulk_loop(). Add handling there as well.
1 parent 1629435 commit 33e0796

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

sql/sql_prepare.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4574,6 +4574,18 @@ Prepared_statement::execute_bulk_loop(String *expanded_query,
45744574
goto err;
45754575
}
45764576

4577+
if (lex->needs_reprepare)
4578+
{
4579+
/*
4580+
Something has happened on previous execution that requires us to
4581+
re-prepare before we try to execute.
4582+
*/
4583+
lex->needs_reprepare= false;
4584+
error= reprepare();
4585+
if (error)
4586+
goto err;
4587+
}
4588+
45774589
if (send_unit_results && thd->init_collecting_unit_results())
45784590
{
45794591
DBUG_PRINT("error", ("Error initializing array."));

tests/mysql_client_test.c

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22888,6 +22888,88 @@ void test_mdev_10075()
2288822888
mysql_free_result(result);
2288922889
}
2289022890

22891+
22892+
#ifndef EMBEDDED_LIBRARY
22893+
/*
22894+
MDEV-36080: Run a Prepared Statement that hits a failure when the query
22895+
optimizer is doing once-per-statement-life optimization. The server should
22896+
re-prepare the statement. Make sure the re-prepare happens when the
22897+
statement parameters are supplied through Array Binding.
22898+
*/
22899+
static void test_mdev_36080()
22900+
{
22901+
MYSQL_STMT *stmt;
22902+
int rc;
22903+
const char *stmt_text;
22904+
MYSQL_BIND bind[1];
22905+
char indicator[]= {0, STMT_INDICATOR_NULL, 0/*STMT_INDICATOR_IGNORE*/};
22906+
my_bool error[1];
22907+
int id[]= {2, 3, 777}, count= sizeof(id)/sizeof(id[0]);
22908+
22909+
myheader("mdev_36080");
22910+
rc= mysql_query(mysql, "SET SQL_MODE=DEFAULT");
22911+
myquery(rc);
22912+
22913+
rc= mysql_query(mysql, "drop table if exists t0");
22914+
myquery(rc);
22915+
rc= mysql_query(mysql, "create table t0(z int);");
22916+
myquery(rc);
22917+
rc= mysql_query(mysql, "insert into t0 values (1);");
22918+
myquery(rc);
22919+
22920+
rc= mysql_query(mysql, "drop table if exists t1");
22921+
myquery(rc);
22922+
rc= mysql_query(mysql, "create table t1 (a int, b int)");
22923+
myquery(rc);
22924+
rc= mysql_query(mysql, "insert into t1 values (1,1)");
22925+
myquery(rc);
22926+
22927+
rc= mysql_query(mysql, "drop table if exists t2");
22928+
myquery(rc);
22929+
rc= mysql_query(mysql, "create table t2 (a int)");
22930+
myquery(rc);
22931+
rc= mysql_query(mysql, "insert into t2 values (1),(2)");
22932+
myquery(rc);
22933+
22934+
stmt= mysql_stmt_init(mysql);
22935+
check_stmt(stmt);
22936+
stmt_text=
22937+
"update t0,t1 set a = a +? "
22938+
" where b = (SELECT * "
22939+
" FROM (select t_10.* from t2 t_10 join t2 t_11 on(t_10.a = t_11.a)) sq "
22940+
" WHERE 'x'=0 LIMIT 1"
22941+
" )";
22942+
22943+
rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
22944+
check_execute(stmt, rc);
22945+
22946+
memset(bind, 0, sizeof(bind));
22947+
bind[0].buffer_type = MYSQL_TYPE_LONG;
22948+
bind[0].buffer = (void *)id;
22949+
bind[0].buffer_length = 0;
22950+
bind[0].is_null = NULL;
22951+
bind[0].length = NULL;
22952+
bind[0].error = error;
22953+
bind[0].u.indicator= indicator;
22954+
22955+
mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, (void*)&count);
22956+
rc= mysql_stmt_bind_param(stmt, bind);
22957+
check_execute(stmt, rc);
22958+
22959+
rc= mysql_stmt_execute(stmt);
22960+
check_execute_r(stmt, rc);
22961+
22962+
rc= mysql_stmt_execute(stmt);
22963+
check_execute_r(stmt, rc);
22964+
22965+
mysql_stmt_close(stmt);
22966+
22967+
rc= mysql_query(mysql, "drop table t0, t1, t2");
22968+
myquery(rc);
22969+
}
22970+
#endif
22971+
22972+
2289122973
static struct my_tests_st my_tests[]= {
2289222974
{ "test_mdev_20516", test_mdev_20516 },
2289322975
{ "test_mdev24827", test_mdev24827 },
@@ -23206,6 +23288,9 @@ static struct my_tests_st my_tests[]= {
2320623288
{ "test_mdev_34958", test_mdev_34958 },
2320723289
#endif
2320823290
{ "test_mdev_10075", test_mdev_10075},
23291+
#ifndef EMBEDDED_LIBRARY
23292+
{ "test_mdev_36080", test_mdev_36080},
23293+
#endif
2320923294
{ 0, 0 }
2321023295
};
2321123296

0 commit comments

Comments
 (0)