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 | 9 | ||||
-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 | 92 | ||||
-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 | ||||
-rw-r--r-- | sql/table.cc | 1 |
21 files changed, 195 insertions, 77 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index cc343eb6e75..9d6e82b0356 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 @@ -6566,20 +6566,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 08e5a99f609..ca7ab346dc7 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 @@ -221,9 +221,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(); /* @@ -555,6 +555,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 3993fad1f9a..234420b64a8 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -342,6 +342,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); @@ -2871,6 +2872,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 55c32ea8f41..c2e208fe10f 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -3098,7 +3098,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: @@ -3136,7 +3136,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: @@ -3269,7 +3270,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); } } @@ -6692,20 +6693,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 be2d340a4d3..4201978201b 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1760,7 +1760,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 f612f944877..ffd0a162e19 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); bool is_null(); diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index c18e042520a..33404dcbe03 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; @@ -1045,7 +1046,13 @@ Item_in_subselect::single_value_transformer(JOIN *join, print_where(item, "rewrite with MIN/MAX", QT_ORDINARY);); if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY) { - DBUG_ASSERT(select_lex->non_agg_field_used()); + /* + If the argument is a field, we assume that fix_fields() has + tagged the select_lex with non_agg_field_used. + We reverse that decision after this rewrite with MIN/MAX. + */ + if (item->get_arg(0)->type() == Item::FIELD_ITEM) + DBUG_ASSERT(select_lex->non_agg_field_used()); select_lex->set_non_agg_field_used(false); } diff --git a/sql/log.cc b/sql/log.cc index 95f8e9e82ee..c74e8bc9233 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -3233,8 +3233,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 f56fa3c698a..2ca1721a7ab 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 5aeadd4d30b..60abf5a2361 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -814,7 +814,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 63495021841..3a7519991b2 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -944,13 +944,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; } @@ -982,7 +982,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; @@ -1098,7 +1098,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 @@ -2551,10 +2551,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> @@ -5244,7 +5240,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; } @@ -5259,7 +5255,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; } @@ -5271,7 +5267,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; } @@ -5290,7 +5286,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 ae0cf6e1bb0..0aefb10356a 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 1971001d759..e793061b844 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1410,6 +1410,54 @@ 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) + { + rotate_relay_log(rli->mi); + rli->sql_force_rotate_relay= false; + } + + rli->ignore_log_space_limit= false; + } + thd->exit_cond(save_proc_info); DBUG_RETURN(slave_killed); } @@ -4224,19 +4272,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 diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 932d0d052e8..473baa9ab9b 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 8c51ea69618..64eb7645d03 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1793,8 +1793,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 1c0ee55b79d..6aa119f7d71 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 932fdf1b2cf..745e02e128a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -5859,6 +5859,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 */ @@ -8631,10 +8632,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) @@ -8655,10 +8656,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(); @@ -13763,6 +13764,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. @@ -13844,7 +13848,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 f40f28b2aae..02505962347 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4362,7 +4362,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); @@ -5355,7 +5356,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); /* diff --git a/sql/table.cc b/sql/table.cc index 0a564f8ad1d..1206fc2dff3 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -4005,6 +4005,7 @@ Item *Field_iterator_table::create_item(THD *thd) { select->non_agg_fields.push_back(item); item->marker= select->cur_pos_in_select_list; + select->set_non_agg_field_used(true); } return item; } |