Skip to content

Commit 8505dc7

Browse files
MDEV-35510 ASAN build crashes during bootstrap
Avoid ASAN failure by collecting statistics from Result objects before cleaning them up. In related single-table cases, statistics are maintained directly by the single-table update and delete functions.
1 parent 6be0940 commit 8505dc7

File tree

6 files changed

+60
-27
lines changed

6 files changed

+60
-27
lines changed

sql/sql_cmd.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#ifndef SQL_CMD_INCLUDED
2121
#define SQL_CMD_INCLUDED
2222

23+
#include <my_base.h>
24+
2325
/*
2426
When a command is added here, be sure it's also added in mysqld.cc
2527
in "struct show_var_st status_vars[]= {" ...
@@ -224,6 +226,11 @@ class Sql_cmd : public Sql_alloc
224226
*/
225227
virtual bool is_dml() const { return false; }
226228

229+
virtual void get_dml_stat (ha_rows &found, ha_rows &changed)
230+
{
231+
found= changed= 0;
232+
}
233+
227234
/**
228235
@brief Unprepare prepared statement for the command
229236
@param thd global context of the processed statement

sql/sql_delete.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,6 @@ bool Sql_cmd_delete::delete_from_single_table(THD *thd)
328328
SQL_SELECT *select= 0;
329329
SORT_INFO *file_sort= 0;
330330
READ_RECORD info;
331-
ha_rows deleted= 0;
332331
bool reverse= FALSE;
333332
bool binlog_is_row;
334333
killed_state killed_status= NOT_KILLED;
@@ -1861,6 +1860,9 @@ bool Sql_cmd_delete::execute_inner(THD *thd)
18611860

18621861
if (result)
18631862
{
1863+
/* In single table case, this->deleted set by delete_from_single_table */
1864+
if (res && multitable)
1865+
deleted= ((multi_delete*)get_result())->num_deleted();
18641866
res= false;
18651867
delete result;
18661868
}

