summaryrefslogtreecommitdiff
path: root/sql/handler.cc
diff options
context:
space:
mode:
authorNirbhay Choubey <nirbhay@skysql.com>2014-03-26 14:27:24 -0400
committerNirbhay Choubey <nirbhay@skysql.com>2014-03-26 14:27:24 -0400
commit90e4f7f9d3f2669ac99f2817f884315bfc86b0a7 (patch)
tree60a10a515a9f5656e797d8142f97b94f89f4e797 /sql/handler.cc
parent586fab72f01e1c7f0f8bf363fa6b06a2f10965b4 (diff)
parent5b7cab82195268f7657504d0b53995654748cefa (diff)
downloadmariadb-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.cc144
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;