Skip to content

Commit 81378b3

Browse files
author
Alexander Barkov
committed
Moving a change_list related methods from THD to Item_change_list
1. Moving the following methods from THD to Item_change_list: nocheck_register_item_tree_change() check_and_register_item_tree_change() rollback_item_tree_changes() as they work only with the "change_list" member and don't require anything else from THD. 2. Deriving THD from Item_change_list This change will help to fix "MDEV-14603 signal 11 with short stacktrace" easier.
1 parent be85c2d commit 81378b3

File tree

5 files changed

+41
-28
lines changed

5 files changed

+41
-28
lines changed

sql/sp_head.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1249,7 +1249,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
12491249
We should also save Item tree change list to avoid rollback something
12501250
too early in the calling query.
12511251
*/
1252-
thd->change_list.move_elements_to(&old_change_list);
1252+
thd->Item_change_list::move_elements_to(&old_change_list);
12531253
/*
12541254
Cursors will use thd->packet, so they may corrupt data which was prepared
12551255
for sending by upper level. OTOH cursors in the same routine can share this
@@ -1389,8 +1389,8 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
13891389
/* Restore all saved */
13901390
thd->server_status= (thd->server_status & ~status_backup_mask) | old_server_status;
13911391
old_packet.swap(thd->packet);
1392-
DBUG_ASSERT(thd->change_list.is_empty());
1393-
old_change_list.move_elements_to(&thd->change_list);
1392+
DBUG_ASSERT(thd->Item_change_list::is_empty());
1393+
old_change_list.move_elements_to(thd);
13941394
thd->lex= old_lex;
13951395
thd->set_query_id(old_query_id);
13961396
DBUG_ASSERT(!thd->derived_tables);
@@ -2976,7 +2976,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
29762976
bool parent_modified_non_trans_table= thd->transaction.stmt.modified_non_trans_table;
29772977
thd->transaction.stmt.modified_non_trans_table= FALSE;
29782978
DBUG_ASSERT(!thd->derived_tables);
2979-
DBUG_ASSERT(thd->change_list.is_empty());
2979+
DBUG_ASSERT(thd->Item_change_list::is_empty());
29802980
/*
29812981
Use our own lex.
29822982
We should not save old value since it is saved/restored in

sql/sql_class.cc

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2605,8 +2605,10 @@ struct Item_change_record: public ilink
26052605
thd->mem_root (due to possible set_n_backup_active_arena called for thd).
26062606
*/
26072607

2608-
void THD::nocheck_register_item_tree_change(Item **place, Item *old_value,
2609-
MEM_ROOT *runtime_memroot)
2608+
void
2609+
Item_change_list::nocheck_register_item_tree_change(Item **place,
2610+
Item *old_value,
2611+
MEM_ROOT *runtime_memroot)
26102612
{
26112613
Item_change_record *change;
26122614
DBUG_ENTER("THD::nocheck_register_item_tree_change");
@@ -2647,8 +2649,10 @@ void THD::nocheck_register_item_tree_change(Item **place, Item *old_value,
26472649
changes to substitute the same reference at both locations L1 and L2.
26482650
*/
26492651

2650-
void THD::check_and_register_item_tree_change(Item **place, Item **new_value,
2651-
MEM_ROOT *runtime_memroot)
2652+
void
2653+
Item_change_list::check_and_register_item_tree_change(Item **place,
2654+
Item **new_value,
2655+
MEM_ROOT *runtime_memroot)
26522656
{
26532657
Item_change_record *change;
26542658
I_List_iterator<Item_change_record> it(change_list);
@@ -2663,7 +2667,7 @@ void THD::check_and_register_item_tree_change(Item **place, Item **new_value,
26632667
}
26642668

26652669

2666-
void THD::rollback_item_tree_changes()
2670+
void Item_change_list::rollback_item_tree_changes()
26672671
{
26682672
I_List_iterator<Item_change_record> it(change_list);
26692673
Item_change_record *change;

sql/sql_class.h

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,7 +1279,21 @@ class Security_context {
12791279
*/
12801280

12811281
struct Item_change_record;
1282-
typedef I_List<Item_change_record> Item_change_list;
1282+
class Item_change_list
1283+
{
1284+
I_List<Item_change_record> change_list;
1285+
public:
1286+
void nocheck_register_item_tree_change(Item **place, Item *old_value,
1287+
MEM_ROOT *runtime_memroot);
1288+
void check_and_register_item_tree_change(Item **place, Item **new_value,
1289+
MEM_ROOT *runtime_memroot);
1290+
void rollback_item_tree_changes();
1291+
void move_elements_to(Item_change_list *to)
1292+
{
1293+
change_list.move_elements_to(&to->change_list);
1294+
}
1295+
bool is_empty() { return change_list.is_empty(); }
1296+
};
12831297

12841298

12851299
/**
@@ -2040,6 +2054,14 @@ void dbug_serve_apcs(THD *thd, int n_calls);
20402054
*/
20412055

20422056
class THD :public Statement,
2057+
/*
2058+
This is to track items changed during execution of a prepared
2059+
statement/stored procedure. It's created by
2060+
nocheck_register_item_tree_change() in memory root of THD,
2061+
and freed in rollback_item_tree_changes().
2062+
For conventional execution it's always empty.
2063+
*/
2064+
public Item_change_list,
20432065
public MDL_context_owner,
20442066
public Open_tables_state
20452067
{
@@ -2510,14 +2532,6 @@ class THD :public Statement,
25102532
#ifdef SIGNAL_WITH_VIO_CLOSE
25112533
Vio* active_vio;
25122534
#endif
2513-
/*
2514-
This is to track items changed during execution of a prepared
2515-
statement/stored procedure. It's created by
2516-
nocheck_register_item_tree_change() in memory root of THD, and freed in
2517-
rollback_item_tree_changes(). For conventional execution it's always
2518-
empty.
2519-
*/
2520-
Item_change_list change_list;
25212535

25222536
/*
25232537
A permanent memory area of the statement. For conventional
@@ -3599,11 +3613,6 @@ class THD :public Statement,
35993613
*/
36003614
memcpy((char*) place, new_value, sizeof(*new_value));
36013615
}
3602-
void nocheck_register_item_tree_change(Item **place, Item *old_value,
3603-
MEM_ROOT *runtime_memroot);
3604-
void check_and_register_item_tree_change(Item **place, Item **new_value,
3605-
MEM_ROOT *runtime_memroot);
3606-
void rollback_item_tree_changes();
36073616

36083617
/*
36093618
Cleanup statement parse state (parse tree, lex) and execution

sql/sql_parse.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7910,7 +7910,7 @@ void mysql_parse(THD *thd, char *rawbuf, uint length,
79107910
sp_cache_enforce_limit(thd->sp_func_cache, stored_program_cache_size);
79117911
thd->end_statement();
79127912
thd->cleanup_after_query();
7913-
DBUG_ASSERT(thd->change_list.is_empty());
7913+
DBUG_ASSERT(thd->Item_change_list::is_empty());
79147914
}
79157915
else
79167916
{

sql/sql_prepare.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3930,7 +3930,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
39303930
If called from a stored procedure, ensure that we won't rollback
39313931
external changes when cleaning up after validation.
39323932
*/
3933-
DBUG_ASSERT(thd->change_list.is_empty());
3933+
DBUG_ASSERT(thd->Item_change_list::is_empty());
39343934

39353935
/*
39363936
Marker used to release metadata locks acquired while the prepared
@@ -4407,7 +4407,7 @@ Prepared_statement::execute_server_runnable(Server_runnable *server_runnable)
44074407
bool error;
44084408
Query_arena *save_stmt_arena= thd->stmt_arena;
44094409
Item_change_list save_change_list;
4410-
thd->change_list.move_elements_to(&save_change_list);
4410+
thd->Item_change_list::move_elements_to(&save_change_list);
44114411

44124412
state= STMT_CONVENTIONAL_EXECUTION;
44134413

@@ -4426,7 +4426,7 @@ Prepared_statement::execute_server_runnable(Server_runnable *server_runnable)
44264426
thd->restore_backup_statement(this, &stmt_backup);
44274427
thd->stmt_arena= save_stmt_arena;
44284428

4429-
save_change_list.move_elements_to(&thd->change_list);
4429+
save_change_list.move_elements_to(thd);
44304430

44314431
/* Items and memory will freed in destructor */
44324432

@@ -4654,7 +4654,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
46544654
If the free_list is not empty, we'll wrongly free some externally
46554655
allocated items when cleaning up after execution of this statement.
46564656
*/
4657-
DBUG_ASSERT(thd->change_list.is_empty());
4657+
DBUG_ASSERT(thd->Item_change_list::is_empty());
46584658

46594659
/*
46604660
The only case where we should have items in the thd->free_list is

0 commit comments

Comments
 (0)