diff options
author | Nirbhay Choubey <nirbhay@skysql.com> | 2014-03-26 14:27:24 -0400 |
---|---|---|
committer | Nirbhay Choubey <nirbhay@skysql.com> | 2014-03-26 14:27:24 -0400 |
commit | 90e4f7f9d3f2669ac99f2817f884315bfc86b0a7 (patch) | |
tree | 60a10a515a9f5656e797d8142f97b94f89f4e797 /sql/handler.cc | |
parent | 586fab72f01e1c7f0f8bf363fa6b06a2f10965b4 (diff) | |
parent | 5b7cab82195268f7657504d0b53995654748cefa (diff) | |
download | mariadb-git-90e4f7f9d3f2669ac99f2817f884315bfc86b0a7.tar.gz |
* bzr merge -rtag:mariadb-10.0.9 maria/10.0
* Fix for post-merge build failures.
Diffstat (limited to 'sql/handler.cc')
-rw-r--r-- | sql/handler.cc | 144 |
1 files changed, 96 insertions, 48 deletions
diff --git a/sql/handler.cc b/sql/handler.cc index 4c797259e2c..40d53170557 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -389,12 +389,13 @@ static int ha_finish_errors(void) static volatile int32 need_full_discover_for_existence= 0; static volatile int32 engines_with_discover_table_names= 0; +static volatile int32 engines_with_discover= 0; static int full_discover_for_existence(handlerton *, const char *, const char *) -{ return 1; } +{ return 0; } static int ext_based_existence(handlerton *, const char *, const char *) -{ return 1; } +{ return 0; } static int hton_ext_based_table_discovery(handlerton *hton, LEX_STRING *db, MY_DIR *dir, handlerton::discovered_list *result) @@ -414,6 +415,9 @@ static void update_discovery_counters(handlerton *hton, int val) if (hton->discover_table_names) my_atomic_add32(&engines_with_discover_table_names, val); + + if (hton->discover_table) + my_atomic_add32(&engines_with_discover, val); } int ha_finalize_handlerton(st_plugin_int *plugin) @@ -1254,7 +1258,8 @@ int ha_commit_trans(THD *thd, bool all) the changes are not durable as they might be rolled back if the enclosing 'all' transaction is rolled back. */ - bool is_real_trans= all || thd->transaction.all.ha_list == 0; + bool is_real_trans= ((all || thd->transaction.all.ha_list == 0) && + !(thd->variables.option_bits & OPTION_GTID_BEGIN)); Ha_trx_info *ha_info= trans->ha_list; bool need_prepare_ordered, need_commit_ordered; my_xid xid; @@ -1269,7 +1274,7 @@ int ha_commit_trans(THD *thd, bool all) ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));); DBUG_PRINT("info", - ("all: %d thd->in_sub_stmt: %d ha_info: %p is_real_trans: %d", + ("all: %d thd->in_sub_stmt: %d ha_info: %p is_real_trans: %d", all, thd->in_sub_stmt, ha_info, is_real_trans)); /* We must not commit the normal transaction if a statement @@ -1311,7 +1316,10 @@ int ha_commit_trans(THD *thd, bool all) Free resources and perform other cleanup even for 'empty' transactions. */ if (is_real_trans) - thd->transaction.cleanup(); + { + thd->transaction.cleanup(); + thd->wakeup_subsequent_commits(error); + } DBUG_RETURN(0); } @@ -1350,6 +1358,7 @@ int ha_commit_trans(THD *thd, bool all) thd->variables.lock_wait_timeout)) { ha_rollback_trans(thd, all); + thd->wakeup_subsequent_commits(1); DBUG_RETURN(1); } @@ -1461,6 +1470,7 @@ done: err: error= 1; /* Transaction was rolled back */ ha_rollback_trans(thd, all); + thd->wakeup_subsequent_commits(error); end: if (rw_trans && mdl_request.ticket) @@ -1503,11 +1513,16 @@ int ha_commit_one_phase(THD *thd, bool all) ha_commit_one_phase() can be called with an empty transaction.all.ha_list, see why in trans_register_ha()). */ - bool is_real_trans=all || thd->transaction.all.ha_list == 0; + bool is_real_trans= ((all || thd->transaction.all.ha_list == 0) && + !(thd->variables.option_bits & OPTION_GTID_BEGIN)); int res; DBUG_ENTER("ha_commit_one_phase"); - if (is_real_trans && (res= thd->wait_for_prior_commit())) - DBUG_RETURN(res); + if (is_real_trans) + { + DEBUG_SYNC(thd, "ha_commit_one_phase"); + if ((res= thd->wait_for_prior_commit())) + DBUG_RETURN(res); + } res= commit_one_phase_2(thd, all, trans, is_real_trans); DBUG_RETURN(res); } @@ -1519,7 +1534,8 @@ commit_one_phase_2(THD *thd, bool all, THD_TRANS *trans, bool is_real_trans) int error= 0; Ha_trx_info *ha_info= trans->ha_list, *ha_info_next; DBUG_ENTER("commit_one_phase_2"); - + if (is_real_trans) + DEBUG_SYNC(thd, "commit_one_phase_2"); if (ha_info) { for (; ha_info; ha_info= ha_info_next) @@ -1632,10 +1648,7 @@ int ha_rollback_trans(THD *thd, bool all) /* Always cleanup. Even if nht==0. There may be savepoints. */ if (is_real_trans) - { - thd->wakeup_subsequent_commits(error); thd->transaction.cleanup(); - } if (all) thd->transaction_rollback_request= FALSE; @@ -2498,7 +2511,7 @@ int handler::ha_open(TABLE *table_arg, const char *name, int mode, cached_table_flags= table_flags(); } reset_statistics(); - internal_tmp_table= test(test_if_locked & HA_OPEN_INTERNAL_TABLE); + internal_tmp_table= MY_TEST(test_if_locked & HA_OPEN_INTERNAL_TABLE); DBUG_RETURN(error); } @@ -3537,7 +3550,7 @@ void handler::print_error(int error, myf errflag) } } else - my_error(ER_GET_ERRNO, errflag, error, table_type()); + my_error(ER_GET_ERRNO, errflag, error, table_type()); DBUG_VOID_RETURN; } } @@ -4153,6 +4166,7 @@ handler::check_if_supported_inplace_alter(TABLE *altered_table, Alter_inplace_info::ALTER_COLUMN_EQUAL_PACK_LENGTH | Alter_inplace_info::ALTER_COLUMN_NAME | Alter_inplace_info::ALTER_COLUMN_DEFAULT | + Alter_inplace_info::ALTER_COLUMN_OPTION | Alter_inplace_info::CHANGE_CREATE_OPTION | Alter_inplace_info::ALTER_RENAME; @@ -4641,14 +4655,16 @@ int ha_create_table(THD *thd, const char *path, error= table.file->ha_create(name, &table, create_info); - (void) closefrm(&table, 0); - if (error) { - my_error(ER_CANT_CREATE_TABLE, MYF(0), db, table_name, error); + if (!thd->is_error()) + my_error(ER_CANT_CREATE_TABLE, MYF(0), db, table_name, error); + table.file->print_error(error, MYF(ME_JUST_WARNING)); PSI_CALL_drop_table_share(temp_table, share.db.str, share.db.length, share.table_name.str, share.table_name.length); } + + (void) closefrm(&table, 0); err: free_table_share(&share); @@ -4819,7 +4835,9 @@ int ha_discover_table(THD *thd, TABLE_SHARE *share) DBUG_ASSERT(share->error == OPEN_FRM_OPEN_ERROR); // share is not OK yet - if (share->db_plugin) + if (!engines_with_discover) + found= FALSE; + else if (share->db_plugin) found= discover_handlerton(thd, share->db_plugin, share); else found= plugin_foreach(thd, discover_handlerton, @@ -4843,6 +4861,7 @@ struct st_discover_existence_args size_t path_len; const char *db, *table_name; handlerton *hton; + bool frm_exists; }; static my_bool discover_existence(THD *thd, plugin_ref plugin, @@ -4851,7 +4870,7 @@ static my_bool discover_existence(THD *thd, plugin_ref plugin, st_discover_existence_args *args= (st_discover_existence_args*)arg; handlerton *ht= plugin_hton(plugin); if (ht->state != SHOW_OPTION_YES || !ht->discover_table_existence) - return FALSE; + return args->frm_exists; args->hton= ht; @@ -4906,40 +4925,36 @@ private: If the 'hton' is not NULL, it's set to the handlerton of the storage engine of this table, or to view_pseudo_hton if the frm belongs to a view. + This function takes discovery correctly into account. If frm is found, + it discovers the table to make sure it really exists in the engine. + If no frm is found it discovers the table, in case it still exists in + the engine. + + While it tries to cut corners (don't open .frm if no discovering engine is + enabled, no full discovery if all discovering engines support + discover_table_existence, etc), it still *may* be quite expensive + and must be used sparingly. @retval true Table exists (even if the error occurred, like bad frm) @retval false Table does not exist (one can do CREATE TABLE table_name) + + @note if frm exists and the table in engine doesn't, *hton will be set, + but the return value will be false. + + @note if frm file exists, but the table cannot be opened (engine not + loaded, frm is invalid), the return value will be true, but + *hton will be NULL. */ bool ha_table_exists(THD *thd, const char *db, const char *table_name, handlerton **hton) { + handlerton *dummy; DBUG_ENTER("ha_table_exists"); if (hton) *hton= 0; - - if (need_full_discover_for_existence) - { - TABLE_LIST table; - uint flags = GTS_TABLE | GTS_VIEW; - - if (!hton) - flags|= GTS_NOLOCK; - - Table_exists_error_handler no_such_table_handler; - thd->push_internal_handler(&no_such_table_handler); - TABLE_SHARE *share= tdc_acquire_share(thd, db, table_name, flags); - thd->pop_internal_handler(); - - if (hton && share) - { - *hton= share->db_type(); - tdc_release_share(share); - } - - // the table doesn't exist if we've caught ER_NO_SUCH_TABLE and nothing else - DBUG_RETURN(!no_such_table_handler.safely_trapped_errors()); - } + else if (engines_with_discover) + hton= &dummy; TABLE_SHARE *share= tdc_lock_share(db, table_name); if (share) @@ -4953,22 +4968,29 @@ bool ha_table_exists(THD *thd, const char *db, const char *table_name, char path[FN_REFLEN + 1]; size_t path_len = build_table_filename(path, sizeof(path) - 1, db, table_name, "", 0); + st_discover_existence_args args= {path, path_len, db, table_name, 0, true}; if (file_ext_exists(path, path_len, reg_ext)) { + bool exists= true; if (hton) { enum legacy_db_type db_type; if (dd_frm_type(thd, path, &db_type) != FRMTYPE_VIEW) - *hton= ha_resolve_by_legacy_type(thd, db_type); + { + handlerton *ht= ha_resolve_by_legacy_type(thd, db_type); + if ((*hton= ht)) + // verify that the table really exists + exists= discover_existence(thd, + plugin_int_to_ref(hton2plugin[ht->slot]), &args); + } else *hton= view_pseudo_hton; } - DBUG_RETURN(TRUE); + DBUG_RETURN(exists); } - st_discover_existence_args args= {path, path_len, db, table_name, 0}; - + args.frm_exists= false; if (plugin_foreach(thd, discover_existence, MYSQL_STORAGE_ENGINE_PLUGIN, &args)) { @@ -4977,6 +4999,30 @@ bool ha_table_exists(THD *thd, const char *db, const char *table_name, DBUG_RETURN(TRUE); } + + if (need_full_discover_for_existence) + { + TABLE_LIST table; + uint flags = GTS_TABLE | GTS_VIEW; + + if (!hton) + flags|= GTS_NOLOCK; + + Table_exists_error_handler no_such_table_handler; + thd->push_internal_handler(&no_such_table_handler); + TABLE_SHARE *share= tdc_acquire_share(thd, db, table_name, flags); + thd->pop_internal_handler(); + + if (hton && share) + { + *hton= share->db_type(); + tdc_release_share(share); + } + + // the table doesn't exist if we've caught ER_NO_SUCH_TABLE and nothing else + DBUG_RETURN(!no_such_table_handler.safely_trapped_errors()); + } + DBUG_RETURN(FALSE); } @@ -5606,8 +5652,10 @@ bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat) "", 0, "DISABLED", 8) ? 1 : 0; } else + { result= db_type->show_status && db_type->show_status(db_type, thd, stat_print, stat) ? 1 : 0; + } } /* @@ -5767,7 +5815,7 @@ static int binlog_log_row(TABLE* table, the first row handled in this statement. In that case, we need to write table maps for all locked tables to the binary log. */ - if (likely(!(error= bitmap_init(&cols, + if (likely(!(error= my_bitmap_init(&cols, use_bitbuf ? bitbuf : NULL, (n_fields + 7) & ~7UL, FALSE)))) @@ -5789,7 +5837,7 @@ static int binlog_log_row(TABLE* table, before_record, after_record); } if (!use_bitbuf) - bitmap_free(&cols); + my_bitmap_free(&cols); } } return error ? HA_ERR_RBR_LOGGING_FAILED : 0; |