From 5babac539d03b4bb9aff2f74965b98c8506726e5 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Jul 2007 11:31:10 +0300 Subject: Bug #29571: INSERT DELAYED IGNORE written to binary log on the master but on the slave MySQL can decide to "downgrade" a INSERT DELAYED statement to normal insert in certain situations. One such situation is when the slave is replaying a replication feed. However INSERT DELAYED is logged even if there're no updates whereas the NORMAL INSERT is not logged in such cases. Fixed by always logging a "downgraded" INSERT DELAYED: even if there were no updates. mysql-test/r/rpl_insert_delayed.result: Bug #29571: test case mysql-test/t/rpl_insert_delayed.test: Bug #29571: test case sql/sql_insert.cc: Bug #29571: log INSERT DELAYED even if it was "downgraded" to INSERT (and there were no updates) --- sql/sql_insert.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 73f8c5e4418..618ba62ef19 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -560,6 +560,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, int error, res; bool transactional_table, joins_freed= FALSE; bool changed; + bool was_insert_delayed= (table_list->lock_type == TL_WRITE_DELAYED); uint value_count; ulong counter = 1; ulonglong id; @@ -859,14 +860,16 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, transactional_table= table->file->has_transactions(); - if ((changed= (info.copied || info.deleted || info.updated))) + if ((changed= (info.copied || info.deleted || info.updated)) || + was_insert_delayed) { /* Invalidate the table in the query cache if something changed. For the transactional algorithm to work the invalidation must be before binlog writing and ha_autocommit_or_rollback */ - query_cache_invalidate3(thd, table_list, 1); + if (changed) + query_cache_invalidate3(thd, table_list, 1); if (error <= 0 || !transactional_table) { if (mysql_bin_log.is_open()) @@ -904,7 +907,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, if (mysql_bin_log.write(&qinfo) && transactional_table) error=1; } - if (!transactional_table) + if (!transactional_table && changed) thd->no_trans_update.all= TRUE; } } -- cgit v1.2.1 From c7150fd814603bb12a686ea0857296b92282de1b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Jul 2007 18:33:05 +0300 Subject: Bug #30036: SHOW TABLE TYPES causes the debug client to crash SHOW TABLE TYPES is a (to be deprecated) synonym for SHOW STORAGE ENGINES. Fixed to use the right schema table in addition to issuing a warning. mysql-test/r/show_check.result: Bug #30036: test case mysql-test/t/show_check.test: Bug #30036: test case sql/sql_yacc.yy: Bug #30036: use the right schema table --- sql/sql_yacc.yy | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sql') diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index d9a808bf8f7..468c3305c57 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -8729,6 +8729,8 @@ show_param: LEX *lex=Lex; lex->sql_command= SQLCOM_SHOW_STORAGE_ENGINES; WARN_DEPRECATED(yythd, "5.2", "SHOW TABLE TYPES", "'SHOW [STORAGE] ENGINES'"); + if (prepare_schema_table(YYTHD, lex, 0, SCH_ENGINES)) + MYSQL_YYABORT; } | opt_storage ENGINES_SYM { -- cgit v1.2.1 From 9206f6847742a208500da660a2e76306e3fadae3 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Jul 2007 20:52:53 +0400 Subject: BUG#28591: make the fix work for BDB tables too: - make ha_berkeley::cmp_ref() take into account that auto-generated PKs are stored in LSB-first order. - Remove the temporary code that made the bugfix work for innodb only mysql-test/r/bdb.result: Adjust test-results. sql/ha_berkeley.cc: BUG#28591: make the fix work for BDB tables too: - make ha_berkeley::cmp_ref() take into account that auto-generated PKs are stored in LSB-first order. sql/sql_select.cc: BUG#28591: Remove "innodb only" clause as the fix now works for BDB too sql/table.cc: BUG#28591: Remove "innodb only" clause as the fix now works for BDB too --- sql/ha_berkeley.cc | 6 +++++- sql/sql_select.cc | 1 - sql/table.cc | 3 +-- 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'sql') diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index 2a5fe775ca6..fbfd5031656 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -2646,7 +2646,11 @@ ha_rows ha_berkeley::estimate_rows_upper_bound() int ha_berkeley::cmp_ref(const byte *ref1, const byte *ref2) { if (hidden_primary_key) - return memcmp(ref1, ref2, BDB_HIDDEN_PRIMARY_KEY_LENGTH); + { + ulonglong a=uint5korr((char*) ref1); + ulonglong b=uint5korr((char*) ref2); + return a < b ? -1 : (a > b ? 1 : 0); + } int result; Field *field; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 2d9d261bb31..d82a0fdcf41 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -12033,7 +12033,6 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx, */ if (!on_primary_key && (table->file->table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) && - table->s->db_type == DB_TYPE_INNODB && table->s->primary_key != MAX_KEY) { on_primary_key= TRUE; diff --git a/sql/table.cc b/sql/table.cc index ce894e6910f..18a395d69af 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -782,8 +782,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX) { field->part_of_key= share->keys_in_use; - if (share->db_type == DB_TYPE_INNODB && - field->part_of_sortkey.is_set(key)) + if (field->part_of_sortkey.is_set(key)) field->part_of_sortkey= share->keys_in_use; } } -- cgit v1.2.1 From d27bf14ed7aab39b8b83d0eed34cb3ba4417de35 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 27 Jul 2007 18:42:25 +0500 Subject: Bug #29878 Garbage data generation when executing SESSION_USER() on a slave. Item_func_user doesn't calculate anything in it's val_str() method, just returns saved str_value. Though Item::save_in_field method can destroy str_value, relying on val_str() return. As a result we get the garbage stored in field. We cannot use Item::save_in_field implementation for Item_func_user, reimplement it in simpler way. mysql-test/r/rpl_session_var.result: Bug #29878 Garbage data generation when executing SESSION_USER() on a slave. test result mysql-test/t/rpl_session_var.test: Bug #29878 Garbage data generation when executing SESSION_USER() on a slave. test case sql/item.cc: Bug #29878 Garbage data generation when executing SESSION_USER() on a slave. duplicating code moved to Item::save_str_in_field sql/item.h: Bug #29878 Garbage data generation when executing SESSION_USER() on a slave. duplicating code moved to Item::save_str_in_field sql/item_strfunc.h: Bug #29878 Garbage data generation when executing SESSION_USER() on a slave. Item_func_user::save_in_field implemented as simple storing str_value --- sql/item.cc | 52 ++++++++++++++++++++++++++++++++++++++-------------- sql/item.h | 6 +++++- sql/item_strfunc.h | 4 ++++ 3 files changed, 47 insertions(+), 15 deletions(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index 2fc58eebe75..bd47fb706a6 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -336,6 +336,37 @@ int Item::save_date_in_field(Field *field) } +/* + Store the string value in field directly + + SYNOPSIS + Item::save_str_value_in_field() + field a pointer to field where to store + result the pointer to the string value to be stored + + DESCRIPTION + The method is used by Item_*::save_in_field implementations + when we don't need to calculate the value to store + See Item_string::save_in_field() implementation for example + + IMPLEMENTATION + Check if the Item is null and stores the NULL or the + result value in the field accordingly. + + RETURN + Nonzero value if error +*/ + +int Item::save_str_value_in_field(Field *field, String *result) +{ + if (null_value) + return set_field_to_null(field); + field->set_notnull(); + return field->store(result->ptr(), result->length(), + collation.collation); +} + + Item::Item(): rsize(0), name(0), orig_name(0), name_length(0), fixed(0), is_autogenerated_name(TRUE), @@ -3009,16 +3040,6 @@ my_decimal *Item_copy_string::val_decimal(my_decimal *decimal_value) } - -int Item_copy_string::save_in_field(Field *field, bool no_conversions) -{ - if (null_value) - return set_field_to_null(field); - field->set_notnull(); - return field->store(str_value.ptr(),str_value.length(), - collation.collation); -} - /* Functions to convert item to field (for send_fields) */ @@ -4417,6 +4438,12 @@ int Item_null::save_safe_in_field(Field *field) } +/* + This implementation can lose str_value content, so if the + Item uses str_value to store something, it should + reimplement it's ::save_in_field() as Item_string, for example, does +*/ + int Item::save_in_field(Field *field, bool no_conversions) { int error; @@ -4474,10 +4501,7 @@ int Item_string::save_in_field(Field *field, bool no_conversions) { String *result; result=val_str(&str_value); - if (null_value) - return set_field_to_null(field); - field->set_notnull(); - return field->store(result->ptr(),result->length(),collation.collation); + return save_str_value_in_field(field, result); } diff --git a/sql/item.h b/sql/item.h index 5b1a80a5f03..72236cb5e63 100644 --- a/sql/item.h +++ b/sql/item.h @@ -612,6 +612,7 @@ public: int save_time_in_field(Field *field); int save_date_in_field(Field *field); + int save_str_value_in_field(Field *field, String *result); virtual Field *get_tmp_table_field() { return 0; } /* This is also used to create fields in CREATE ... SELECT: */ @@ -2166,7 +2167,10 @@ public: my_decimal *val_decimal(my_decimal *); void make_field(Send_field *field) { item->make_field(field); } void copy(); - int save_in_field(Field *field, bool no_conversions); + int save_in_field(Field *field, bool no_conversions) + { + return save_str_value_in_field(field, &str_value); + } table_map used_tables() const { return (table_map) 1L; } bool const_item() const { return 0; } bool is_null() { return null_value; } diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index d7c4a3eddef..6ca0b89a22b 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -434,6 +434,10 @@ public: } const char *func_name() const { return "user"; } const char *fully_qualified_func_name() const { return "user()"; } + int save_in_field(Field *field, bool no_conversions) + { + return save_str_value_in_field(field, &str_value); + } }; -- cgit v1.2.1 From 82c87c0a44d17ff2ae723c1ac38ad103bf6949f5 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 27 Jul 2007 17:55:39 +0300 Subject: Bug #30000: SHOW commands once again ends up in the slow query log Disable the SHOW commands to appear in the show query log. Update the commands type array. mysql-test/r/show_check.result: Bug #30000: test case mysql-test/t/show_check.test: Bug #30000: test case sql/sql_parse.cc: Bug #30000: skip SHOW commands from the slow query log. --- sql/sql_parse.cc | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) (limited to 'sql') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 93887db88e1..63971609794 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -223,7 +223,6 @@ void init_update_queries(void) sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT; sql_command_flags[SQLCOM_SHOW_STATUS_PROC]= CF_STATUS_COMMAND; - sql_command_flags[SQLCOM_SHOW_STATUS_FUNC]= CF_STATUS_COMMAND; sql_command_flags[SQLCOM_SHOW_STATUS]= CF_STATUS_COMMAND; sql_command_flags[SQLCOM_SHOW_DATABASES]= CF_STATUS_COMMAND; sql_command_flags[SQLCOM_SHOW_TRIGGERS]= CF_STATUS_COMMAND; @@ -235,10 +234,36 @@ void init_update_queries(void) sql_command_flags[SQLCOM_SHOW_VARIABLES]= CF_STATUS_COMMAND; sql_command_flags[SQLCOM_SHOW_CHARSETS]= CF_STATUS_COMMAND; sql_command_flags[SQLCOM_SHOW_COLLATIONS]= CF_STATUS_COMMAND; - sql_command_flags[SQLCOM_SHOW_STATUS_PROC]= CF_STATUS_COMMAND; - - sql_command_flags[SQLCOM_SHOW_TABLES]= (CF_STATUS_COMMAND | - CF_SHOW_TABLE_COMMAND); + sql_command_flags[SQLCOM_SHOW_NEW_MASTER]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_BINLOGS]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_SLAVE_HOSTS]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_BINLOG_EVENTS]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_COLUMN_TYPES]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_STORAGE_ENGINES]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_AUTHORS]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_CONTRIBUTORS]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_PRIVILEGES]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_WARNS]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_ERRORS]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_ENGINE_STATUS]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_ENGINE_MUTEX]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_ENGINE_LOGS]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_PROCESSLIST]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_GRANTS]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_CREATE_DB]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_CREATE]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_MASTER_STAT]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_SLAVE_STAT]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_CREATE_PROC]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_CREATE_FUNC]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_CREATE_TRIGGER]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_STATUS_FUNC]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_PROC_CODE]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_FUNC_CODE]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_CREATE_EVENT]= CF_STATUS_COMMAND; + + sql_command_flags[SQLCOM_SHOW_TABLES]= (CF_STATUS_COMMAND | + CF_SHOW_TABLE_COMMAND); sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]= (CF_STATUS_COMMAND | CF_SHOW_TABLE_COMMAND); @@ -1323,7 +1348,8 @@ void log_slow_statement(THD *thd) thd->variables.long_query_time || ((thd->server_status & (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) && - opt_log_queries_not_using_indexes)) + opt_log_queries_not_using_indexes && + !(sql_command_flags[thd->lex->sql_command] & CF_STATUS_COMMAND))) { thd->status_var.long_query_count++; slow_log_print(thd, thd->query, thd->query_length, start_of_query); -- cgit v1.2.1