diff options
Diffstat (limited to 'sql/sql_handler.cc')
-rw-r--r-- | sql/sql_handler.cc | 91 |
1 files changed, 20 insertions, 71 deletions
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index b5b1fe81430..a811cee998f 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2001, 2015, Oracle and/or its affiliates. - Copyright (c) 2011, 2015, MariaDB + Copyright (c) 2011, 2016, MariaDB Corporation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -31,7 +31,7 @@ then do { handler_items=concat(handler_items, free_list); free_list=0; } But !!! do_command calls free_root at the end of every query and frees up - all the sql_alloc'ed memory. It's harder to work around... + all the memory allocated on THD::mem_root. It's harder to work around... */ /* @@ -179,9 +179,8 @@ static void mysql_ha_close_table(SQL_HANDLER *handler) { /* Must be a temporary table */ table->file->ha_index_or_rnd_end(); - table->query_id= thd->query_id; table->open_by_handler= 0; - mark_tmp_table_for_reuse(table); + thd->mark_tmp_table_as_free_for_reuse(table); } my_free(handler->lock); handler->init(); @@ -285,7 +284,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, SQL_HANDLER *reopen) back-off for such locks. */ tables->mdl_request.init(MDL_key::TABLE, tables->db, tables->table_name, - MDL_SHARED, MDL_TRANSACTION); + MDL_SHARED_READ, MDL_TRANSACTION); mdl_savepoint= thd->mdl_context.mdl_savepoint(); /* for now HANDLER can be used only for real TABLES */ @@ -296,7 +295,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, SQL_HANDLER *reopen) open_ltable() or open_table() because we would like to be able to open a temporary table. */ - error= (open_temporary_tables(thd, tables) || + error= (thd->open_temporary_tables(tables) || open_tables(thd, &tables, &counter, 0)); if (error) @@ -391,8 +390,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, SQL_HANDLER *reopen) /* Assert that the above check prevents opening of views and merge tables. For temporary tables, TABLE::next can be set even if only one table - was opened for HANDLER as it is used to link them together - (see thd->temporary_tables). + was opened for HANDLER as it is used to link them together. */ DBUG_ASSERT(sql_handler->table->next == NULL || sql_handler->table->s->tmp_table); @@ -459,9 +457,10 @@ bool mysql_ha_close(THD *thd, TABLE_LIST *tables) my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0)); DBUG_RETURN(TRUE); } - if ((handler= (SQL_HANDLER*) my_hash_search(&thd->handler_tables_hash, - (uchar*) tables->alias, - strlen(tables->alias) + 1))) + if ((my_hash_inited(&thd->handler_tables_hash)) && + (handler= (SQL_HANDLER*) my_hash_search(&thd->handler_tables_hash, + (uchar*) tables->alias, + strlen(tables->alias) + 1))) { mysql_ha_close_table(handler); my_hash_delete(&thd->handler_tables_hash, (uchar*) handler); @@ -487,56 +486,6 @@ bool mysql_ha_close(THD *thd, TABLE_LIST *tables) /** - A helper class to process an error from mysql_lock_tables(). - HANDLER READ statement's attempt to lock the subject table - may get aborted if there is a pending DDL. In that case - we close the table, reopen it, and try to read again. - This is implicit and obscure, since HANDLER position - is lost in the process, but it's the legacy server - behaviour we should preserve. -*/ - -class Sql_handler_lock_error_handler: public Internal_error_handler -{ -public: - virtual - bool handle_condition(THD *thd, - uint sql_errno, - const char *sqlstate, - Sql_condition::enum_warning_level level, - const char* msg, - Sql_condition **cond_hdl); - - bool need_reopen() const { return m_need_reopen; }; - void init() { m_need_reopen= FALSE; }; -private: - bool m_need_reopen; -}; - - -/** - Handle an error from mysql_lock_tables(). - Ignore ER_LOCK_ABORTED errors. -*/ - -bool -Sql_handler_lock_error_handler:: -handle_condition(THD *thd, - uint sql_errno, - const char *sqlstate, - Sql_condition::enum_warning_level level, - const char* msg, - Sql_condition **cond_hdl) -{ - *cond_hdl= NULL; - if (sql_errno == ER_LOCK_ABORTED) - m_need_reopen= TRUE; - - return m_need_reopen; -} - - -/** Finds an open HANDLER table. @params name Name of handler to open @@ -548,8 +497,10 @@ handle_condition(THD *thd, SQL_HANDLER *mysql_ha_find_handler(THD *thd, const char *name) { SQL_HANDLER *handler; - if ((handler= (SQL_HANDLER*) my_hash_search(&thd->handler_tables_hash, - (uchar*) name, strlen(name) + 1))) + if ((my_hash_inited(&thd->handler_tables_hash)) && + (handler= (SQL_HANDLER*) my_hash_search(&thd->handler_tables_hash, + (uchar*) name, + strlen(name) + 1))) { DBUG_PRINT("info-in-hash",("'%s'.'%s' as '%s' table: %p", handler->db.str, @@ -732,7 +683,7 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, int error, keyno; uint num_rows; uchar *UNINIT_VAR(key); - Sql_handler_lock_error_handler sql_handler_lock_error; + MDL_deadlock_and_lock_abort_error_handler sql_handler_lock_error; DBUG_ENTER("mysql_ha_read"); DBUG_PRINT("enter",("'%s'.'%s' as '%s'", tables->db, tables->table_name, tables->alias)); @@ -751,11 +702,12 @@ retry: tables->table= table; // This is used by fix_fields table->pos_in_table_list= tables; - if (handler->lock->lock_count > 0) + if (handler->lock->table_count > 0) { int lock_error; - handler->lock->locks[0]->type= handler->lock->locks[0]->org_type; + if (handler->lock->lock_count > 0) + handler->lock->locks[0]->type= handler->lock->locks[0]->org_type; /* save open_tables state */ TABLE* backup_open_tables= thd->open_tables; @@ -929,9 +881,6 @@ retry: } goto ok; } - /* Generate values for virtual fields */ - if (table->vfield) - update_virtual_fields(thd, table); if (cond && !cond->val_int()) { if (thd->is_error()) @@ -1195,10 +1144,10 @@ void mysql_ha_set_explicit_lock_duration(THD *thd) Remove temporary tables from the HANDLER's hash table. The reason for having a separate function, rather than calling mysql_ha_rm_tables() is that it is not always feasible (e.g. in - close_temporary_tables) to obtain a TABLE_LIST containing the + THD::close_temporary_tables) to obtain a TABLE_LIST containing the temporary tables. - @See close_temporary_tables + @See THD::close_temporary_tables() @param thd Thread identifier. */ void mysql_ha_rm_temporary_tables(THD *thd) |