diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/ha_partition.cc | 30 | ||||
-rw-r--r-- | sql/ha_partition.h | 22 | ||||
-rw-r--r-- | sql/handler.cc | 2 | ||||
-rw-r--r-- | sql/item.cc | 23 | ||||
-rw-r--r-- | sql/item.h | 2 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 2 | ||||
-rw-r--r-- | sql/item_subselect.cc | 1 | ||||
-rw-r--r-- | sql/log.cc | 2 | ||||
-rw-r--r-- | sql/log_event.cc | 25 | ||||
-rw-r--r-- | sql/mysql_priv.h | 2 | ||||
-rw-r--r-- | sql/mysqld.cc | 20 | ||||
-rw-r--r-- | sql/rpl_rli.h | 7 | ||||
-rw-r--r-- | sql/signal_handler.cc | 1 | ||||
-rw-r--r-- | sql/slave.cc | 98 | ||||
-rw-r--r-- | sql/sp_head.cc | 2 | ||||
-rw-r--r-- | sql/spatial.cc | 3 | ||||
-rw-r--r-- | sql/sql_parse.cc | 5 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 6 | ||||
-rw-r--r-- | sql/sql_select.cc | 11 | ||||
-rw-r--r-- | sql/sql_show.cc | 5 |
20 files changed, 192 insertions, 77 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 542af265f52..299170d1ff4 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, 2011, Oracle and/or its affiliates. + Copyright (c) 2005, 2012, Oracle and/or its affiliates. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -6540,20 +6540,20 @@ int ha_partition::add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys) return ret; err: if (file > m_file) - {
- uint *key_numbers= (uint*) ha_thd()->alloc(sizeof(uint) * num_of_keys);
- KEY *old_key_info= table_arg->key_info;
- uint i;
- /* Use the newly added key_info as table->key_info to remove them. */
- for (i= 0; i < num_of_keys; i++)
- key_numbers[i]= i;
- table_arg->key_info= key_info;
- while (--file >= m_file)
- {
- (void) (*file)->prepare_drop_index(table_arg, key_numbers, num_of_keys);
- (void) (*file)->final_drop_index(table_arg);
- }
- table_arg->key_info= old_key_info;
+ { + uint *key_numbers= (uint*) ha_thd()->alloc(sizeof(uint) * num_of_keys); + KEY *old_key_info= table_arg->key_info; + uint i; + /* Use the newly added key_info as table->key_info to remove them. */ + for (i= 0; i < num_of_keys; i++) + key_numbers[i]= i; + table_arg->key_info= key_info; + while (--file >= m_file) + { + (void) (*file)->prepare_drop_index(table_arg, key_numbers, num_of_keys); + (void) (*file)->final_drop_index(table_arg); + } + table_arg->key_info= old_key_info; } return ret; } diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 59449ef9634..b1e38e0421d 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, 2011, Oracle and/or its affiliates. + Copyright (c) 2005, 2012, Oracle and/or its affiliates. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -220,9 +220,9 @@ public: */ ha_partition(handlerton *hton, TABLE_SHARE * table); ha_partition(handlerton *hton, partition_info * part_info); - ha_partition(handlerton *hton, TABLE_SHARE *share,
- partition_info *part_info_arg,
- ha_partition *clone_arg,
+ ha_partition(handlerton *hton, TABLE_SHARE *share, + partition_info *part_info_arg, + ha_partition *clone_arg, MEM_ROOT *clone_mem_root_arg); ~ha_partition(); /* @@ -552,6 +552,20 @@ public: virtual int extra(enum ha_extra_function operation); virtual int extra_opt(enum ha_extra_function operation, ulong cachesize); virtual int reset(void); + /* + Do not allow caching of partitioned tables, since we cannot return + a callback or engine_data that would work for a generic engine. + */ + virtual my_bool register_query_cache_table(THD *thd, char *table_key, + uint key_length, + qc_engine_callback + *engine_callback, + ulonglong *engine_data) + { + *engine_callback= NULL; + *engine_data= 0; + return FALSE; + } private: static const uint NO_CURRENT_PART_ID; diff --git a/sql/handler.cc b/sql/handler.cc index 1f6a3b9f665..135757597fc 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -343,6 +343,7 @@ int ha_init_errors(void) SETMSG(HA_ERR_AUTOINC_READ_FAILED, ER(ER_AUTOINC_READ_FAILED)); SETMSG(HA_ERR_AUTOINC_ERANGE, ER(ER_WARN_DATA_OUT_OF_RANGE)); SETMSG(HA_ERR_TOO_MANY_CONCURRENT_TRXS, ER(ER_TOO_MANY_CONCURRENT_TRXS)); + SETMSG(HA_ERR_TABLE_IN_FK_CHECK, "Table being used in foreign key check"); /* Register the error messages for use with my_error(). */ return my_error_register(errmsgs, HA_ERR_FIRST, HA_ERR_LAST); @@ -2889,6 +2890,7 @@ void handler::print_error(int error, myf errflag) case HA_ERR_TOO_MANY_CONCURRENT_TRXS: textno= ER_TOO_MANY_CONCURRENT_TRXS; break; + case HA_ERR_TABLE_IN_FK_CHECK: default: { /* The error was "unknown" to this function. diff --git a/sql/item.cc b/sql/item.cc index 4bcad8a72bc..71b7a68c258 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -3118,7 +3118,7 @@ String *Item_param::val_str(String* str) that binary log contains wrong statement */ -const String *Item_param::query_val_str(String* str) const +const String *Item_param::query_val_str(THD *thd, String* str) const { switch (state) { case INT_VALUE: @@ -3156,7 +3156,8 @@ const String *Item_param::query_val_str(String* str) const case LONG_DATA_VALUE: { str->length(0); - append_query_string(value.cs_info.character_set_client, &str_value, str); + append_query_string(thd, value.cs_info.character_set_client, &str_value, + str); break; } case NULL_VALUE: @@ -3289,7 +3290,7 @@ void Item_param::print(String *str, enum_query_type query_type) char buffer[STRING_BUFFER_USUAL_SIZE]; String tmp(buffer, sizeof(buffer), &my_charset_bin); const String *res; - res= query_val_str(&tmp); + res= query_val_str(current_thd, &tmp); str->append(*res); } } @@ -6727,20 +6728,12 @@ bool Item_insert_value::fix_fields(THD *thd, Item **items) } if (arg->type() == REF_ITEM) + arg= static_cast<Item_ref *>(arg)->ref[0]; + if (arg->type() != FIELD_ITEM) { - Item_ref *ref= (Item_ref *)arg; - if (ref->ref[0]->type() != FIELD_ITEM) - { - my_error(ER_BAD_FIELD_ERROR, MYF(0), "", "VALUES() function"); - return TRUE; - } - arg= ref->ref[0]; + my_error(ER_BAD_FIELD_ERROR, MYF(0), "", "VALUES() function"); + return TRUE; } - /* - According to our SQL grammar, VALUES() function can reference - only to a column. - */ - DBUG_ASSERT(arg->type() == FIELD_ITEM); Item_field *field_arg= (Item_field *)arg; diff --git a/sql/item.h b/sql/item.h index 0445cd4a9d5..4f1bd10612a 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1828,7 +1828,7 @@ public: */ void (*set_param_func)(Item_param *param, uchar **pos, ulong len); - const String *query_val_str(String *str) const; + const String *query_val_str(THD *thd, String *str) const; bool convert_str_value(THD *thd); diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 5f8a7c6bd22..25b636397a8 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -254,7 +254,7 @@ public: Item_in_optimizer(Item *a, Item_in_subselect *b): Item_bool_func(a, my_reinterpret_cast(Item *)(b)), cache(0), save_cache(0), result_for_null_param(UNKNOWN) - {} + { with_subselect= true; } bool fix_fields(THD *, Item **); bool fix_left(THD *thd, Item **ref); table_map not_null_tables() const { return 0; } diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 15c8bbfe395..fc214a584ee 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -177,6 +177,7 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref) (*ref)= substitution; substitution->name= name; + substitution->name_length= name_length; if (have_to_be_excluded) engine->exclude(); substitution= 0; diff --git a/sql/log.cc b/sql/log.cc index 047439f6b73..4e42298a03c 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -3276,8 +3276,6 @@ int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included) pthread_mutex_lock(&rli->log_space_lock); rli->relay_log.purge_logs(to_purge_if_included, included, 0, 0, &rli->log_space_total); - // Tell the I/O thread to take the relay_log_space_limit into account - rli->ignore_log_space_limit= 0; pthread_mutex_unlock(&rli->log_space_lock); /* diff --git a/sql/log_event.cc b/sql/log_event.cc index 927b61eb391..572bcf9668e 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -572,7 +572,7 @@ char *str_to_hex(char *to, const char *from, uint len) */ int -append_query_string(CHARSET_INFO *csinfo, +append_query_string(THD *thd, CHARSET_INFO *csinfo, String const *from, String *to) { char *beg, *ptr; @@ -587,9 +587,26 @@ append_query_string(CHARSET_INFO *csinfo, else { *ptr++= '\''; - ptr+= escape_string_for_mysql(csinfo, ptr, 0, - from->ptr(), from->length()); - *ptr++='\''; + if (!(thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES)) + { + ptr+= escape_string_for_mysql(csinfo, ptr, 0, + from->ptr(), from->length()); + } + else + { + const char *frm_str= from->ptr(); + + for (; frm_str < (from->ptr() + from->length()); frm_str++) + { + /* Using '' way to represent "'" */ + if (*frm_str == '\'') + *ptr++= *frm_str; + + *ptr++= *frm_str; + } + } + + *ptr++= '\''; } to->length(orig_len + ptr - beg); return 0; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 26bb8df9249..6206c3c4a85 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -828,7 +828,7 @@ bool delete_precheck(THD *thd, TABLE_LIST *tables); bool insert_precheck(THD *thd, TABLE_LIST *tables); bool create_table_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *create_table); -int append_query_string(CHARSET_INFO *csinfo, +int append_query_string(THD *thd, CHARSET_INFO *csinfo, String const *from, String *to); void get_default_definer(THD *thd, LEX_USER *definer); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 586c614555d..e177f5f3ba6 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -964,13 +964,13 @@ static void close_connections(void) { if (base_ip_sock != INVALID_SOCKET) { - (void) shutdown(base_ip_sock, SHUT_RDWR); + (void) mysql_socket_shutdown(base_ip_sock, SHUT_RDWR); (void) closesocket(base_ip_sock); base_ip_sock= INVALID_SOCKET; } if (extra_ip_sock != INVALID_SOCKET) { - (void) shutdown(extra_ip_sock, SHUT_RDWR); + (void) mysql_socket_shutdown(extra_ip_sock, SHUT_RDWR); (void) closesocket(extra_ip_sock); extra_ip_sock= INVALID_SOCKET; } @@ -1002,7 +1002,7 @@ static void close_connections(void) #ifdef HAVE_SYS_UN_H if (unix_sock != INVALID_SOCKET) { - (void) shutdown(unix_sock, SHUT_RDWR); + (void) mysql_socket_shutdown(unix_sock, SHUT_RDWR); (void) closesocket(unix_sock); (void) unlink(mysqld_unix_port); unix_sock= INVALID_SOCKET; @@ -1118,7 +1118,7 @@ static void close_socket(my_socket sock, const char *info) if (sock != INVALID_SOCKET) { DBUG_PRINT("info", ("calling shutdown on %s socket", info)); - (void) shutdown(sock, SHUT_RDWR); + (void) mysql_socket_shutdown(sock, SHUT_RDWR); #if defined(__NETWARE__) /* The following code is disabled for normal systems as it causes MySQL @@ -2573,10 +2573,6 @@ static void check_data_home(const char *path) #endif /*__WIN__ || __NETWARE */ -#ifdef HAVE_LINUXTHREADS -#define UNSAFE_DEFAULT_LINUX_THREADS 200 -#endif - #if BACKTRACE_DEMANGLE #include <cxxabi.h> @@ -5324,7 +5320,7 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused))) if (req.sink) ((void (*)(int))req.sink)(req.fd); - (void) shutdown(new_sock, SHUT_RDWR); + (void) mysql_socket_shutdown(new_sock, SHUT_RDWR); (void) closesocket(new_sock); continue; } @@ -5339,7 +5335,7 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused))) if (getsockname(new_sock,&dummy, &dummyLen) < 0) { sql_perror("Error on new connection socket"); - (void) shutdown(new_sock, SHUT_RDWR); + (void) mysql_socket_shutdown(new_sock, SHUT_RDWR); (void) closesocket(new_sock); continue; } @@ -5351,7 +5347,7 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused))) if (!(thd= new THD)) { - (void) shutdown(new_sock, SHUT_RDWR); + (void) mysql_socket_shutdown(new_sock, SHUT_RDWR); VOID(closesocket(new_sock)); continue; } @@ -5370,7 +5366,7 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused))) vio_delete(vio_tmp); else { - (void) shutdown(new_sock, SHUT_RDWR); + (void) mysql_socket_shutdown(new_sock, SHUT_RDWR); (void) closesocket(new_sock); } delete thd; diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index 4f659e7821c..f82d0901d79 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -190,6 +190,13 @@ public: bool ignore_log_space_limit; /* + Used by the SQL thread to instructs the IO thread to rotate + the logs when the SQL thread needs to purge to release some + disk space. + */ + bool sql_force_rotate_relay; + + /* When it commits, InnoDB internally stores the master log position it has processed so far; the position to store is the one of the end of the committing event (the COMMIT query event, or the event if in autocommit diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc index 8128dddc7ee..3546efa9ee1 100644 --- a/sql/signal_handler.cc +++ b/sql/signal_handler.cc @@ -132,6 +132,7 @@ extern "C" sig_handler handle_fatal_signal(int sig) "Hope that's ok; if not, decrease some variables in the equation.\n\n"); #if defined(HAVE_LINUXTHREADS) +#define UNSAFE_DEFAULT_LINUX_THREADS 200 if (sizeof(char*) == 4 && thread_count > UNSAFE_DEFAULT_LINUX_THREADS) { my_safe_printf_stderr( diff --git a/sql/slave.cc b/sql/slave.cc index ff12a660883..7dd1a1885f1 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1411,6 +1411,56 @@ Waiting for the slave SQL thread to free enough relay log space"); !(slave_killed=io_slave_killed(thd,mi)) && !rli->ignore_log_space_limit) pthread_cond_wait(&rli->log_space_cond, &rli->log_space_lock); + + /* + Makes the IO thread read only one event at a time + until the SQL thread is able to purge the relay + logs, freeing some space. + + Therefore, once the SQL thread processes this next + event, it goes to sleep (no more events in the queue), + sets ignore_log_space_limit=true and wakes the IO thread. + However, this event may have been enough already for + the SQL thread to purge some log files, freeing + rli->log_space_total . + + This guarantees that the SQL and IO thread move + forward only one event at a time (to avoid deadlocks), + when the relay space limit is reached. It also + guarantees that when the SQL thread is prepared to + rotate (to be able to purge some logs), the IO thread + will know about it and will rotate. + + NOTE: The ignore_log_space_limit is only set when the SQL + thread sleeps waiting for events. + + */ + if (rli->ignore_log_space_limit) + { +#ifndef DBUG_OFF + { + char llbuf1[22], llbuf2[22]; + DBUG_PRINT("info", ("log_space_limit=%s " + "log_space_total=%s " + "ignore_log_space_limit=%d " + "sql_force_rotate_relay=%d", + llstr(rli->log_space_limit,llbuf1), + llstr(rli->log_space_total,llbuf2), + (int) rli->ignore_log_space_limit, + (int) rli->sql_force_rotate_relay)); + } +#endif + if (rli->sql_force_rotate_relay) + { + pthread_mutex_lock(&active_mi->data_lock); + rotate_relay_log(rli->mi); + pthread_mutex_unlock(&active_mi->data_lock); + rli->sql_force_rotate_relay= false; + } + + rli->ignore_log_space_limit= false; + } + thd->exit_cond(save_proc_info); DBUG_RETURN(slave_killed); } @@ -4225,19 +4275,45 @@ static Log_event* next_event(Relay_log_info* rli) constraint, because we do not want the I/O thread to block because of space (it's ok if it blocks for any other reason (e.g. because the master does not send anything). Then the I/O thread stops waiting - and reads more events. - The SQL thread decides when the I/O thread should take log_space_limit - into account again : ignore_log_space_limit is reset to 0 - in purge_first_log (when the SQL thread purges the just-read relay - log), and also when the SQL thread starts. We should also reset - ignore_log_space_limit to 0 when the user does RESET SLAVE, but in - fact, no need as RESET SLAVE requires that the slave + and reads one more event and starts honoring log_space_limit again. + + If the SQL thread needs more events to be able to rotate the log (it + might need to finish the current group first), then it can ask for one + more at a time. Thus we don't outgrow the relay log indefinitely, + but rather in a controlled manner, until the next rotate. + + When the SQL thread starts it sets ignore_log_space_limit to false. + We should also reset ignore_log_space_limit to 0 when the user does + RESET SLAVE, but in fact, no need as RESET SLAVE requires that the slave be stopped, and the SQL thread sets ignore_log_space_limit to 0 when it stops. */ pthread_mutex_lock(&rli->log_space_lock); - // prevent the I/O thread from blocking next times - rli->ignore_log_space_limit= 1; + + /* + If we have reached the limit of the relay space and we + are going to sleep, waiting for more events: + + 1. If outside a group, SQL thread asks the IO thread + to force a rotation so that the SQL thread purges + logs next time it processes an event (thus space is + freed). + + 2. If in a group, SQL thread asks the IO thread to + ignore the limit and queues yet one more event + so that the SQL thread finishes the group and + is are able to rotate and purge sometime soon. + */ + if (rli->log_space_limit && + rli->log_space_limit < rli->log_space_total) + { + /* force rotation if not in an unfinished group */ + rli->sql_force_rotate_relay= !rli->is_in_group(); + + /* ask for one more event */ + rli->ignore_log_space_limit= true; + } + /* If the I/O thread is blocked, unblock it. Ok to broadcast after unlock, because the mutex is only destroyed in @@ -4458,7 +4534,6 @@ int rotate_relay_log(Master_info* mi) DBUG_ENTER("rotate_relay_log"); Relay_log_info* rli= &mi->rli; int error= 0; - safe_mutex_assert_owner(&mi->data_lock); /* We need to test inited because otherwise, new_file() will attempt to lock @@ -4486,7 +4561,10 @@ int rotate_relay_log(Master_info* mi) output in SHOW SLAVE STATUS meanwhile. So we harvest now. If the log is closed, then this will just harvest the last writes, probably 0 as they probably have been harvested. + + Note that it needs to be protected by mi->data_lock. */ + safe_mutex_assert_owner(&mi->data_lock); rli->relay_log.harvest_bytes_written(&rli->log_space_total); end: DBUG_RETURN(error); diff --git a/sql/sp_head.cc b/sql/sp_head.cc index e36f5f4f1d5..9b06b3cb1b1 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -157,7 +157,7 @@ sp_get_item_value(THD *thd, Item *item, String *str) buf.append(result->charset()->csname); if (cs->escape_with_backslash_is_dangerous) buf.append(' '); - append_query_string(cs, result, &buf); + append_query_string(thd, cs, result, &buf); buf.append(" COLLATE '"); buf.append(item->collation.collation->name); buf.append('\''); diff --git a/sql/spatial.cc b/sql/spatial.cc index 6e2e03bf5bb..783d37ada48 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -627,7 +627,8 @@ int Gis_line_string::is_closed(int *closed) const return 0; } data+= 4; - if (no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points)) + if (n_points == 0 || + no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points)) return 1; /* Get first point */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1510ea7bf10..9f3dcd99701 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1738,8 +1738,9 @@ void log_slow_statement(THD *thd) ulonglong end_utime_of_query= thd->current_utime(); thd_proc_info(thd, "logging slow query"); - if (((end_utime_of_query - thd->utime_after_lock) > - thd->variables.long_query_time || + if ((((end_utime_of_query > thd->utime_after_lock) && + ((end_utime_of_query - thd->utime_after_lock) > + 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 && diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 2c062deacd0..be305cfa013 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -796,7 +796,7 @@ static bool insert_params_with_log(Prepared_statement *stmt, uchar *null_array, */ else if (! is_param_long_data_type(param)) DBUG_RETURN(1); - res= param->query_val_str(&str); + res= param->query_val_str(thd, &str); if (param->convert_str_value(thd)) DBUG_RETURN(1); /* out of memory */ @@ -970,7 +970,7 @@ static bool emb_insert_params_with_log(Prepared_statement *stmt, DBUG_RETURN(1); } } - res= param->query_val_str(&str); + res= param->query_val_str(thd, &str); if (param->convert_str_value(thd)) DBUG_RETURN(1); /* out of memory */ @@ -1116,7 +1116,7 @@ static bool insert_params_from_vars_with_log(Prepared_statement *stmt, setup_one_conversion_function(thd, param, param->param_type); if (param->set_from_user_var(thd, entry)) DBUG_RETURN(1); - val= param->query_val_str(&buf); + val= param->query_val_str(thd, &buf); if (param->convert_str_value(thd)) DBUG_RETURN(1); /* out of memory */ diff --git a/sql/sql_select.cc b/sql/sql_select.cc index bd7dd7df709..150f19f96a6 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -5861,6 +5861,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, } keyuse++; } while (keyuse->table == table && keyuse->key == key); + DBUG_ASSERT(length > 0 && keyparts != 0); } /* not ftkey */ /* set up fieldref */ @@ -8674,10 +8675,10 @@ change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list, left_item->collation.collation == value->collation.collation)) { Item *tmp=value->clone_item(); - tmp->collation.set(right_item->collation); if (tmp) { + tmp->collation.set(right_item->collation); thd->change_item_tree(args + 1, tmp); func->update_used_tables(); if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC) @@ -8698,10 +8699,10 @@ change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list, right_item->collation.collation == value->collation.collation)) { Item *tmp= value->clone_item(); - tmp->collation.set(left_item->collation); if (tmp) { + tmp->collation.set(left_item->collation); thd->change_item_tree(args, tmp); value= tmp; func->update_used_tables(); @@ -13838,6 +13839,9 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, DBUG_ENTER("test_if_skip_sort_order"); LINT_INIT(ref_key_parts); + /* Check that we are always called with first non-const table */ + DBUG_ASSERT(tab == tab->join->join_tab + tab->join->const_tables); + /* Keys disabled by ALTER TABLE ... DISABLE KEYS should have already been taken into account. @@ -13919,7 +13923,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, while (keyuse->key != new_ref_key && keyuse->table == tab->table) keyuse++; if (create_ref_for_key(tab->join, tab, keyuse, - tab->join->const_table_map)) + (tab->join->const_table_map | + OUTER_REF_TABLE_BIT))) DBUG_RETURN(0); pick_table_access_method(tab); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 52b6718d5e2..df213cf4df8 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4753,7 +4753,8 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table, (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0) { restore_record(table, s->default_values); - if (!wild || !wild[0] || !wild_compare(sp_name.c_ptr_safe(), wild, 0)) + if (!wild || !wild[0] || !wild_case_compare(system_charset_info, + sp_name.c_ptr_safe(), wild)) { int enum_idx= (int) proc_table->field[5]->val_int(); table->field[3]->store(sp_name.ptr(), sp_name.length(), cs); @@ -5746,7 +5747,7 @@ copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table) DBUG_RETURN(1); } - if (!(!wild || !wild[0] || !wild_compare(et.name.str, wild, 0))) + if (!(!wild || !wild[0] || !wild_case_compare(scs, et.name.str, wild))) DBUG_RETURN(0); /* |