more wl#2936 fixes: removed implicit ha_thd() calls (too error-prone),

fixed an assert crash
parent d2384064
...@@ -651,6 +651,7 @@ long long thd_test_options(const MYSQL_THD thd, long long test_options); ...@@ -651,6 +651,7 @@ long long thd_test_options(const MYSQL_THD thd, long long test_options);
int thd_sql_command(const MYSQL_THD thd); int thd_sql_command(const MYSQL_THD thd);
const char *thd_proc_info(MYSQL_THD thd, const char *info); const char *thd_proc_info(MYSQL_THD thd, const char *info);
void **thd_ha_data(const MYSQL_THD thd, const struct handlerton *hton); void **thd_ha_data(const MYSQL_THD thd, const struct handlerton *hton);
int thd_tx_isolation(const MYSQL_THD thd);
char *thd_security_context(MYSQL_THD thd, char *buffer, unsigned int length, char *thd_security_context(MYSQL_THD thd, char *buffer, unsigned int length,
unsigned int max_query_len); unsigned int max_query_len);
......
...@@ -1330,10 +1330,13 @@ sub collect_mysqld_features () { ...@@ -1330,10 +1330,13 @@ sub collect_mysqld_features () {
my $found_variable_list_start= 0; my $found_variable_list_start= 0;
# #
# Execute "mysqld --no-defaults --help --verbose" to get a # Execute "mysqld --help --verbose" to get a list
# of all features and settings # of all features and settings
# #
my $list= `$exe_mysqld --no-defaults --verbose --help`; # --no-defaults and --skip-grant-tables are to avoid loading
# system-wide configs and plugins
#
my $list= `$exe_mysqld --no-defaults --skip-grant-tables --verbose --help`;
foreach my $line (split('\n', $list)) foreach my $line (split('\n', $list))
{ {
......
...@@ -66,10 +66,11 @@ engine = innodb ...@@ -66,10 +66,11 @@ engine = innodb
partition by list (a) partition by list (a)
(partition p0 values in (0)); (partition p0 values in (0));
alter table t1 engine = x; alter table t1 engine = x;
ERROR 42000: Unknown table engine 'x' Warnings:
Warning 1266 Using storage engine MyISAM for table 't1'
show create table t1; show create table t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL `a` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (a) (PARTITION p0 VALUES IN (0) ENGINE = InnoDB) */ ) ENGINE=MyISAM DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (a) (PARTITION p0 VALUES IN (0) ENGINE = MyISAM) */
drop table t1; drop table t1;
...@@ -71,7 +71,6 @@ engine = innodb ...@@ -71,7 +71,6 @@ engine = innodb
partition by list (a) partition by list (a)
(partition p0 values in (0)); (partition p0 values in (0));
--error ER_UNKNOWN_STORAGE_ENGINE
alter table t1 engine = x; alter table t1 engine = x;
show create table t1; show create table t1;
drop table t1; drop table t1;
......
...@@ -1491,19 +1491,9 @@ void handler::ha_statistic_increment(ulong SSV::*offset) const ...@@ -1491,19 +1491,9 @@ void handler::ha_statistic_increment(ulong SSV::*offset) const
statistic_increment(table->in_use->status_var.*offset, &LOCK_status); statistic_increment(table->in_use->status_var.*offset, &LOCK_status);
} }
enum enum_tx_isolation handler::ha_tx_isolation(void) const void **handler::ha_data(THD *thd) const
{ {
return (enum_tx_isolation) ha_thd()->variables.tx_isolation; return (void **) thd->ha_data + ht->slot;
}
uint handler::ha_sql_command(void) const
{
return (uint) ha_thd()->lex->sql_command;
}
void **handler::ha_data(void) const
{
return (void **) ha_thd()->ha_data + ht->slot;
} }
THD *handler::ha_thd(void) const THD *handler::ha_thd(void) const
......
...@@ -898,9 +898,7 @@ class handler :public Sql_alloc ...@@ -898,9 +898,7 @@ class handler :public Sql_alloc
virtual ulonglong table_flags(void) const =0; virtual ulonglong table_flags(void) const =0;
void ha_statistic_increment(ulong SSV::*offset) const; void ha_statistic_increment(ulong SSV::*offset) const;
enum enum_tx_isolation ha_tx_isolation(void) const; void **ha_data(THD *) const;
uint ha_sql_command(void) const;
void **ha_data(void) const;
THD *ha_thd(void) const; THD *ha_thd(void) const;
ha_rows estimation_rows_to_insert; ha_rows estimation_rows_to_insert;
......
...@@ -211,6 +211,12 @@ int thd_sql_command(const THD *thd) ...@@ -211,6 +211,12 @@ int thd_sql_command(const THD *thd)
return (int) thd->lex->sql_command; return (int) thd->lex->sql_command;
} }
extern "C"
int thd_tx_isolation(const THD *thd)
{
return (int) thd->variables.tx_isolation;
}
/* /*
Dumps a text description of a thread, its security context Dumps a text description of a thread, its security context
......
...@@ -1323,6 +1323,13 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv) ...@@ -1323,6 +1323,13 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv)
table= tables.table; table= tables.table;
init_read_record(&read_record_info, new_thd, table, NULL, 1, 0); init_read_record(&read_record_info, new_thd, table, NULL, 1, 0);
table->use_all_columns(); table->use_all_columns();
/*
there're no other threads running yet, so we don't need a mutex.
but plugin_add() before is designed to work in multi-threaded
environment, and it uses safe_mutex_assert_owner(), so we lock
the mutex here to satisfy the assert
*/
pthread_mutex_lock(&LOCK_plugin);
while (!(error= read_record_info.read_record(&read_record_info))) while (!(error= read_record_info.read_record(&read_record_info)))
{ {
DBUG_PRINT("info", ("init plugin record")); DBUG_PRINT("info", ("init plugin record"));
...@@ -1333,11 +1340,12 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv) ...@@ -1333,11 +1340,12 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv)
LEX_STRING name= {(char *)str_name.ptr(), str_name.length()}; LEX_STRING name= {(char *)str_name.ptr(), str_name.length()};
LEX_STRING dl= {(char *)str_dl.ptr(), str_dl.length()}; LEX_STRING dl= {(char *)str_dl.ptr(), str_dl.length()};
free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE));
if (plugin_add(tmp_root, &name, &dl, argc, argv, REPORT_TO_LOG)) if (plugin_add(tmp_root, &name, &dl, argc, argv, REPORT_TO_LOG))
sql_print_warning("Couldn't load plugin named '%s' with soname '%s'.", sql_print_warning("Couldn't load plugin named '%s' with soname '%s'.",
str_name.c_ptr(), str_dl.c_ptr()); str_name.c_ptr(), str_dl.c_ptr());
free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE));
} }
pthread_mutex_unlock(&LOCK_plugin);
if (error > 0) if (error > 0)
sql_print_error(ER(ER_GET_ERRNO), my_errno); sql_print_error(ER(ER_GET_ERRNO), my_errno);
end_read_record(&read_record_info); end_read_record(&read_record_info);
......
...@@ -3220,15 +3220,16 @@ ha_innobase::write_row( ...@@ -3220,15 +3220,16 @@ ha_innobase::write_row(
longlong auto_inc; longlong auto_inc;
longlong dummy; longlong dummy;
ibool auto_inc_used= FALSE; ibool auto_inc_used= FALSE;
THD *thd= ha_thd();
DBUG_ENTER("ha_innobase::write_row"); DBUG_ENTER("ha_innobase::write_row");
if (prebuilt->trx != if (prebuilt->trx !=
*(trx_t**) ha_data()) { *(trx_t**) ha_data(thd)) {
sql_print_error("The transaction object for the table handle is at " sql_print_error("The transaction object for the table handle is at "
"%p, but for the current thread it is at %p", "%p, but for the current thread it is at %p",
prebuilt->trx, prebuilt->trx,
*(trx_t**) ha_data()); *(trx_t**) ha_data(thd));
fputs("InnoDB: Dump of 200 bytes around prebuilt: ", stderr); fputs("InnoDB: Dump of 200 bytes around prebuilt: ", stderr);
ut_print_buf(stderr, ((const byte*)prebuilt) - 100, 200); ut_print_buf(stderr, ((const byte*)prebuilt) - 100, 200);
...@@ -3236,7 +3237,7 @@ ha_innobase::write_row( ...@@ -3236,7 +3237,7 @@ ha_innobase::write_row(
"InnoDB: Dump of 200 bytes around transaction.all: ", "InnoDB: Dump of 200 bytes around transaction.all: ",
stderr); stderr);
ut_print_buf(stderr, ut_print_buf(stderr,
((byte*)(*(trx_t**) ha_data())) - 100, ((byte*)(*(trx_t**) ha_data(thd))) - 100,
200); 200);
putc('\n', stderr); putc('\n', stderr);
ut_error; ut_error;
...@@ -3247,10 +3248,10 @@ ha_innobase::write_row( ...@@ -3247,10 +3248,10 @@ ha_innobase::write_row(
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
table->timestamp_field->set_time(); table->timestamp_field->set_time();
if ((ha_sql_command() == SQLCOM_ALTER_TABLE if ((thd_sql_command(thd) == SQLCOM_ALTER_TABLE
|| ha_sql_command() == SQLCOM_OPTIMIZE || thd_sql_command(thd) == SQLCOM_OPTIMIZE
|| ha_sql_command() == SQLCOM_CREATE_INDEX || thd_sql_command(thd) == SQLCOM_CREATE_INDEX
|| ha_sql_command() == SQLCOM_DROP_INDEX) || thd_sql_command(thd) == SQLCOM_DROP_INDEX)
&& num_write_row >= 10000) { && num_write_row >= 10000) {
/* ALTER TABLE is COMMITted at every 10000 copied rows. /* ALTER TABLE is COMMITted at every 10000 copied rows.
The IX table lock for the original table has to be re-issued. The IX table lock for the original table has to be re-issued.
...@@ -3409,9 +3410,9 @@ no_commit: ...@@ -3409,9 +3410,9 @@ no_commit:
performing those statements. */ performing those statements. */
if (error == DB_DUPLICATE_KEY && auto_inc_used if (error == DB_DUPLICATE_KEY && auto_inc_used
&& (ha_sql_command() == SQLCOM_REPLACE && (thd_sql_command(thd) == SQLCOM_REPLACE
|| ha_sql_command() == SQLCOM_REPLACE_SELECT || thd_sql_command(thd) == SQLCOM_REPLACE_SELECT
|| (ha_sql_command() == SQLCOM_LOAD || (thd_sql_command(thd) == SQLCOM_LOAD
&& prebuilt->trx->allow_duplicates && prebuilt->trx->allow_duplicates
&& prebuilt->trx->replace_duplicates))) { && prebuilt->trx->replace_duplicates))) {
...@@ -3613,7 +3614,7 @@ ha_innobase::update_row( ...@@ -3613,7 +3614,7 @@ ha_innobase::update_row(
DBUG_ENTER("ha_innobase::update_row"); DBUG_ENTER("ha_innobase::update_row");
ut_a(prebuilt->trx == ut_a(prebuilt->trx ==
*(trx_t**) ha_data()); *(trx_t**) ha_data(ha_thd()));
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
table->timestamp_field->set_time(); table->timestamp_field->set_time();
...@@ -3674,7 +3675,7 @@ ha_innobase::delete_row( ...@@ -3674,7 +3675,7 @@ ha_innobase::delete_row(
DBUG_ENTER("ha_innobase::delete_row"); DBUG_ENTER("ha_innobase::delete_row");
ut_a(prebuilt->trx == ut_a(prebuilt->trx ==
*(trx_t**) ha_data()); *(trx_t**) ha_data(ha_thd()));
if (last_query_id != user_thd->query_id) { if (last_query_id != user_thd->query_id) {
prebuilt->sql_stat_start = TRUE; prebuilt->sql_stat_start = TRUE;
...@@ -3772,7 +3773,7 @@ ha_innobase::try_semi_consistent_read(bool yes) ...@@ -3772,7 +3773,7 @@ ha_innobase::try_semi_consistent_read(bool yes)
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
ut_a(prebuilt->trx == ut_a(prebuilt->trx ==
*(trx_t**) ha_data()); *(trx_t**) ha_data(ha_thd()));
/* Row read type is set to semi consistent read if this was /* Row read type is set to semi consistent read if this was
requested by the MySQL and either innodb_locks_unsafe_for_binlog requested by the MySQL and either innodb_locks_unsafe_for_binlog
...@@ -3939,7 +3940,7 @@ ha_innobase::index_read( ...@@ -3939,7 +3940,7 @@ ha_innobase::index_read(
DBUG_ENTER("index_read"); DBUG_ENTER("index_read");
ut_a(prebuilt->trx == ut_a(prebuilt->trx ==
*(trx_t**) ha_data()); *(trx_t**) ha_data(ha_thd()));
ha_statistic_increment(&SSV::ha_read_key_count); ha_statistic_increment(&SSV::ha_read_key_count);
...@@ -4052,7 +4053,7 @@ ha_innobase::change_active_index( ...@@ -4052,7 +4053,7 @@ ha_innobase::change_active_index(
ut_ad(user_thd == current_thd); ut_ad(user_thd == current_thd);
ut_a(prebuilt->trx == ut_a(prebuilt->trx ==
*(trx_t**) ha_data()); *(trx_t**) ha_data(ha_thd()));
active_index = keynr; active_index = keynr;
...@@ -4142,7 +4143,7 @@ ha_innobase::general_fetch( ...@@ -4142,7 +4143,7 @@ ha_innobase::general_fetch(
DBUG_ENTER("general_fetch"); DBUG_ENTER("general_fetch");
ut_a(prebuilt->trx == ut_a(prebuilt->trx ==
*(trx_t**) ha_data()); *(trx_t**) ha_data(ha_thd()));
innodb_srv_conc_enter_innodb(prebuilt->trx); innodb_srv_conc_enter_innodb(prebuilt->trx);
...@@ -4371,7 +4372,7 @@ ha_innobase::rnd_pos( ...@@ -4371,7 +4372,7 @@ ha_innobase::rnd_pos(
ha_statistic_increment(&SSV::ha_read_rnd_count); ha_statistic_increment(&SSV::ha_read_rnd_count);
ut_a(prebuilt->trx == ut_a(prebuilt->trx ==
*(trx_t**) ha_data()); *(trx_t**) ha_data(ha_thd()));
if (prebuilt->clust_index_was_generated) { if (prebuilt->clust_index_was_generated) {
/* No primary key was defined for the table and we /* No primary key was defined for the table and we
...@@ -4421,7 +4422,7 @@ ha_innobase::position( ...@@ -4421,7 +4422,7 @@ ha_innobase::position(
uint len; uint len;
ut_a(prebuilt->trx == ut_a(prebuilt->trx ==
*(trx_t**) ha_data()); *(trx_t**) ha_data(ha_thd()));
if (prebuilt->clust_index_was_generated) { if (prebuilt->clust_index_was_generated) {
/* No primary key was defined for the table and we /* No primary key was defined for the table and we
...@@ -4921,7 +4922,7 @@ ha_innobase::discard_or_import_tablespace( ...@@ -4921,7 +4922,7 @@ ha_innobase::discard_or_import_tablespace(
ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N); ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N);
ut_a(prebuilt->trx == ut_a(prebuilt->trx ==
*(trx_t**) ha_data()); *(trx_t**) ha_data(ha_thd()));
dict_table = prebuilt->table; dict_table = prebuilt->table;
trx = prebuilt->trx; trx = prebuilt->trx;
...@@ -4956,7 +4957,7 @@ ha_innobase::delete_all_rows(void) ...@@ -4956,7 +4957,7 @@ ha_innobase::delete_all_rows(void)
update_thd(thd); update_thd(thd);
if (ha_sql_command() == SQLCOM_TRUNCATE) { if (thd_sql_command(thd) == SQLCOM_TRUNCATE) {
/* Truncate the table in InnoDB */ /* Truncate the table in InnoDB */
error = row_truncate_table_for_mysql(prebuilt->table, prebuilt->trx); error = row_truncate_table_for_mysql(prebuilt->table, prebuilt->trx);
...@@ -5250,7 +5251,7 @@ ha_innobase::records_in_range( ...@@ -5250,7 +5251,7 @@ ha_innobase::records_in_range(
DBUG_ENTER("records_in_range"); DBUG_ENTER("records_in_range");
ut_a(prebuilt->trx == ut_a(prebuilt->trx ==
*(trx_t**) ha_data()); *(trx_t**) ha_data(ha_thd()));
prebuilt->trx->op_info = (char*)"estimating records in index range"; prebuilt->trx->op_info = (char*)"estimating records in index range";
...@@ -5686,7 +5687,7 @@ ha_innobase::check( ...@@ -5686,7 +5687,7 @@ ha_innobase::check(
ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N); ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N);
ut_a(prebuilt->trx == ut_a(prebuilt->trx ==
*(trx_t**) ha_data()); *(trx_t**) ha_data(ha_thd()));
if (prebuilt->mysql_template == NULL) { if (prebuilt->mysql_template == NULL) {
/* Build the template; we will use a dummy template /* Build the template; we will use a dummy template
...@@ -5988,7 +5989,7 @@ ha_innobase::can_switch_engines(void) ...@@ -5988,7 +5989,7 @@ ha_innobase::can_switch_engines(void)
DBUG_ENTER("ha_innobase::can_switch_engines"); DBUG_ENTER("ha_innobase::can_switch_engines");
ut_a(prebuilt->trx == ut_a(prebuilt->trx ==
*(trx_t**) ha_data()); *(trx_t**) ha_data(ha_thd()));
prebuilt->trx->op_info = prebuilt->trx->op_info =
"determining if there are foreign key constraints"; "determining if there are foreign key constraints";
...@@ -6154,7 +6155,7 @@ ha_innobase::start_stmt( ...@@ -6154,7 +6155,7 @@ ha_innobase::start_stmt(
prebuilt->select_lock_type = LOCK_X; prebuilt->select_lock_type = LOCK_X;
} else { } else {
if (trx->isolation_level != TRX_ISO_SERIALIZABLE if (trx->isolation_level != TRX_ISO_SERIALIZABLE
&& ha_sql_command() == SQLCOM_SELECT && thd_sql_command(thd) == SQLCOM_SELECT
&& lock_type == TL_READ) { && lock_type == TL_READ) {
/* For other than temporary tables, we obtain /* For other than temporary tables, we obtain
...@@ -6296,7 +6297,7 @@ ha_innobase::external_lock( ...@@ -6296,7 +6297,7 @@ ha_innobase::external_lock(
if (prebuilt->select_lock_type != LOCK_NONE) { if (prebuilt->select_lock_type != LOCK_NONE) {
if (thd_in_lock_tables(thd) && if (thd_in_lock_tables(thd) &&
ha_sql_command() == SQLCOM_LOCK_TABLES && thd_sql_command(thd) == SQLCOM_LOCK_TABLES &&
THDVAR(thd, table_locks) && THDVAR(thd, table_locks) &&
thd_test_options(thd, OPTION_NOT_AUTOCOMMIT)) { thd_test_options(thd, OPTION_NOT_AUTOCOMMIT)) {
...@@ -6768,12 +6769,12 @@ ha_innobase::store_lock( ...@@ -6768,12 +6769,12 @@ ha_innobase::store_lock(
if (lock_type != TL_IGNORE if (lock_type != TL_IGNORE
&& trx->n_mysql_tables_in_use == 0) { && trx->n_mysql_tables_in_use == 0) {
trx->isolation_level = innobase_map_isolation_level( trx->isolation_level = innobase_map_isolation_level(
ha_tx_isolation()); (enum_tx_isolation)thd_tx_isolation(thd));
} }
DBUG_ASSERT(thd == current_thd); DBUG_ASSERT(thd == current_thd);
const bool in_lock_tables = thd_in_lock_tables(thd); const bool in_lock_tables = thd_in_lock_tables(thd);
const uint sql_command = ha_sql_command(); const uint sql_command = thd_sql_command(thd);
if (sql_command == SQLCOM_DROP_TABLE) { if (sql_command == SQLCOM_DROP_TABLE) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment