From 151b8ec4d11abbb3bf1fb55e10df3e3e7449fe1c Mon Sep 17 00:00:00 2001 From: Venkatesh Duggirala Date: Fri, 13 Mar 2015 12:32:44 +0530 Subject: Bug #20439913 CREATE TABLE DB.TABLE LIKE TMPTABLE IS BINLOGGED INCORRECTLY - BREAKS A SLAVE Analysis: In row based replication, Master does not send temp table information to Slave. If there are any DDLs that involves in regular table that needs to be sent to Slave and a temp tables (which will not be available at Slave), the Master rewrites the query replacing temp table with it's defintion. Eg: create table regular_table like temptable. In rewrite logic, server is ignoring the database of regular table which can cause problems mentioned in this bug. Fix: dont ignore database information (if available) while rewriting the query --- sql/sql_table.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sql/sql_table.cc') diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 096e3d6be0f..b0547a16050 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4720,7 +4720,8 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, int result __attribute__((unused))= store_create_info(thd, table, &query, - create_info, FALSE /* show_database */); + create_info, + table->db ? TRUE : FALSE/* show_database */); DBUG_ASSERT(result == 0); // store_create_info() always return 0 if (write_bin_log(thd, TRUE, query.ptr(), query.length())) -- cgit v1.2.1 From 59142d9a279339f766a23e35a0f7b183406e43c0 Mon Sep 17 00:00:00 2001 From: Venkatesh Duggirala Date: Fri, 13 Mar 2015 13:13:48 +0530 Subject: Bug #20439913 CREATE TABLE DB.TABLE LIKE TMPTABLE IS BINLOGGED INCORRECTLY - BREAKS A SLAVE Submitted a incomplete patch with my previous push, re submitting the extra changes the required to make the patch complete. --- sql/sql_table.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'sql/sql_table.cc') diff --git a/sql/sql_table.cc b/sql/sql_table.cc index b0547a16050..b8858cffce6 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4720,8 +4720,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, int result __attribute__((unused))= store_create_info(thd, table, &query, - create_info, - table->db ? TRUE : FALSE/* show_database */); + create_info, TRUE /* show_database */); DBUG_ASSERT(result == 0); // store_create_info() always return 0 if (write_bin_log(thd, TRUE, query.ptr(), query.length())) -- cgit v1.2.1 From 196528eb42c843ca800b81be27a79c7c4806a057 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Sun, 14 Jun 2015 18:54:13 +0500 Subject: MDEV-8212 alter table - failing to ADD PRIMARY KEY IF NOT EXISTS when existing index of same as column name. The default name for the primary key is rather 'PRIMARY' instead of the indexed column name. --- sql/sql_table.cc | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'sql/sql_table.cc') diff --git a/sql/sql_table.cc b/sql/sql_table.cc index da2a220d3f1..6ee0e9bc871 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -5859,12 +5859,17 @@ drop_create_field: /* let us check the name of the first key part. */ if ((keyname= key->name.str) == NULL) { - List_iterator part_it(key->columns); - Key_part_spec *kp; - if ((kp= part_it++)) - keyname= kp->field_name.str; - if (keyname == NULL) - continue; + if (key->type == Key::PRIMARY) + keyname= primary_key_name; + else + { + List_iterator part_it(key->columns); + Key_part_spec *kp; + if ((kp= part_it++)) + keyname= kp->field_name.str; + if (keyname == NULL) + continue; + } } if (key->type != Key::FOREIGN_KEY) { -- cgit v1.2.1 From 909f7607018e644754a2c41b791b44b25a05e8fb Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Mon, 15 Jun 2015 15:37:14 +0400 Subject: MDEV-5309 - RENAME TABLE does not check for existence of the table's engine When RENAME TABLE is executed, it apparently does not check whether the engine is available (unlike ALTER TABLE .. RENAME, which does). It means that if the engine in question was not loaded on some reason, the table might become unusable, since the engine won't know about the change. With this patch RENAME TABLE fails if storage engine is not available. --- sql/sql_table.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sql/sql_table.cc') diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 6ee0e9bc871..c31a6fd6474 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -5149,6 +5149,7 @@ mysql_rename_table(handlerton *base, const char *old_db, ulonglong save_bits= thd->variables.option_bits; int length; DBUG_ENTER("mysql_rename_table"); + DBUG_ASSERT(base); DBUG_PRINT("enter", ("old: '%s'.'%s' new: '%s'.'%s'", old_db, old_name, new_db, new_name)); @@ -5156,8 +5157,7 @@ mysql_rename_table(handlerton *base, const char *old_db, if (flags & NO_FK_CHECKS) thd->variables.option_bits|= OPTION_NO_FOREIGN_KEY_CHECKS; - file= (base == NULL ? 0 : - get_new_handler((TABLE_SHARE*) 0, thd->mem_root, base)); + file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root, base); build_table_filename(from, sizeof(from) - 1, old_db, old_name, "", flags & FN_FROM_IS_TMP); -- cgit v1.2.1 From 985e430c0f1c99cbd0854aae649f8aefff98adc0 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 16 Jun 2015 23:55:56 +0200 Subject: after-merge fixes in innobase: compilation error on windows other changes: perfschema merge followup --- sql/sql_table.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'sql/sql_table.cc') diff --git a/sql/sql_table.cc b/sql/sql_table.cc index c31a6fd6474..3a7930f6963 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1672,6 +1672,7 @@ void execute_ddl_log_recovery() (void) mysql_file_delete(key_file_global_ddl_log, file_name, MYF(0)); global_ddl_log.recovery_phase= FALSE; mysql_mutex_unlock(&LOCK_gdl); + thd->reset_query(); delete thd; /* Remember that we don't have a THD */ set_current_thd(0); -- cgit v1.2.1 From b56ad494b47c19fef98101c224ed764664691b72 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 16 Jun 2015 17:27:53 +0200 Subject: MDEV-8287 DROP TABLE suppresses all engine errors in ha_delete_table() * only convert ENOENT and HA_ERR_NO_SUCH_TABLE to warnings * only return real error codes (that is, not ENOENT and not HA_ERR_NO_SUCH_TABLE) * intercept HA_ERR_ROW_IS_REFERENCED to generate backward compatible ER_ROW_IS_REFERENCED in mysql_rm_table_no_locks() * no special code to handle HA_ERR_ROW_IS_REFERENCED * no special code to handle ENOENT and HA_ERR_NO_SUCH_TABLE * return multi-table error ER_BAD_TABLE_ERROR only when there were many errors, not when there were many tables to drop (but only one table generated an error) --- sql/sql_table.cc | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) (limited to 'sql/sql_table.cc') diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 3a7930f6963..20cfccaa3d9 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2201,15 +2201,13 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, char path[FN_REFLEN + 1], wrong_tables_buff[160], *alias= NULL; String wrong_tables(wrong_tables_buff, sizeof(wrong_tables_buff)-1, system_charset_info); - uint path_length= 0; + uint path_length= 0, errors= 0; int error= 0; int non_temp_tables_count= 0; - bool foreign_key_error=0; bool non_tmp_error= 0; bool trans_tmp_table_deleted= 0, non_trans_tmp_table_deleted= 0; bool non_tmp_table_deleted= 0; bool is_drop_tmp_if_exists_added= 0; - bool one_table= tables->next_local == 0; bool was_view= 0; String built_query; String built_trans_tmp_query, built_non_trans_tmp_query; @@ -2495,12 +2493,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, error= ha_delete_table(thd, table_type, path, db, table->table_name, !dont_log_query); - if (error == HA_ERR_ROW_IS_REFERENCED) - { - /* the table is referenced by a foreign key constraint */ - foreign_key_error= 1; - } - if (!error || error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) + if (!error) { int frm_delete_error, trigger_drop_error= 0; /* Delete the table definition file */ @@ -2518,11 +2511,8 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, if (trigger_drop_error || (frm_delete_error && frm_delete_error != ENOENT)) error= 1; - else if (!frm_delete_error || !error || if_exists) - { - error= 0; + else if (frm_delete_error && if_exists) thd->clear_error(); - } } non_tmp_error= error ? TRUE : non_tmp_error; } @@ -2533,6 +2523,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, wrong_tables.append(db); wrong_tables.append('.'); wrong_tables.append(table->table_name); + errors++; } else { @@ -2556,14 +2547,13 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, err: if (wrong_tables.length()) { - if (one_table && was_view) + DBUG_ASSERT(errors); + if (errors == 1 && was_view) my_printf_error(ER_IT_IS_A_VIEW, ER(ER_IT_IS_A_VIEW), MYF(0), wrong_tables.c_ptr_safe()); - else if (!foreign_key_error) + else if (errors > 1 || !thd->is_error()) my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0), wrong_tables.c_ptr_safe()); - else - my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0)); error= 1; } @@ -2614,8 +2604,8 @@ err: /* Chop of the last comma */ built_query.chop(); built_query.append(" /* generated by server */"); - int error_code = (non_tmp_error ? - (foreign_key_error ? ER_ROW_IS_REFERENCED : ER_BAD_TABLE_ERROR) : 0); + int error_code = non_tmp_error ? thd->get_stmt_da()->sql_errno() + : 0; error |= thd->binlog_query(THD::STMT_QUERY_TYPE, built_query.ptr(), built_query.length(), -- cgit v1.2.1