diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/opt_range.cc | 8 | ||||
-rw-r--r-- | sql/sql_class.cc | 69 | ||||
-rw-r--r-- | sql/sql_class.h | 16 |
3 files changed, 66 insertions, 27 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 27e8e9c11e7..9c5b0235767 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -2554,7 +2554,8 @@ static bool null_part_in_key(KEY_PART *key_part, const char *key, uint length) QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, TABLE_REF *ref) { - QUICK_SELECT *quick=new QUICK_SELECT(thd, table, ref->key, 1); + MEM_ROOT *old_root= my_pthread_getspecific_ptr(MEM_ROOT*, THR_MALLOC); + QUICK_SELECT *quick= new QUICK_SELECT(thd, table, ref->key); KEY *key_info = &table->key_info[ref->key]; KEY_PART *key_part; QUICK_RANGE *range; @@ -2566,7 +2567,7 @@ QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, TABLE_REF *ref) { if (thd->is_fatal_error) goto err; // out of memory - return quick; // empty range + goto ok; // empty range } if (!(range= new QUICK_RANGE())) @@ -2613,9 +2614,12 @@ QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, TABLE_REF *ref) goto err; } +ok: + my_pthread_setspecific_ptr(THR_MALLOC, old_root); return quick; err: + my_pthread_setspecific_ptr(THR_MALLOC, old_root); delete quick; return 0; } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 16c0c206df3..2074f0f5d40 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -221,7 +221,6 @@ THD::THD() init(); /* Initialize sub structures */ - clear_alloc_root(&transaction.mem_root); init_alloc_root(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE); user_connect=(USER_CONN *)0; hash_init(&user_vars, &my_charset_bin, USER_VARS_HASH_SIZE, 0, 0, @@ -258,6 +257,7 @@ THD::THD() transaction.trans_log.end_of_file= max_binlog_cache_size; } #endif + init_alloc_root(&transaction.mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0); { ulong tmp=sql_rnd_with_mutex(); randominit(&rand, tmp + (ulong) &rand, tmp + (ulong) ::query_id); @@ -303,12 +303,12 @@ void THD::init(void) void THD::init_for_queries() { ha_enable_transaction(this,TRUE); - init_sql_alloc(&mem_root, - variables.query_alloc_block_size, - variables.query_prealloc_size); - init_sql_alloc(&transaction.mem_root, - variables.trans_alloc_block_size, - variables.trans_prealloc_size); + + reset_root_defaults(&mem_root, variables.query_alloc_block_size, + variables.query_prealloc_size); + reset_root_defaults(&transaction.mem_root, + variables.trans_alloc_block_size, + variables.trans_prealloc_size); } @@ -1331,6 +1331,17 @@ void select_dumpvar::cleanup() } +/* + Create arena for already constructed THD. + + SYNOPSYS + Item_arena() + thd - thread for which arena is created + + DESCRIPTION + Create arena for already existing THD using its variables as parameters + for memory root initialization. +*/ Item_arena::Item_arena(THD* thd) :free_list(0), state(INITIALIZED) @@ -1341,24 +1352,31 @@ Item_arena::Item_arena(THD* thd) } -/* This constructor is called when Item_arena is a subobject of THD */ +/* + Create arena and optionally initialize memory root. -Item_arena::Item_arena() - :free_list(0), - state(CONVENTIONAL_EXECUTION) -{ - clear_alloc_root(&mem_root); -} + SYNOPSYS + Item_arena() + init_mem_root - whenever we need to initialize memory root + DESCRIPTION + Create arena and optionally initialize memory root with minimal + possible parameters. + NOTE + We use this constructor when arena is part of THD, but reinitialize + its memory root in THD::init_for_queries() before execution of real + statements. +*/ Item_arena::Item_arena(bool init_mem_root) :free_list(0), - state(INITIALIZED) + state(CONVENTIONAL_EXECUTION) { if (init_mem_root) - clear_alloc_root(&mem_root); + init_alloc_root(&mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0); } + Item_arena::Type Item_arena::type() const { DBUG_ASSERT("Item_arena::type()" == "abstract"); @@ -1366,10 +1384,6 @@ Item_arena::Type Item_arena::type() const } -Item_arena::~Item_arena() -{} - - /* Statement functions */ @@ -1393,7 +1407,8 @@ Statement::Statement(THD *thd) */ Statement::Statement() - :id(0), + :Item_arena((bool)TRUE), + id(0), set_query_id(1), allow_sum_func(0), /* initialized later */ lex(&main_lex), @@ -1461,8 +1476,16 @@ void Item_arena::restore_backup_item_arena(Item_arena *set, Item_arena *backup) { set->set_item_arena(this); set_item_arena(backup); - // reset backup mem_root to avoid its freeing - init_alloc_root(&backup->mem_root, 0, 0); +#ifdef NOT_NEEDED_NOW + /* + Reset backup mem_root to avoid its freeing. + Since Item_arena's mem_root is freed only when it is part of Statement + we need this only if we use some Statement's arena as backup storage. + But we do this only with THD::stmt_backup and this Statement is specially + handled in this respect. So this code is not really needed now. + */ + clear_alloc_root(&backup->mem_root); +#endif } void Item_arena::set_item_arena(Item_arena *set) diff --git a/sql/sql_class.h b/sql/sql_class.h index 387bba43cad..89bf2dde12e 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -441,11 +441,23 @@ public: STATEMENT, PREPARED_STATEMENT, STORED_PROCEDURE }; + /* + This constructor is used only when Item_arena is created as + backup storage for another instance of Item_arena. + */ + Item_arena() {}; + /* + Create arena for already constructed THD using its variables as + parameters for memory root initialization. + */ Item_arena(THD *thd); - Item_arena(); + /* + Create arena and optionally init memory root with minimal values. + Particularly used if Item_arena is part of Statement. + */ Item_arena(bool init_mem_root); virtual Type type() const; - virtual ~Item_arena(); + virtual ~Item_arena() {}; inline bool is_stmt_prepare() const { return (int)state < (int)PREPARED; } inline bool is_first_stmt_execute() const { return state == PREPARED; } |