sql/sql_delete.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ template <typename T> class SQL_I_List;
4343
class Sql_cmd_delete final : public Sql_cmd_dml
4444
{
4545
public:
46+
ha_rows deleted{0};
4647
Sql_cmd_delete(bool multitable_arg)
4748
: orig_multitable(multitable_arg), multitable(multitable_arg),
4849
save_protocol(NULL)
@@ -66,6 +67,12 @@ class Sql_cmd_delete final : public Sql_cmd_dml
6667

6768
void remove_order_by_without_limit(THD *thd);
6869

70+
void get_dml_stat (ha_rows &found, ha_rows &changed) override
71+
{
72+
found= 0;
73+
changed= deleted;
74+
}
75+
6976
protected:
7077
/**
7178
@brief Perform precheck of table privileges for delete statements

sql/sql_select.cc

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -34139,39 +34139,38 @@ static void MYSQL_DML_START(THD *thd)
3413934139
}
3414034140

3414134141

34142-
static void MYSQL_DML_DONE(THD *thd, int rc)
34142+
static void MYSQL_DML_GET_STAT(THD * thd, ha_rows &found, ha_rows &changed)
3414334143
{
3414434144
switch (thd->lex->sql_command) {
34145+
case SQLCOM_UPDATE:
34146+
case SQLCOM_UPDATE_MULTI:
34147+
case SQLCOM_DELETE_MULTI:
34148+
thd->lex->m_sql_cmd->get_dml_stat(found, changed);
34149+
break;
34150+
case SQLCOM_DELETE:
34151+
found= 0;
34152+
changed= (thd->get_row_count_func());
34153+
break;
34154+
default:
34155+
DBUG_ASSERT(0);
34156+
}
34157+
}
34158+
3414534159

34160+
static void MYSQL_DML_DONE(THD *thd, int rc, ha_rows found, ha_rows changed)
34161+
{
34162+
switch (thd->lex->sql_command) {
3414634163
case SQLCOM_UPDATE:
34147-
MYSQL_UPDATE_DONE(
34148-
rc,
34149-
(rc ? 0 :
34150-
((multi_update*)(((Sql_cmd_dml*)(thd->lex->m_sql_cmd))->get_result()))
34151-
->num_found()),
34152-
(rc ? 0 :
34153-
((multi_update*)(((Sql_cmd_dml*)(thd->lex->m_sql_cmd))->get_result()))
34154-
->num_updated()));
34164+
MYSQL_UPDATE_DONE(rc, found, changed);
3415534165
break;
3415634166
case SQLCOM_UPDATE_MULTI:
34157-
MYSQL_MULTI_UPDATE_DONE(
34158-
rc,
34159-
(rc ? 0 :
34160-
((multi_update*)(((Sql_cmd_dml*)(thd->lex->m_sql_cmd))->get_result()))
34161-
->num_found()),
34162-
(rc ? 0 :
34163-
((multi_update*)(((Sql_cmd_dml*)(thd->lex->m_sql_cmd))->get_result()))
34164-
->num_updated()));
34167+
MYSQL_MULTI_UPDATE_DONE(rc, found, changed);
3416534168
break;
3416634169
case SQLCOM_DELETE:
34167-
MYSQL_DELETE_DONE(rc, (rc ? 0 : (ulong) (thd->get_row_count_func())));
34170+
MYSQL_DELETE_DONE(rc, changed);
3416834171
break;
3416934172
case SQLCOM_DELETE_MULTI:
34170-
MYSQL_MULTI_DELETE_DONE(
34171-
rc,
34172-
(rc ? 0 :
34173-
((multi_delete*)(((Sql_cmd_dml*)(thd->lex->m_sql_cmd))->get_result()))
34174-
->num_deleted()));
34173+
MYSQL_MULTI_DELETE_DONE(rc, changed);
3417534174
break;
3417634175
default:
3417734176
DBUG_ASSERT(0);
@@ -34260,6 +34259,7 @@ bool Sql_cmd_dml::prepare(THD *thd)
3426034259
bool Sql_cmd_dml::execute(THD *thd)
3426134260
{
3426234261
lex = thd->lex;
34262+
ha_rows found= 0, changed= 0;
3426334263
bool res;
3426434264

3426534265
SELECT_LEX_UNIT *unit = &lex->unit;
@@ -34310,6 +34310,8 @@ bool Sql_cmd_dml::execute(THD *thd)
3431034310

3431134311
if (res)
3431234312
goto err;
34313+
else
34314+
MYSQL_DML_GET_STAT(thd, found, changed);
3431334315

3431434316
res= unit->cleanup();
3431534317

@@ -34318,13 +34320,13 @@ bool Sql_cmd_dml::execute(THD *thd)
3431834320

3431934321
THD_STAGE_INFO(thd, stage_end);
3432034322

34321-
MYSQL_DML_DONE(thd, res);
34323+
MYSQL_DML_DONE(thd, 0, found, changed);
3432234324

3432334325
return res;
3432434326

3432534327
err:
3432634328
DBUG_ASSERT(thd->is_error() || thd->killed);
34327-
MYSQL_DML_DONE(thd, 1);
34329+
MYSQL_DML_DONE(thd, 1, 0, 0);
3432834330
THD_STAGE_INFO(thd, stage_end);
3432934331
(void)unit->cleanup();
3433034332
if (is_prepared())

sql/sql_update.cc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ bool Sql_cmd_update::update_single_table(THD *thd)
366366
ha_rows dup_key_found;
367367
bool need_sort= TRUE;
368368
bool reverse= FALSE;
369-
ha_rows updated, updated_or_same, found;
369+
ha_rows updated_or_same;
370370
key_map old_covering_keys;
371371
TABLE *table;
372372
SQL_SELECT *select= NULL;
@@ -3140,6 +3140,13 @@ bool Sql_cmd_update::execute_inner(THD *thd)
31403140

31413141
if (result)
31423142
{
3143+
/* In single table case, this->updated set by update_single_table */
3144+
if (res && multitable)
3145+
{
3146+
found= ((multi_update*)get_result())->num_found();
3147+
updated= ((multi_update*)get_result())->num_updated();
3148+
}
3149+
31433150
res= false;
31443151
delete result;
31453152
}

sql/sql_update.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ bool compare_record(const TABLE *table);
4545
class Sql_cmd_update final : public Sql_cmd_dml
4646
{
4747
public:
48+
ha_rows found{0}, updated{0};
4849
Sql_cmd_update(bool multitable_arg)
4950
: orig_multitable(multitable_arg), multitable(multitable_arg)
5051
{}
@@ -65,6 +66,13 @@ class Sql_cmd_update final : public Sql_cmd_dml
6566

6667
void set_as_multitable() { multitable= true; }
6768

69+
void get_dml_stat (ha_rows &found, ha_rows &changed) override
70+
{
71+
72+
found= this->found;
73+
changed= this->updated;
74+
}
75+
6876
protected:
6977
/**
7078
@brief Perform precheck of table privileges for update statements

0 commit comments

Comments
 (0)