diff options
author | Sergei Golubchik <sergii@pisem.net> | 2013-07-18 16:46:57 +0200 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2013-07-18 16:46:57 +0200 |
commit | 5f6380adde2dac3f32b40339b9b702c0135eb7d6 (patch) | |
tree | 31068acc0b39c208d35d524688a5985831af0447 /sql | |
parent | 8a23ae088dc38f591efeab9eccdef5eb9094add9 (diff) | |
parent | 97e640b9ae83e07b444fceede6b0524256c7a3cc (diff) | |
download | mariadb-git-5f6380adde2dac3f32b40339b9b702c0135eb7d6.tar.gz |
10.0-base merge
Diffstat (limited to 'sql')
120 files changed, 1530 insertions, 941 deletions
diff --git a/sql/custom_conf.h b/sql/custom_conf.h index 137b7e9eef2..afef0219857 100644 --- a/sql/custom_conf.h +++ b/sql/custom_conf.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __MYSQL_CUSTOM_BUILD_CONFIG__ #define __MYSQL_CUSTOM_BUILD_CONFIG__ diff --git a/sql/discover.cc b/sql/discover.cc index 4224e8ce0b0..cc0dece031a 100644 --- a/sql/discover.cc +++ b/sql/discover.cc @@ -198,10 +198,10 @@ int extension_based_table_discovery(MY_DIR *dirp, const char *ext_meta, end= cur + dirp->number_of_files; while (cur < end) { - char *octothorp= strrchr(cur->name, '#'); + char *octothorp= strrchr(cur->name + 1, '#'); char *ext= strchr(octothorp ? octothorp : cur->name, FN_EXTCHAR); - if (ext && octothorp != cur->name) + if (ext) { size_t len= (octothorp ? octothorp : ext) - cur->name; if (from != cur && @@ -239,13 +239,6 @@ int extension_based_table_discovery(MY_DIR *dirp, const char *ext_meta, simplified version of extension_based_table_discovery(), that does not modify the list of files. It cannot be called many times for the same directory listing, otherwise it'll produce duplicate results. - - @note - For backward compatibility reasons, this will find tables with names, - starting from '#', as long as they don't start from '#sql-'. - These names are invalid since 5.0, and the compex discovery function - will ignore them. Anyone still having these files, should disable - discovering engines, and rename these invalid table files. */ int ext_table_discovery_simple(MY_DIR *dirp, handlerton::discovered_list *result) @@ -259,7 +252,7 @@ int ext_table_discovery_simple(MY_DIR *dirp, { char *ext= strrchr(cur->name, FN_EXTCHAR); - if (ext && !is_prefix(cur->name, tmp_file_prefix)) + if (ext) { if (my_strnncoll(cs, (uchar*)ext, strlen(ext), (uchar*)reg_ext, reg_ext_length) == 0) diff --git a/sql/field.cc b/sql/field.cc index e6cab7184fd..1cdf2ffd313 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -5158,10 +5158,9 @@ int Field_temporal_with_date::store(const char *from, uint len, CHARSET_INFO *cs THD *thd= get_thd(); ErrConvString str(from, len, cs); bool func_res= !str_to_datetime(cs, from, len, <ime, - (TIME_FUZZY_DATE | - (thd->variables.sql_mode & + (thd->variables.sql_mode & (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | - MODE_INVALID_DATES))), + MODE_INVALID_DATES)), &status); return store_TIME_with_warning(<ime, &str, status.warnings, func_res); } @@ -5175,11 +5174,10 @@ int Field_temporal_with_date::store(double nr) ErrConvDouble str(nr); longlong tmp= double_to_datetime(nr, <ime, - (TIME_FUZZY_DATE | - (thd->variables.sql_mode & + (thd->variables.sql_mode & (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | - MODE_INVALID_DATES))), &error); + MODE_INVALID_DATES)), &error); return store_TIME_with_warning(<ime, &str, error, tmp != -1); } @@ -5192,11 +5190,10 @@ int Field_temporal_with_date::store(longlong nr, bool unsigned_val) THD *thd= get_thd(); ErrConvInteger str(nr); - tmp= number_to_datetime(nr, 0, <ime, (TIME_FUZZY_DATE | - (thd->variables.sql_mode & + tmp= number_to_datetime(nr, 0, <ime, (thd->variables.sql_mode & (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | - MODE_INVALID_DATES))), &error); + MODE_INVALID_DATES)), &error); return store_TIME_with_warning(<ime, &str, error, tmp != -1); } @@ -5212,17 +5209,16 @@ int Field_temporal_with_date::store_time_dec(MYSQL_TIME *ltime, uint dec) structure always fit into DATETIME range. */ have_smth_to_conv= !check_date(&l_time, pack_time(&l_time) != 0, - (TIME_FUZZY_DATE | - (current_thd->variables.sql_mode & + (current_thd->variables.sql_mode & (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | - MODE_INVALID_DATES))), &error); + MODE_INVALID_DATES)), &error); return store_TIME_with_warning(&l_time, &str, error, have_smth_to_conv); } my_decimal *Field_temporal::val_decimal(my_decimal *d) { MYSQL_TIME ltime; - if (get_date(<ime, TIME_FUZZY_DATE)) + if (get_date(<ime, 0)) { bzero(<ime, sizeof(ltime)); ltime.time_type= mysql_type_to_time_type(type()); @@ -5373,9 +5369,10 @@ String *Field_time::val_str(String *str, bool Field_time::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) { - THD *thd= get_thd(); - if (!(fuzzydate & (TIME_FUZZY_DATE|TIME_TIME_ONLY))) + if (!(fuzzydate & TIME_TIME_ONLY) && + (fuzzydate & TIME_NO_ZERO_IN_DATE)) { + THD *thd= get_thd(); push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, ER(ER_WARN_DATA_OUT_OF_RANGE), field_name, @@ -5499,7 +5496,7 @@ bool Field_time_hires::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) ltime->time_type= MYSQL_TIMESTAMP_TIME; ltime->hour+= (ltime->month*32+ltime->day)*24; ltime->month= ltime->day= 0; - return fuzzydate & (TIME_FUZZY_DATE | TIME_TIME_ONLY) ? 0 : 1; + return !(fuzzydate & TIME_TIME_ONLY) && (fuzzydate & TIME_NO_ZERO_IN_DATE); } @@ -5901,7 +5898,7 @@ void Field_datetime::store_TIME(MYSQL_TIME *ltime) bool Field_datetime::send_binary(Protocol *protocol) { MYSQL_TIME tm; - Field_datetime::get_date(&tm, TIME_FUZZY_DATE); + Field_datetime::get_date(&tm, 0); return protocol->store(&tm, 0); } @@ -5985,7 +5982,7 @@ bool Field_datetime::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) if (!tmp) return fuzzydate & TIME_NO_ZERO_DATE; if (!ltime->month || !ltime->day) - return !(fuzzydate & TIME_FUZZY_DATE); + return fuzzydate & TIME_NO_ZERO_IN_DATE; return 0; } @@ -6059,11 +6056,10 @@ int Field_temporal_with_date::store_decimal(const my_decimal *d) error= 2; } else - tmp= number_to_datetime(nr, sec_part, <ime, (TIME_FUZZY_DATE | - (thd->variables.sql_mode & + tmp= number_to_datetime(nr, sec_part, <ime, (thd->variables.sql_mode & (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | - MODE_INVALID_DATES))), &error); + MODE_INVALID_DATES)), &error); return store_TIME_with_warning(<ime, &str, error, tmp != -1); } @@ -6071,7 +6067,7 @@ int Field_temporal_with_date::store_decimal(const my_decimal *d) bool Field_datetime_with_dec::send_binary(Protocol *protocol) { MYSQL_TIME ltime; - get_date(<ime, TIME_FUZZY_DATE); + get_date(<ime, 0); return protocol->store(<ime, dec); } @@ -6079,14 +6075,14 @@ bool Field_datetime_with_dec::send_binary(Protocol *protocol) double Field_datetime_with_dec::val_real(void) { MYSQL_TIME ltime; - get_date(<ime, TIME_FUZZY_DATE); + get_date(<ime, 0); return TIME_to_double(<ime); } longlong Field_datetime_with_dec::val_int(void) { MYSQL_TIME ltime; - get_date(<ime, TIME_FUZZY_DATE); + get_date(<ime, 0); return TIME_to_ulonglong_datetime(<ime); } @@ -6095,7 +6091,7 @@ String *Field_datetime_with_dec::val_str(String *str, String *unused __attribute__((unused))) { MYSQL_TIME ltime; - get_date(<ime, TIME_FUZZY_DATE); + get_date(<ime, 0); str->alloc(field_length+1); str->length(field_length); my_datetime_to_str(<ime, (char*) str->ptr(), dec); @@ -6110,7 +6106,7 @@ bool Field_datetime_hires::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) if (!packed) return fuzzydate & TIME_NO_ZERO_DATE; if (!ltime->month || !ltime->day) - return !(fuzzydate & TIME_FUZZY_DATE); + return fuzzydate & TIME_NO_ZERO_IN_DATE; return 0; } @@ -6157,7 +6153,7 @@ bool Field_datetimef::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) if (!tmp) return fuzzydate & TIME_NO_ZERO_DATE; if (!ltime->month || !ltime->day) - return !(fuzzydate & TIME_FUZZY_DATE); + return fuzzydate & TIME_NO_ZERO_IN_DATE; return false; } diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 6685b334d06..6c3fcc0d355 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -419,7 +419,7 @@ static void do_field_decimal(Copy_field *copy) static void do_field_temporal(Copy_field *copy) { MYSQL_TIME ltime; - copy->from_field->get_date(<ime, TIME_FUZZY_DATE); + copy->from_field->get_date(<ime, 0); copy->to_field->store_time_dec(<ime, copy->from_field->decimals()); } @@ -890,7 +890,7 @@ int field_conv(Field *to,Field *from) if (from->cmp_type() == TIME_RESULT) { MYSQL_TIME ltime; - if (from->get_date(<ime, TIME_FUZZY_DATE)) + if (from->get_date(<ime, 0)) return to->reset(); else return to->store_time_dec(<ime, from->decimals()); diff --git a/sql/filesort.cc b/sql/filesort.cc index 6f8867e8d64..f5a85036faa 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** @@ -55,7 +55,7 @@ static ha_rows find_all_keys(Sort_param *param,SQL_SELECT *select, IO_CACHE *tempfile, Bounded_queue<uchar, uchar> *pq, ha_rows *found_rows); -static int write_keys(Sort_param *param, Filesort_info *fs_info, +static bool write_keys(Sort_param *param, Filesort_info *fs_info, uint count, IO_CACHE *buffer_file, IO_CACHE *tempfile); static void make_sortkey(Sort_param *param, uchar *to, uchar *ref_pos); static void register_used_fields(Sort_param *param); @@ -147,7 +147,7 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, ha_rows *found_rows) { int error; - ulong memory_available= thd->variables.sortbuff_size; + size_t memory_available= thd->variables.sortbuff_size; uint maxbuffer; BUFFPEK *buffpek; ha_rows num_rows= HA_POS_ERROR; @@ -245,11 +245,11 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, { DBUG_PRINT("info", ("filesort PQ is not applicable")); - ulong min_sort_memory= max(MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2); + size_t min_sort_memory= max(MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2); set_if_bigger(min_sort_memory, sizeof(BUFFPEK*)*MERGEBUFF2); while (memory_available >= min_sort_memory) { - ulong keys= memory_available / (param.rec_length + sizeof(char*)); + ulonglong keys= memory_available / (param.rec_length + sizeof(char*)); param.max_keys_per_buffer= (uint) min(num_rows, keys); if (table_sort.get_sort_keys()) { @@ -267,7 +267,7 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, table_sort.alloc_sort_buffer(param.max_keys_per_buffer, param.rec_length); if (table_sort.get_sort_keys()) break; - ulong old_memory_available= memory_available; + size_t old_memory_available= memory_available; memory_available= memory_available/4*3; if (memory_available < min_sort_memory && old_memory_available > min_sort_memory) @@ -448,7 +448,7 @@ void filesort_free_buffers(TABLE *table, bool full) static uchar *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count, uchar *buf) { - ulong length= sizeof(BUFFPEK)*count; + size_t length= sizeof(BUFFPEK)*count; uchar *tmp= buf; DBUG_ENTER("read_buffpek_from_file"); if (count > UINT_MAX/sizeof(BUFFPEK)) @@ -790,7 +790,7 @@ static ha_rows find_all_keys(Sort_param *param, SQL_SELECT *select, 1 Error */ -static int +static bool write_keys(Sort_param *param, Filesort_info *fs_info, uint count, IO_CACHE *buffpek_pointers, IO_CACHE *tempfile) { @@ -951,7 +951,7 @@ static void make_sortkey(register Sort_param *param, else { MYSQL_TIME buf; - if (item->get_date_result(&buf, TIME_FUZZY_DATE | TIME_INVALID_DATES)) + if (item->get_date_result(&buf, TIME_INVALID_DATES)) { DBUG_ASSERT(maybe_null); DBUG_ASSERT(item->null_value); diff --git a/sql/ha_ndbcluster_cond.cc b/sql/ha_ndbcluster_cond.cc index 9ab7fb6208d..f8b2ed8429a 100644 --- a/sql/ha_ndbcluster_cond.cc +++ b/sql/ha_ndbcluster_cond.cc @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /* diff --git a/sql/ha_ndbcluster_cond.h b/sql/ha_ndbcluster_cond.h index 442eac2fafd..27675588ed7 100644 --- a/sql/ha_ndbcluster_cond.h +++ b/sql/ha_ndbcluster_cond.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /* This file defines the data structures used by engine condition pushdown in diff --git a/sql/ha_ndbcluster_tables.h b/sql/ha_ndbcluster_tables.h index ba2e8ec251b..6ed46123738 100644 --- a/sql/ha_ndbcluster_tables.h +++ b/sql/ha_ndbcluster_tables.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #define NDB_REP_DB "mysql" diff --git a/sql/handler.cc b/sql/handler.cc index 867d07f4990..726b663341b 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -121,7 +121,7 @@ handlerton *ha_default_handlerton(THD *thd) { plugin_ref plugin= ha_default_plugin(thd); DBUG_ASSERT(plugin); - handlerton *hton= plugin_data(plugin, handlerton*); + handlerton *hton= plugin_hton(plugin); DBUG_ASSERT(hton); return hton; } @@ -152,7 +152,7 @@ redo: if ((plugin= my_plugin_lock_by_name(thd, name, MYSQL_STORAGE_ENGINE_PLUGIN))) { - handlerton *hton= plugin_data(plugin, handlerton *); + handlerton *hton= plugin_hton(plugin); if (hton && !(hton->flags & HTON_NOT_USER_SELECTABLE)) return plugin; @@ -200,7 +200,7 @@ handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type) default: if (db_type > DB_TYPE_UNKNOWN && db_type < DB_TYPE_DEFAULT && (plugin= ha_lock_engine(thd, installed_htons[db_type]))) - return plugin_data(plugin, handlerton*); + return plugin_hton(plugin); /* fall through */ case DB_TYPE_UNKNOWN: return NULL; @@ -660,7 +660,7 @@ int ha_end() static my_bool dropdb_handlerton(THD *unused1, plugin_ref plugin, void *path) { - handlerton *hton= plugin_data(plugin, handlerton *); + handlerton *hton= plugin_hton(plugin); if (hton->state == SHOW_OPTION_YES && hton->drop_database) hton->drop_database(hton, (char *)path); return FALSE; @@ -676,7 +676,7 @@ void ha_drop_database(char* path) static my_bool checkpoint_state_handlerton(THD *unused1, plugin_ref plugin, void *disable) { - handlerton *hton= plugin_data(plugin, handlerton *); + handlerton *hton= plugin_hton(plugin); if (hton->state == SHOW_OPTION_YES && hton->checkpoint_state) hton->checkpoint_state(hton, (int) *(bool*) disable); return FALSE; @@ -698,7 +698,7 @@ static my_bool commit_checkpoint_request_handlerton(THD *unused1, plugin_ref plu void *data) { st_commit_checkpoint_request *st= (st_commit_checkpoint_request *)data; - handlerton *hton= plugin_data(plugin, handlerton *); + handlerton *hton= plugin_hton(plugin); if (hton->state == SHOW_OPTION_YES && hton->commit_checkpoint_request) { void *cookie= st->cookie; @@ -730,7 +730,7 @@ ha_commit_checkpoint_request(void *cookie, void (*pre_hook)(void *)) static my_bool closecon_handlerton(THD *thd, plugin_ref plugin, void *unused) { - handlerton *hton= plugin_data(plugin, handlerton *); + handlerton *hton= plugin_hton(plugin); /* there's no need to rollback here as all transactions must be rolled back already @@ -757,7 +757,7 @@ void ha_close_connection(THD* thd) static my_bool kill_handlerton(THD *thd, plugin_ref plugin, void *level) { - handlerton *hton= plugin_data(plugin, handlerton *); + handlerton *hton= plugin_hton(plugin); if (hton->state == SHOW_OPTION_YES && hton->kill_query && thd_get_ha_data(thd, hton)) @@ -1610,7 +1610,7 @@ struct xahton_st { static my_bool xacommit_handlerton(THD *unused1, plugin_ref plugin, void *arg) { - handlerton *hton= plugin_data(plugin, handlerton *); + handlerton *hton= plugin_hton(plugin); if (hton->state == SHOW_OPTION_YES && hton->recover) { hton->commit_by_xid(hton, ((struct xahton_st *)arg)->xid); @@ -1622,7 +1622,7 @@ static my_bool xacommit_handlerton(THD *unused1, plugin_ref plugin, static my_bool xarollback_handlerton(THD *unused1, plugin_ref plugin, void *arg) { - handlerton *hton= plugin_data(plugin, handlerton *); + handlerton *hton= plugin_hton(plugin); if (hton->state == SHOW_OPTION_YES && hton->recover) { hton->rollback_by_xid(hton, ((struct xahton_st *)arg)->xid); @@ -1728,7 +1728,7 @@ struct xarecover_st static my_bool xarecover_handlerton(THD *unused, plugin_ref plugin, void *arg) { - handlerton *hton= plugin_data(plugin, handlerton *); + handlerton *hton= plugin_hton(plugin); struct xarecover_st *info= (struct xarecover_st *) arg; int got; @@ -2057,7 +2057,7 @@ int ha_release_savepoint(THD *thd, SAVEPOINT *sv) static my_bool snapshot_handlerton(THD *thd, plugin_ref plugin, void *arg) { - handlerton *hton= plugin_data(plugin, handlerton *); + handlerton *hton= plugin_hton(plugin); if (hton->state == SHOW_OPTION_YES && hton->start_consistent_snapshot) { @@ -2097,7 +2097,7 @@ int ha_start_consistent_snapshot(THD *thd) static my_bool flush_handlerton(THD *thd, plugin_ref plugin, void *arg) { - handlerton *hton= plugin_data(plugin, handlerton *); + handlerton *hton= plugin_hton(plugin); if (hton->state == SHOW_OPTION_YES && hton->flush_logs && hton->flush_logs(hton)) return TRUE; @@ -3030,6 +3030,7 @@ void handler::get_auto_increment(ulonglong offset, ulonglong increment, { /* This should never happen, assert in debug, and fail in release build */ DBUG_ASSERT(0); + (void) extra(HA_EXTRA_NO_KEYREAD); *first_value= ULONGLONG_MAX; return; } @@ -4495,7 +4496,7 @@ static my_bool discover_handlerton(THD *thd, plugin_ref plugin, void *arg) { TABLE_SHARE *share= (TABLE_SHARE *)arg; - handlerton *hton= plugin_data(plugin, handlerton *); + handlerton *hton= plugin_hton(plugin); if (hton->state == SHOW_OPTION_YES && hton->discover_table) { share->db_plugin= plugin; @@ -4504,8 +4505,13 @@ static my_bool discover_handlerton(THD *thd, plugin_ref plugin, { if (error) { - DBUG_ASSERT(share->error); // MUST be always set for get_cached_table_share to work - my_error(ER_GET_ERRNO, MYF(0), error, plugin_name(plugin)->str); + DBUG_ASSERT(share->error); // get_cached_table_share needs that + /* + report an error, unless it is "generic" and a more + specific one was already reported + */ + if (error != HA_ERR_GENERIC || !thd->is_error()) + my_error(ER_GET_ERRNO, MYF(0), error, plugin_name(plugin)->str); share->db_plugin= 0; } else @@ -4558,7 +4564,7 @@ static my_bool discover_existence(THD *thd, plugin_ref plugin, void *arg) { st_discover_existence_args *args= (st_discover_existence_args*)arg; - handlerton *ht= plugin_data(plugin, handlerton *); + handlerton *ht= plugin_hton(plugin); if (ht->state != SHOW_OPTION_YES || !ht->discover_table_existence) return FALSE; @@ -4782,7 +4788,7 @@ static my_bool discover_names(THD *thd, plugin_ref plugin, void *arg) { st_discover_names_args *args= (st_discover_names_args *)arg; - handlerton *ht= plugin_data(plugin, handlerton *); + handlerton *ht= plugin_hton(plugin); if (ht->state == SHOW_OPTION_YES && ht->discover_table_names) { @@ -4802,12 +4808,12 @@ static my_bool discover_names(THD *thd, plugin_ref plugin, } int ha_discover_table_names(THD *thd, LEX_STRING *db, MY_DIR *dirp, - Discovered_table_list *result) + Discovered_table_list *result, bool reusable) { int error; DBUG_ENTER("ha_discover_table_names"); - if (engines_with_discover_table_names == 0) + if (engines_with_discover_table_names == 0 && !reusable) { error= ext_table_discovery_simple(dirp, result); result->sort(); @@ -4859,7 +4865,7 @@ struct binlog_func_st static my_bool binlog_func_list(THD *thd, plugin_ref plugin, void *arg) { hton_list_st *hton_list= (hton_list_st *)arg; - handlerton *hton= plugin_data(plugin, handlerton *); + handlerton *hton= plugin_hton(plugin); if (hton->state == SHOW_OPTION_YES && hton->binlog_func) { uint sz= hton_list->sz; @@ -4949,7 +4955,7 @@ static my_bool binlog_log_query_handlerton(THD *thd, plugin_ref plugin, void *args) { - return binlog_log_query_handlerton2(thd, plugin_data(plugin, handlerton *), args); + return binlog_log_query_handlerton2(thd, plugin_hton(plugin), args); } void ha_binlog_log_query(THD *thd, handlerton *hton, @@ -5180,7 +5186,7 @@ static my_bool exts_handlerton(THD *unused, plugin_ref plugin, void *arg) { List<char> *found_exts= (List<char> *) arg; - handlerton *hton= plugin_data(plugin, handlerton *); + handlerton *hton= plugin_hton(plugin); List_iterator_fast<char> it(*found_exts); const char **ext, *old_ext; @@ -5249,7 +5255,7 @@ static my_bool showstat_handlerton(THD *thd, plugin_ref plugin, void *arg) { enum ha_stat_type stat= *(enum ha_stat_type *) arg; - handlerton *hton= plugin_data(plugin, handlerton *); + handlerton *hton= plugin_hton(plugin); if (hton->state == SHOW_OPTION_YES && hton->show_status && hton->show_status(hton, thd, stat_print, stat)) return TRUE; diff --git a/sql/handler.h b/sql/handler.h index 99d75816c68..9f8290ee176 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -370,9 +370,9 @@ enum legacy_db_type DB_TYPE_PARTITION_DB=20, DB_TYPE_BINLOG=21, DB_TYPE_PBXT=23, - DB_TYPE_MARIA=27, DB_TYPE_PERFORMANCE_SCHEMA=28, - DB_TYPE_FIRST_DYNAMIC=42, + DB_TYPE_ARIA=42, + DB_TYPE_FIRST_DYNAMIC=43, DB_TYPE_DEFAULT=127 // Must be last }; /* @@ -1227,6 +1227,11 @@ static inline LEX_STRING *hton_name(const handlerton *hton) return &(hton2plugin[hton->slot]->name); } +static inline handlerton *plugin_hton(plugin_ref plugin) +{ + return plugin_data(plugin, handlerton *); +} + static inline sys_var *find_hton_sysvar(handlerton *hton, st_mysql_sys_var *var) { return find_plugin_sysvar(hton2plugin[hton->slot], var); @@ -2859,7 +2864,33 @@ public: Pops the top if condition stack, if stack is not empty. */ virtual void cond_pop() { return; }; + + /** + Push down an index condition to the handler. + + The server will use this method to push down a condition it wants + the handler to evaluate when retrieving records using a specified + index. The pushed index condition will only refer to fields from + this handler that is contained in the index (but it may also refer + to fields in other handlers). Before the handler evaluates the + condition it must read the content of the index entry into the + record buffer. + + The handler is free to decide if and how much of the condition it + will take responsibility for evaluating. Based on this evaluation + it should return the part of the condition it will not evaluate. + If it decides to evaluate the entire condition it should return + NULL. If it decides not to evaluate any part of the condition it + should return a pointer to the same condition as given as argument. + + @param keyno the index number to evaluate the condition on + @param idx_cond the condition to be evaluated by the handler + + @return The part of the pushed condition that the handler decides + not to evaluate + */ virtual Item *idx_cond_push(uint keyno, Item* idx_cond) { return idx_cond; } + /** Reset information about pushed index conditions */ virtual void cancel_pushed_idx_cond() { @@ -3238,7 +3269,7 @@ public: int ha_discover_table(THD *thd, TABLE_SHARE *share); int ha_discover_table_names(THD *thd, LEX_STRING *db, MY_DIR *dirp, - Discovered_table_list *result); + Discovered_table_list *result, bool reusable); bool ha_table_exists(THD *thd, const char *db, const char *table_name, handlerton **hton= 0); #endif diff --git a/sql/hostname.cc b/sql/hostname.cc index ee30d071602..3540dd8c8ab 100644 --- a/sql/hostname.cc +++ b/sql/hostname.cc @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** diff --git a/sql/innodb_priv.h b/sql/innodb_priv.h index 24ee848bed1..33ba7b0f5b3 100644 --- a/sql/innodb_priv.h +++ b/sql/innodb_priv.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef INNODB_PRIV_INCLUDED #define INNODB_PRIV_INCLUDED diff --git a/sql/item.cc b/sql/item.cc index 21eacb38401..6ce93f501fe 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -297,7 +297,7 @@ String *Item::val_string_from_decimal(String *str) String *Item::val_string_from_date(String *str) { MYSQL_TIME ltime; - if (get_date(<ime, TIME_FUZZY_DATE) || + if (get_date(<ime, 0) || str->alloc(MAX_DATE_STRING_REP_LENGTH)) { null_value= 1; @@ -354,7 +354,7 @@ my_decimal *Item::val_decimal_from_date(my_decimal *decimal_value) { DBUG_ASSERT(fixed == 1); MYSQL_TIME ltime; - if (get_date(<ime, TIME_FUZZY_DATE)) + if (get_date(<ime, 0)) { my_decimal_set_zero(decimal_value); null_value= 1; // set NULL, stop processing @@ -381,7 +381,7 @@ longlong Item::val_int_from_date() { DBUG_ASSERT(fixed == 1); MYSQL_TIME ltime; - if (get_date(<ime, TIME_FUZZY_DATE)) + if (get_date(<ime, 0)) return 0; longlong v= TIME_to_ulonglong(<ime); return ltime.neg ? -v : v; @@ -392,7 +392,7 @@ double Item::val_real_from_date() { DBUG_ASSERT(fixed == 1); MYSQL_TIME ltime; - if (get_date(<ime, TIME_FUZZY_DATE)) + if (get_date(<ime, 0)) return 0; return TIME_to_double(<ime); } @@ -434,10 +434,9 @@ int Item::save_time_in_field(Field *field) int Item::save_date_in_field(Field *field) { MYSQL_TIME ltime; - if (get_date(<ime, TIME_FUZZY_DATE | - (current_thd->variables.sql_mode & - (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | - MODE_INVALID_DATES)))) + if (get_date(<ime, (current_thd->variables.sql_mode & + (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | + MODE_INVALID_DATES)))) return set_field_to_null_with_conversions(field, 0); field->set_notnull(); return field->store_time_dec(<ime, decimals); @@ -1309,7 +1308,7 @@ err: if allowed, otherwise - null. */ bzero((char*) ltime,sizeof(*ltime)); - return null_value|= (fuzzydate & (TIME_NO_ZERO_DATE|TIME_NO_ZERO_IN_DATE)); + return null_value|= !(fuzzydate & TIME_FUZZY_DATES); } bool Item::get_seconds(ulonglong *sec, ulong *sec_part) @@ -3697,7 +3696,9 @@ bool Item_param::convert_str_value(THD *thd) /* Here str_value is guaranteed to be in final_character_set_of_str_value */ max_length= str_value.numchars() * str_value.charset()->mbmaxlen; - decimals= 0; + + /* For the strings converted to numeric form within some functions */ + decimals= NOT_FIXED_DEC; /* str_value_ptr is returned from val_str(). It must be not alloced to prevent it's modification by val_str() invoker. @@ -6475,7 +6476,7 @@ bool Item::send(Protocol *protocol, String *buffer) case MYSQL_TYPE_TIMESTAMP: { MYSQL_TIME tm; - get_date(&tm, TIME_FUZZY_DATE | sql_mode_for_dates()); + get_date(&tm, sql_mode_for_dates()); if (!null_value) { if (f_type == MYSQL_TYPE_DATE) @@ -8707,8 +8708,8 @@ int stored_field_cmp_to_item(THD *thd, Field *field, Item *item) } else { - field->get_date(&field_time, TIME_FUZZY_DATE | TIME_INVALID_DATES); - item->get_date(&item_time, TIME_FUZZY_DATE | TIME_INVALID_DATES); + field->get_date(&field_time, TIME_INVALID_DATES); + item->get_date(&item_time, TIME_INVALID_DATES); } return my_time_compare(&field_time, &item_time); } @@ -8890,7 +8891,7 @@ bool Item_cache_temporal::cache_value() value_cached= true; MYSQL_TIME ltime; - if (example->get_date_result(<ime, TIME_FUZZY_DATE)) + if (example->get_date_result(<ime, 0)) value=0; else value= pack_time(<ime); diff --git a/sql/item.h b/sql/item.h index a298f16a93b..5514231e4fd 100644 --- a/sql/item.h +++ b/sql/item.h @@ -15,7 +15,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifdef USE_PRAGMA_INTERFACE @@ -1060,7 +1060,7 @@ public: Item **ref, bool skip_registered); virtual bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate); bool get_time(MYSQL_TIME *ltime) - { return get_date(ltime, TIME_TIME_ONLY | TIME_FUZZY_DATE); } + { return get_date(ltime, TIME_TIME_ONLY); } bool get_seconds(ulonglong *sec, ulong *sec_part); virtual bool get_date_result(MYSQL_TIME *ltime, ulonglong fuzzydate) { return get_date(ltime,fuzzydate); } diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 122505ab265..5dbd7f8b152 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** @@ -722,7 +722,7 @@ bool get_mysql_time_from_str(THD *thd, String *str, timestamp_type warn_type, { bool value; MYSQL_TIME_STATUS status; - int flags= TIME_FUZZY_DATE | MODE_INVALID_DATES; + int flags= TIME_FUZZY_DATES | MODE_INVALID_DATES; ErrConvString err(str); DBUG_ASSERT(warn_type != MYSQL_TIMESTAMP_TIME); @@ -896,7 +896,7 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, else { MYSQL_TIME ltime; - uint fuzzydate= TIME_FUZZY_DATE | TIME_INVALID_DATES; + uint fuzzydate= TIME_FUZZY_DATES | TIME_INVALID_DATES; if (f_type == MYSQL_TYPE_TIME) fuzzydate|= TIME_TIME_ONLY; if (item->get_date(<ime, fuzzydate)) diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index ab4219564fe..bf65d6e7c07 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /* compare and test functions */ diff --git a/sql/item_create.cc b/sql/item_create.cc index c6d0f09907b..ba1ce2b0d3b 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -5841,11 +5841,10 @@ Item *create_temporal_literal(THD *thd, MYSQL_TIME_STATUS status; MYSQL_TIME ltime; Item *item= NULL; - ulonglong datetime_flags= thd->variables.sql_mode & + ulonglong flags= thd->variables.sql_mode & (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES); - ulonglong flags= TIME_FUZZY_DATE | datetime_flags; switch(type) { diff --git a/sql/item_func.cc b/sql/item_func.cc index 05dae1b1d2a..7ac42ebdbad 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -41,6 +41,7 @@ #include "sql_acl.h" // EXECUTE_ACL #include "mysqld.h" // LOCK_short_uuid_generator #include "rpl_mi.h" +#include "sql_time.h" #include <m_ctype.h> #include <hash.h> #include <time.h> @@ -2775,6 +2776,12 @@ bool Item_func_min_max::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) min_max= res; } unpack_time(min_max, ltime); + + if (!(fuzzy_date & TIME_TIME_ONLY) && + ((null_value= check_date_with_warn(ltime, fuzzy_date, + MYSQL_TIMESTAMP_ERROR)))) + return true; + if (compare_as_dates->field_type() == MYSQL_TYPE_DATE) { ltime->time_type= MYSQL_TIMESTAMP_DATE; @@ -2838,7 +2845,7 @@ double Item_func_min_max::val_real() if (compare_as_dates) { MYSQL_TIME ltime; - if (get_date(<ime, TIME_FUZZY_DATE)) + if (get_date(<ime, 0)) return 0; return TIME_to_double(<ime); @@ -2867,7 +2874,7 @@ longlong Item_func_min_max::val_int() if (compare_as_dates) { MYSQL_TIME ltime; - if (get_date(<ime, TIME_FUZZY_DATE)) + if (get_date(<ime, 0)) return 0; return TIME_to_ulonglong(<ime); @@ -2897,7 +2904,7 @@ my_decimal *Item_func_min_max::val_decimal(my_decimal *dec) if (compare_as_dates) { MYSQL_TIME ltime; - if (get_date(<ime, TIME_FUZZY_DATE)) + if (get_date(<ime, 0)) return 0; return date2my_decimal(<ime, dec); @@ -6076,6 +6083,13 @@ bool Item_func_match::fix_index() uint ft_to_key[MAX_KEY], ft_cnt[MAX_KEY], fts=0, keynr; uint max_cnt=0, mkeys=0, i; + /* + We will skip execution if the item is not fixed + with fix_field + */ + if (!fixed) + return false; + if (key == NO_SUCH_KEY) return 0; diff --git a/sql/item_func.h b/sql/item_func.h index bdf91810d81..bbe70724f79 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /* Function items used by mysql */ @@ -1807,7 +1807,6 @@ public: bool is_expensive_processor(uchar *arg) { return TRUE; } enum Functype functype() const { return FT_FUNC; } const char *func_name() const { return "match"; } - void update_used_tables() {} table_map not_null_tables() const { return 0; } bool fix_fields(THD *thd, Item **ref); bool eq(const Item *, bool binary_cmp) const; diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h index ee61f921adb..4d5911324ac 100644 --- a/sql/item_geofunc.h +++ b/sql/item_geofunc.h @@ -14,8 +14,8 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /* This file defines all spatial functions */ diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 1495456bda4..09518bb4bd5 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -4100,10 +4100,10 @@ bool Item_func_dyncol_create::prepare_arguments(bool force_names_arg) } break; case DYN_COL_DATETIME: - args[valpos]->get_date(&vals[i].x.time_value, TIME_FUZZY_DATE); + args[valpos]->get_date(&vals[i].x.time_value, 0); break; case DYN_COL_DATE: - args[valpos]->get_date(&vals[i].x.time_value, TIME_FUZZY_DATE); + args[valpos]->get_date(&vals[i].x.time_value, 0); break; case DYN_COL_TIME: args[valpos]->get_time(&vals[i].x.time_value); diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 9daddf94c0b..84d91a879ff 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /* This file defines all string functions */ diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 92fff032095..bed9499834a 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. +/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. Copyright (c) 2008, 2013 Monty Program Ab This program is free software; you can redistribute it and/or modify @@ -2969,9 +2969,9 @@ int group_concat_key_cmp_with_distinct(void* arg, const void* key1, for (uint i= 0; i < item_func->arg_count_field; i++) { Item *item= item_func->args[i]; - /* - If field_item is a const item then either get_tmp_table_field returns 0 - or it is an item over a const table. + /* + If item is a const item then either get_tmp_table_field returns 0 + or it is an item over a const table. */ if (item->const_item()) continue; @@ -2981,10 +2981,14 @@ int group_concat_key_cmp_with_distinct(void* arg, const void* key1, the temporary table, not the original field */ Field *field= item->get_tmp_table_field(); - int res; + + if (!field) + continue; + uint offset= (field->offset(field->table->record[0]) - field->table->s->null_bytes); - if((res= field->cmp((uchar*)key1 + offset, (uchar*)key2 + offset))) + int res= field->cmp((uchar*)key1 + offset, (uchar*)key2 + offset); + if (res) return res; } return 0; @@ -3014,27 +3018,29 @@ int group_concat_key_cmp_with_order(void* arg, const void* key1, if (item->const_item()) continue; /* + If item is a const item then either get_tmp_table_field returns 0 + or it is an item over a const table. + */ + if (item->const_item()) + continue; + /* We have to use get_tmp_table_field() instead of real_item()->get_tmp_table_field() because we want the field in the temporary table, not the original field Note that for the case of ROLLUP, field may point to another table - tham grp_item->table. This is howver ok as the table definitions are + tham grp_item->table. This is however ok as the table definitions are the same. */ Field *field= item->get_tmp_table_field(); - /* - If item is a const item then either get_tmp_table_field returns 0 - or it is an item over a const table. - */ - if (field) - { - int res; - uint offset= (field->offset(field->table->record[0]) - - field->table->s->null_bytes); - if ((res= field->cmp((uchar*)key1 + offset, (uchar*)key2 + offset))) - return (*order_item)->asc ? res : -res; - } + if (!field) + continue; + + uint offset= (field->offset(field->table->record[0]) - + field->table->s->null_bytes); + int res= field->cmp((uchar*)key1 + offset, (uchar*)key2 + offset); + if (res) + return (*order_item)->asc ? res : -res; } /* We can't return 0 because in that case the tree class would remove this @@ -3074,23 +3080,28 @@ int dump_leaf_key(void* key_arg, element_count count __attribute__((unused)), for (; arg < arg_end; arg++) { String *res; - if (! (*arg)->const_item()) + /* + We have to use get_tmp_table_field() instead of + real_item()->get_tmp_table_field() because we want the field in + the temporary table, not the original field + We also can't use table->field array to access the fields + because it contains both order and arg list fields. + */ + if ((*arg)->const_item()) + res= (*arg)->val_str(&tmp); + else { - /* - We have to use get_tmp_table_field() instead of - real_item()->get_tmp_table_field() because we want the field in - the temporary table, not the original field - We also can't use table->field array to access the fields - because it contains both order and arg list fields. - */ Field *field= (*arg)->get_tmp_table_field(); - uint offset= (field->offset(field->table->record[0]) - - table->s->null_bytes); - DBUG_ASSERT(offset < table->s->reclength); - res= field->val_str(&tmp, key + offset); + if (field) + { + uint offset= (field->offset(field->table->record[0]) - + table->s->null_bytes); + DBUG_ASSERT(offset < table->s->reclength); + res= field->val_str(&tmp, key + offset); + } + else + res= (*arg)->val_str(&tmp); } - else - res= (*arg)->val_str(&tmp); if (res) result->append(*res); } @@ -3138,11 +3149,12 @@ int dump_leaf_key(void* key_arg, element_count count __attribute__((unused)), Item_func_group_concat:: Item_func_group_concat(Name_resolution_context *context_arg, bool distinct_arg, List<Item> *select_list, - SQL_I_List<ORDER> *order_list, String *separator_arg) + const SQL_I_List<ORDER> &order_list, + String *separator_arg) :tmp_table_param(0), separator(separator_arg), tree(0), unique_filter(NULL), table(0), order(0), context(context_arg), - arg_count_order(order_list ? order_list->elements : 0), + arg_count_order(order_list.elements), arg_count_field(select_list->elements), row_count(0), distinct(distinct_arg), @@ -3182,7 +3194,7 @@ Item_func_group_concat(Name_resolution_context *context_arg, if (arg_count_order) { ORDER **order_ptr= order; - for (ORDER *order_item= order_list->first; + for (ORDER *order_item= order_list.first; order_item != NULL; order_item= order_item->next) { @@ -3230,8 +3242,14 @@ Item_func_group_concat::Item_func_group_concat(THD *thd, order= (ORDER **)(tmp + arg_count_order); for (uint i= 0; i < arg_count_order; i++, tmp++) { - memcpy(tmp, item->order[i], sizeof(ORDER)); - tmp->next= i == arg_count_order-1 ? 0 : tmp+1; + /* + Compiler generated copy constructor is used to + to copy all the members of ORDER struct. + It's also necessary to update ORDER::next pointer + so that it points to new ORDER element. + */ + new (tmp) st_order(*(item->order[i])); + tmp->next= (i + 1 == arg_count_order) ? NULL : (tmp + 1); order[i]= tmp; } } @@ -3321,12 +3339,12 @@ bool Item_func_group_concat::add() for (uint i= 0; i < arg_count_field; i++) { Item *show_item= args[i]; - if (!show_item->const_item()) - { - Field *f= show_item->get_tmp_table_field(); - if (f->is_null_in_record((const uchar*) table->record[0])) + if (show_item->const_item()) + continue; + + Field *field= show_item->get_tmp_table_field(); + if (field && field->is_null_in_record((const uchar*) table->record[0])) return 0; // Skip row if it contains null - } } null_value= FALSE; diff --git a/sql/item_sum.h b/sql/item_sum.h index 6769c47a411..e82e0ead1c2 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -1,6 +1,6 @@ #ifndef ITEM_SUM_INCLUDED #define ITEM_SUM_INCLUDED -/* Copyright (c) 2000, 2011 Oracle and/or its affiliates. +/* Copyright (c) 2000, 2013 Oracle and/or its affiliates. Copyright (c) 2008, 2013 Monty Program Ab. This program is free software; you can redistribute it and/or modify @@ -1428,7 +1428,7 @@ class Item_func_group_concat : public Item_sum public: Item_func_group_concat(Name_resolution_context *context_arg, bool is_distinct, List<Item> *is_select, - SQL_I_List<ORDER> *is_order, String *is_separator); + const SQL_I_List<ORDER> &is_order, String *is_separator); Item_func_group_concat(THD *thd, Item_func_group_concat *item); ~Item_func_group_concat(); diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index c0e623f499c..788da1a5713 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -415,8 +415,8 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, l_time->minute > 59 || l_time->second > 59) goto err; - if ((fuzzy_date & TIME_NO_ZERO_DATE) && - (l_time->year == 0 || l_time->month == 0 || l_time->day == 0)) + int was_cut; + if (check_date(l_time, fuzzy_date | TIME_INVALID_DATES, &was_cut)) goto err; if (val != val_end) @@ -780,7 +780,7 @@ longlong Item_func_to_seconds::val_int_endpoint(bool left_endp, longlong seconds; longlong days; int dummy; /* unused */ - if (get_arg0_date(<ime, TIME_FUZZY_DATE)) + if (get_arg0_date(<ime, TIME_FUZZY_DATES)) { /* got NULL, leave the incl_endp intact */ return LONGLONG_MIN; @@ -858,7 +858,7 @@ longlong Item_func_to_days::val_int_endpoint(bool left_endp, bool *incl_endp) MYSQL_TIME ltime; longlong res; int dummy; /* unused */ - if (get_arg0_date(<ime, TIME_FUZZY_DATE)) + if (get_arg0_date(<ime, 0)) { /* got NULL, leave the incl_endp intact */ return LONGLONG_MIN; @@ -866,7 +866,6 @@ longlong Item_func_to_days::val_int_endpoint(bool left_endp, bool *incl_endp) res=(longlong) calc_daynr(ltime.year,ltime.month,ltime.day); /* Set to NULL if invalid date, but keep the value */ null_value= check_date(<ime, - (ltime.year || ltime.month || ltime.day), (TIME_NO_ZERO_IN_DATE | TIME_NO_ZERO_DATE), &dummy); if (null_value) @@ -923,14 +922,14 @@ longlong Item_func_dayofmonth::val_int() { DBUG_ASSERT(fixed == 1); MYSQL_TIME ltime; - return get_arg0_date(<ime, TIME_FUZZY_DATE) ? 0 : (longlong) ltime.day; + return get_arg0_date(<ime, 0) ? 0 : (longlong) ltime.day; } longlong Item_func_month::val_int() { DBUG_ASSERT(fixed == 1); MYSQL_TIME ltime; - return get_arg0_date(<ime, TIME_FUZZY_DATE) ? 0 : (longlong) ltime.month; + return get_arg0_date(<ime, 0) ? 0 : (longlong) ltime.month; } @@ -954,7 +953,7 @@ String* Item_func_monthname::val_str(String* str) uint err; MYSQL_TIME ltime; - if ((null_value= (get_arg0_date(<ime, TIME_FUZZY_DATE) || !ltime.month))) + if ((null_value= (get_arg0_date(<ime, 0) || !ltime.month))) return (String *) 0; month_name= locale->month_names->type_names[ltime.month - 1]; @@ -972,7 +971,7 @@ longlong Item_func_quarter::val_int() { DBUG_ASSERT(fixed == 1); MYSQL_TIME ltime; - if (get_arg0_date(<ime, TIME_FUZZY_DATE)) + if (get_arg0_date(<ime, 0)) return 0; return (longlong) ((ltime.month+2)/3); } @@ -1046,7 +1045,7 @@ longlong Item_func_week::val_int() DBUG_ASSERT(fixed == 1); uint year; MYSQL_TIME ltime; - if (get_arg0_date(<ime, TIME_NO_ZERO_DATE)) + if (get_arg0_date(<ime, TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE)) return 0; return (longlong) calc_week(<ime, week_mode((uint) args[1]->val_int()), @@ -1059,7 +1058,7 @@ longlong Item_func_yearweek::val_int() DBUG_ASSERT(fixed == 1); uint year,week; MYSQL_TIME ltime; - if (get_arg0_date(<ime, TIME_NO_ZERO_DATE)) + if (get_arg0_date(<ime, TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE)) return 0; week= calc_week(<ime, (week_mode((uint) args[1]->val_int()) | WEEK_YEAR), @@ -1073,7 +1072,7 @@ longlong Item_func_weekday::val_int() DBUG_ASSERT(fixed == 1); MYSQL_TIME ltime; - if (get_arg0_date(<ime, TIME_NO_ZERO_DATE)) + if (get_arg0_date(<ime, TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE)) return 0; return (longlong) calc_weekday(calc_daynr(ltime.year, ltime.month, @@ -1115,7 +1114,7 @@ longlong Item_func_year::val_int() { DBUG_ASSERT(fixed == 1); MYSQL_TIME ltime; - return get_arg0_date(<ime, TIME_FUZZY_DATE) ? 0 : (longlong) ltime.year; + return get_arg0_date(<ime, 0) ? 0 : (longlong) ltime.year; } @@ -1147,7 +1146,7 @@ longlong Item_func_year::val_int_endpoint(bool left_endp, bool *incl_endp) { DBUG_ASSERT(fixed == 1); MYSQL_TIME ltime; - if (get_arg0_date(<ime, TIME_FUZZY_DATE)) + if (get_arg0_date(<ime, 0)) { /* got NULL, leave the incl_endp intact */ return LONGLONG_MIN; @@ -1190,7 +1189,7 @@ bool Item_func_unix_timestamp::get_timestamp_value(my_time_t *seconds, } MYSQL_TIME ltime; - if (get_arg0_date(<ime, 0)) + if (get_arg0_date(<ime, TIME_NO_ZERO_IN_DATE)) return 1; uint error_code; @@ -1468,7 +1467,7 @@ longlong Item_temporal_func::val_int() { DBUG_ASSERT(fixed == 1); MYSQL_TIME ltime; - if (get_date(<ime, TIME_FUZZY_DATE | sql_mode)) + if (get_date(<ime, sql_mode)) return 0; longlong v= TIME_to_ulonglong(<ime); return ltime.neg ? -v : v; @@ -1479,7 +1478,7 @@ double Item_temporal_func::val_real() { DBUG_ASSERT(fixed == 1); MYSQL_TIME ltime; - if (get_date(<ime, TIME_FUZZY_DATE | sql_mode)) + if (get_date(<ime, sql_mode)) return 0; return TIME_to_double(<ime); } @@ -1859,7 +1858,7 @@ String *Item_func_date_format::val_str(String *str) int is_time_flag = is_time_format ? TIME_TIME_ONLY : 0; DBUG_ASSERT(fixed == 1); - if (get_arg0_date(&l_time, TIME_FUZZY_DATE | is_time_flag)) + if (get_arg0_date(&l_time, is_time_flag)) return 0; if (!(format = args[1]->val_str(str)) || !format->length()) @@ -2033,10 +2032,15 @@ bool Item_date_add_interval::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) { INTERVAL interval; - if (args[0]->get_date(ltime, TIME_NO_ZERO_DATE | TIME_FUZZY_DATE | TIME_NO_ZERO_IN_DATE) || + if (args[0]->get_date(ltime, 0) || get_interval_value(args[1], int_type, &interval)) return (null_value=1); + if (ltime->time_type != MYSQL_TIMESTAMP_TIME && + check_date_with_warn(ltime, TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE, + MYSQL_TIMESTAMP_ERROR)) + return (null_value=1); + if (date_sub_interval) interval.neg = !interval.neg; @@ -2129,7 +2133,7 @@ longlong Item_extract::val_int() long neg; int is_time_flag = date_value ? 0 : TIME_TIME_ONLY; - if (get_arg0_date(<ime, TIME_FUZZY_DATE | is_time_flag)) + if (get_arg0_date(<ime, is_time_flag)) return 0; neg= ltime.neg ? -1 : 1; @@ -2553,7 +2557,7 @@ bool Item_func_add_time::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) if (is_date) // TIMESTAMP function { - if (get_arg0_date(&l_time1, TIME_FUZZY_DATE) || + if (get_arg0_date(&l_time1, 0) || args[1]->get_time(&l_time2) || l_time1.time_type == MYSQL_TIMESTAMP_TIME || l_time2.time_type != MYSQL_TIMESTAMP_TIME) diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 3f58fe09af1..8a8419c7bd8 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /* Function items used by mysql */ diff --git a/sql/lex_symbol.h b/sql/lex_symbol.h index 000c0709071..5f3c70a50a4 100644 --- a/sql/lex_symbol.h +++ b/sql/lex_symbol.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /* This struct includes all reserved words and functions */ diff --git a/sql/log.cc b/sql/log.cc index 69447503c47..1a3b651f76f 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** @@ -3821,7 +3821,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd, bool create_new_log) for (;;) { - if ((error= my_delete_allow_opened(linfo.log_file_name, MYF(0))) != 0) + if ((error= my_delete(linfo.log_file_name, MYF(0))) != 0) { if (my_errno == ENOENT) { @@ -3857,7 +3857,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd, bool create_new_log) /* Start logging with a new file */ close(LOG_CLOSE_INDEX | LOG_CLOSE_TO_BE_OPENED); - if ((error= my_delete_allow_opened(index_file_name, MYF(0)))) // Reset (open will update) + if ((error= my_delete(index_file_name, MYF(0)))) // Reset (open will update) { if (my_errno == ENOENT) { diff --git a/sql/log_event.cc b/sql/log_event.cc index 6f56d1d53b9..4a92414c548 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -6965,6 +6965,12 @@ int Xid_log_event::do_apply_event(Relay_log_info const *rli) thd->is_slave_error= 1; return err; } + + DBUG_EXECUTE_IF("gtid_fail_after_record_gtid", + { my_error(ER_ERROR_DURING_COMMIT, MYF(0), HA_ERR_WRONG_COMMAND); + thd->is_slave_error= 1; + return 1; + }); } /* For a slave Xid_log_event is COMMIT */ @@ -7122,7 +7128,7 @@ User_var_log_event(const char* buf, uint event_len, const Format_description_log_event* description_event) :Log_event(buf, description_event) #ifndef MYSQL_CLIENT - , deferred(false) + , deferred(false), query_id(0) #endif { bool error= false; @@ -7406,12 +7412,18 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli) Item *it= 0; CHARSET_INFO *charset; DBUG_ENTER("User_var_log_event::do_apply_event"); + query_id_t sav_query_id= 0; /* memorize orig id when deferred applying */ if (rli->deferred_events_collecting) { - set_deferred(); + set_deferred(current_thd->query_id); DBUG_RETURN(rli->deferred_events->add(this)); } + else if (is_deferred()) + { + sav_query_id= current_thd->query_id; + current_thd->query_id= query_id; /* recreating original time context */ + } if (!(charset= get_charset(charset_number, MYF(MY_WME)))) DBUG_RETURN(1); @@ -7485,6 +7497,8 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli) (flags & User_var_log_event::UNSIGNED_F)); if (!is_deferred()) free_root(thd->mem_root, 0); + else + current_thd->query_id= sav_query_id; /* restore current query's context */ DBUG_RETURN(0); } @@ -8163,7 +8177,7 @@ int Append_block_log_event::do_apply_event(Relay_log_info const *rli) DBUG_EXECUTE_IF("remove_slave_load_file_before_write", { - my_delete_allow_opened(fname, MYF(0)); + my_delete(fname, MYF(0)); }); if (mysql_file_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP))) @@ -10896,6 +10910,8 @@ Write_rows_log_event::do_exec_row(const Relay_log_info *const rli) #ifdef MYSQL_CLIENT void Write_rows_log_event::print(FILE *file, PRINT_EVENT_INFO* print_event_info) { + DBUG_EXECUTE_IF("simulate_cache_read_error", + {DBUG_SET("+d,simulate_my_b_fill_error");}); Rows_log_event::print_helper(file, print_event_info, "Write_rows"); } #endif diff --git a/sql/log_event.h b/sql/log_event.h index b54e2028ef2..b73c0e71f77 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -2814,6 +2814,7 @@ public: uchar flags; #ifdef MYSQL_SERVER bool deferred; + query_id_t query_id; User_var_log_event(THD* thd_arg, char *name_arg, uint name_len_arg, char *val_arg, ulong val_len_arg, Item_result type_arg, uint charset_number_arg, uchar flags_arg, @@ -2844,7 +2845,11 @@ public: and which case the applier adjusts execution path. */ bool is_deferred() { return deferred; } - void set_deferred() { deferred= true; } + /* + In case of the deffered applying the variable instance is flagged + and the parsing time query id is stored to be used at applying time. + */ + void set_deferred(query_id_t qid) { deferred= true; query_id= qid; } #endif bool is_valid() const { return name != 0; } diff --git a/sql/log_event_old.h b/sql/log_event_old.h index 3e1efd8e2c0..0034bb9d142 100644 --- a/sql/log_event_old.h +++ b/sql/log_event_old.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef LOG_EVENT_OLD_H #define LOG_EVENT_OLD_H diff --git a/sql/mem_root_array.h b/sql/mem_root_array.h index 5ce4dcb584d..9dc9638c13f 100644 --- a/sql/mem_root_array.h +++ b/sql/mem_root_array.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef MEM_ROOT_ARRAY_INCLUDED diff --git a/sql/multi_range_read.cc b/sql/multi_range_read.cc index 3ea65b16e3d..3aee7936b79 100644 --- a/sql/multi_range_read.cc +++ b/sql/multi_range_read.cc @@ -1114,6 +1114,7 @@ void DsMrr_impl::close_second_handler() { if (secondary_file) { + secondary_file->extra(HA_EXTRA_NO_KEYREAD); secondary_file->ha_index_or_rnd_end(); secondary_file->ha_external_lock(current_thd, F_UNLCK); secondary_file->ha_close(); diff --git a/sql/my_decimal.h b/sql/my_decimal.h index 3b104bbdee6..e561d180d12 100644 --- a/sql/my_decimal.h +++ b/sql/my_decimal.h @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** @file diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d28bdea9d20..2cf0dddd1aa 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "sql_plugin.h" #include "sql_priv.h" @@ -1906,7 +1906,7 @@ static void mysqld_exit(int exit_code) clean_up_error_log_mutex(); my_end((opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0)); #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE - shutdown_performance_schema(); + shutdown_performance_schema(); // we do it as late as possible #endif DBUG_LEAVE; exit(exit_code); /* purecov: inspected */ @@ -1943,8 +1943,8 @@ void clean_up(bool print_message) my_tz_free(); my_dboptions_cache_free(); ignore_db_dirs_free(); -#ifndef NO_EMBEDDED_ACCESS_CHECKS servers_free(1); +#ifndef NO_EMBEDDED_ACCESS_CHECKS acl_free(1); grant_free(); #endif @@ -3603,6 +3603,7 @@ SHOW_VAR com_status_vars[]= { {"show_user_statistics", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_USER_STATS]), SHOW_LONG_STATUS}, {"show_variables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_VARIABLES]), SHOW_LONG_STATUS}, {"show_warnings", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_WARNS]), SHOW_LONG_STATUS}, + {"shutdown", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHUTDOWN]), SHOW_LONG_STATUS}, {"start_all_slaves", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_ALL_START]), SHOW_LONG_STATUS}, {"start_slave", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_START]), SHOW_LONG_STATUS}, {"stmt_close", (char*) offsetof(STATUS_VAR, com_stmt_close), SHOW_LONG_STATUS}, @@ -4745,7 +4746,7 @@ a file name for --log-bin-index option", opt_binlog_index_name); plugin_ref plugin; handlerton *hton; if ((plugin= ha_resolve_by_name(0, &name))) - hton= plugin_data(plugin, handlerton*); + hton= plugin_hton(plugin); else { sql_print_error("Unknown/unsupported storage engine: %s", @@ -4845,6 +4846,8 @@ a file name for --log-bin-index option", opt_binlog_index_name); init_update_queries(); init_global_user_stats(); init_global_client_stats(); + if (!opt_bootstrap) + servers_init(0); DBUG_RETURN(0); } @@ -5263,9 +5266,6 @@ int mysqld_main(int argc, char **argv) if (!opt_noacl) (void) grant_init(); - if (!opt_bootstrap) - servers_init(0); - if (!opt_noacl) { #ifdef HAVE_DLOPEN diff --git a/sql/net_serv.cc b/sql/net_serv.cc index b6890ab9fda..93ca14337f5 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** @file diff --git a/sql/opt_range.cc b/sql/opt_range.cc index e8213ea8dd6..75142e87f98 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1,5 +1,5 @@ -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. - Copyright (c) 2008-2011 Monty Program Ab +/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. + Copyright (c) 2008, 2013, Monty Program Ab. 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 @@ -844,8 +844,17 @@ public: /* Number of SEL_ARG objects allocated by SEL_ARG::clone_tree operations */ uint alloced_sel_args; + bool force_default_mrr; KEY_PART *key[MAX_KEY]; /* First key parts of keys used in the query */ + + bool statement_should_be_aborted() const + { + return + thd->is_fatal_error || + thd->is_error() || + alloced_sel_args > SEL_ARG::MAX_SEL_ARGS; + } }; class PARAM : public RANGE_OPT_PARAM @@ -2074,30 +2083,16 @@ end: org_key_read= head->key_read; head->file= file; head->key_read= 0; + head->mark_columns_used_by_index_no_reset(index, head->read_set); + if (!head->no_keyread) { doing_key_read= 1; - head->mark_columns_used_by_index_no_reset(index, head->read_set); head->enable_keyread(); } head->prepare_for_position(); - if (head->no_keyread) - { - /* - We can get here when doing multi-table delete and having index_merge - condition on a table that we're deleting from. It probably doesn't make - sense to use index_merge, but de-facto it is used. - - When it is used, we need to index columns to be read (before maria-5.3, - read_multi_range_first() would set it). - We shouldn't call mark_columns_used_by_index(), because it calls - enable_keyread(), which is not allowed. - */ - head->mark_columns_used_by_index_no_reset(index, head->read_set); - } - head->file= org_file; head->key_read= org_key_read; @@ -3609,6 +3604,44 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item *cond) /**************************************************************************** * Partition pruning module ****************************************************************************/ + +/* + Store field key image to table record + + SYNOPSIS + store_key_image_to_rec() + field Field which key image should be stored + ptr Field value in key format + len Length of the value, in bytes + + DESCRIPTION + Copy the field value from its key image to the table record. The source + is the value in key image format, occupying len bytes in buffer pointed + by ptr. The destination is table record, in "field value in table record" + format. +*/ + +void store_key_image_to_rec(Field *field, uchar *ptr, uint len) +{ + /* Do the same as print_key() does */ + my_bitmap_map *old_map; + + if (field->real_maybe_null()) + { + if (*ptr) + { + field->set_null(); + return; + } + field->set_notnull(); + ptr++; + } + old_map= dbug_tmp_use_all_columns(field->table, + field->table->write_set); + field->set_key_image(ptr, len); + dbug_tmp_restore_column_map(field->table->write_set, old_map); +} + #ifdef WITH_PARTITION_STORAGE_ENGINE /* @@ -3944,44 +3977,6 @@ end: /* - Store field key image to table record - - SYNOPSIS - store_key_image_to_rec() - field Field which key image should be stored - ptr Field value in key format - len Length of the value, in bytes - - DESCRIPTION - Copy the field value from its key image to the table record. The source - is the value in key image format, occupying len bytes in buffer pointed - by ptr. The destination is table record, in "field value in table record" - format. -*/ - -void store_key_image_to_rec(Field *field, uchar *ptr, uint len) -{ - /* Do the same as print_key() does */ - my_bitmap_map *old_map; - - if (field->real_maybe_null()) - { - if (*ptr) - { - field->set_null(); - return; - } - field->set_notnull(); - ptr++; - } - old_map= dbug_tmp_use_all_columns(field->table, - field->table->write_set); - field->set_key_image(ptr, len); - dbug_tmp_restore_column_map(field->table->write_set, old_map); -} - - -/* For SEL_ARG* array, store sel_arg->min values into table record buffer SYNOPSIS @@ -5326,6 +5321,8 @@ TABLE_READ_PLAN *merge_same_index_scans(PARAM *param, SEL_IMERGE *imerge, bzero((*changed_tree)->keys, sizeof((*changed_tree)->keys[0])*param->keys); (*changed_tree)->keys_map.clear_all(); + key->incr_refs(); + (*tree)->keys[key_idx]->incr_refs(); if (((*changed_tree)->keys[key_idx]= key_or(param, key, (*tree)->keys[key_idx]))) (*changed_tree)->keys_map.set_bit(key_idx); @@ -7531,6 +7528,34 @@ static SEL_TREE *get_func_mm_tree(RANGE_OPT_PARAM *param, Item_func *cond_func, { new_interval->min_value= last_val->max_value; new_interval->min_flag= NEAR_MIN; + + /* + If the interval is over a partial keypart, the + interval must be "c_{i-1} <= X < c_i" instead of + "c_{i-1} < X < c_i". Reason: + + Consider a table with a column "my_col VARCHAR(3)", + and an index with definition + "INDEX my_idx my_col(1)". If the table contains rows + with my_col values "f" and "foo", the index will not + distinguish the two rows. + + Note that tree_or() below will effectively merge + this range with the range created for c_{i-1} and + we'll eventually end up with only one range: + "NULL < X". + + Partitioning indexes are never partial. + */ + if (param->using_real_indexes) + { + const KEY key= + param->table->key_info[param->real_keynr[idx]]; + const KEY_PART_INFO *kpi= key.key_part + new_interval->part; + + if (kpi->key_part_flag & HA_PART_KEY_SEG) + new_interval->min_flag= 0; + } } } /* @@ -7743,34 +7768,35 @@ static SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param,COND *cond) if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC) { - tree=0; + tree= NULL; Item *item; while ((item=li++)) { - SEL_TREE *new_tree=get_mm_tree(param,item); - if (param->thd->is_fatal_error || - param->alloced_sel_args > SEL_ARG::MAX_SEL_ARGS) - DBUG_RETURN(0); // out of memory - tree=tree_and(param,tree,new_tree); - if (tree && tree->type == SEL_TREE::IMPOSSIBLE) - break; + SEL_TREE *new_tree= get_mm_tree(param,item); + if (param->statement_should_be_aborted()) + DBUG_RETURN(NULL); + tree= tree_and(param,tree,new_tree); + if (tree && tree->type == SEL_TREE::IMPOSSIBLE) + break; } } else - { // COND OR - tree=get_mm_tree(param,li++); + { // COND OR + tree= get_mm_tree(param,li++); + if (param->statement_should_be_aborted()) + DBUG_RETURN(NULL); if (tree) { - Item *item; - while ((item=li++)) - { - SEL_TREE *new_tree=get_mm_tree(param,item); - if (!new_tree) - DBUG_RETURN(0); // out of memory - tree=tree_or(param,tree,new_tree); - if (!tree || tree->type == SEL_TREE::ALWAYS) - break; - } + Item *item; + while ((item=li++)) + { + SEL_TREE *new_tree=get_mm_tree(param,item); + if (new_tree == NULL || param->statement_should_be_aborted()) + DBUG_RETURN(NULL); + tree= tree_or(param,tree,new_tree); + if (tree == NULL || tree->type == SEL_TREE::ALWAYS) + break; + } } } DBUG_RETURN(tree); @@ -8024,6 +8050,7 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field, if (key_part->image_type == Field::itMBR) { + // @todo: use is_spatial_operator() instead? switch (type) { case Item_func::SP_EQUALS_FUNC: case Item_func::SP_DISJOINT_FUNC: @@ -10993,12 +11020,13 @@ int read_keys_and_merge_scans(THD *thd, Unique *unique= *unique_ptr; handler *file= head->file; bool with_cpk_filter= pk_quick_select != NULL; - + bool enabled_keyread= 0; DBUG_ENTER("read_keys_and_merge"); /* We're going to just read rowids. */ if (!head->key_read) { + enabled_keyread= 1; head->enable_keyread(); } head->prepare_for_position(); @@ -11092,13 +11120,15 @@ int read_keys_and_merge_scans(THD *thd, /* index merge currently doesn't support "using index" at all */ - head->disable_keyread(); + if (enabled_keyread) + head->disable_keyread(); if (init_read_record(read_record, thd, head, (SQL_SELECT*) 0, 1 , 1, TRUE)) result= 1; DBUG_RETURN(result); err: - head->disable_keyread(); + if (enabled_keyread) + head->disable_keyread(); DBUG_RETURN(1); } @@ -13584,7 +13614,11 @@ QUICK_GROUP_MIN_MAX_SELECT::~QUICK_GROUP_MIN_MAX_SELECT() DBUG_ASSERT(file == head->file); if (doing_key_read) head->disable_keyread(); - file->ha_index_end(); + /* + There may be a code path when the same table was first accessed by index, + then the index is closed, and the table is scanned (order by + loose scan). + */ + file->ha_index_or_rnd_end(); } if (min_max_arg_part) delete_dynamic(&min_max_ranges); diff --git a/sql/opt_range.h b/sql/opt_range.h index ddaa5c5e59a..ccddd40686c 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -1046,8 +1046,8 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item *cond); #ifdef WITH_PARTITION_STORAGE_ENGINE bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond); -void store_key_image_to_rec(Field *field, uchar *ptr, uint len); #endif +void store_key_image_to_rec(Field *field, uchar *ptr, uint len); extern String null_string; diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 34e705d3218..28d802375e2 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -4114,7 +4114,7 @@ SJ_TMP_TABLE::create_sj_weedout_tmp_table(THD *thd) recinfo++; if (share->db_type() == TMP_ENGINE_HTON) { - if (create_internal_tmp_table(table, keyinfo, start_recinfo, &recinfo, 0, 0)) + if (create_internal_tmp_table(table, keyinfo, start_recinfo, &recinfo, 0)) goto err; } if (open_tmp_table(table)) @@ -4234,9 +4234,13 @@ int SJ_TMP_TABLE::sj_weedout_check_row(THD *thd) /* create_internal_tmp_table_from_heap will generate error if needed */ if (!tmp_table->file->is_fatal_error(error, HA_CHECK_DUP)) DBUG_RETURN(1); /* Duplicate */ + + bool is_duplicate; if (create_internal_tmp_table_from_heap(thd, tmp_table, start_recinfo, - &recinfo, error, 1)) + &recinfo, error, 1, &is_duplicate)) DBUG_RETURN(-1); + if (is_duplicate) + DBUG_RETURN(1); } DBUG_RETURN(0); } diff --git a/sql/protocol.cc b/sql/protocol.cc index 1e257b5a282..be16d8c3ed8 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -1546,14 +1546,14 @@ bool Protocol_binary::send_out_parameters(List<Item_param> *sp_params) /* Restore THD::server_status. */ thd->server_status&= ~SERVER_PS_OUT_PARAMS; + /* Send EOF-packet. */ + net_send_eof(thd, thd->server_status, 0); + /* Reset SERVER_MORE_RESULTS_EXISTS bit, because this is the last packet for sure. */ thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS; - /* Send EOF-packet. */ - net_send_eof(thd, thd->server_status, 0); - return FALSE; } diff --git a/sql/rpl_filter.cc b/sql/rpl_filter.cc index 2e7a2242d45..72e7770b6ee 100644 --- a/sql/rpl_filter.cc +++ b/sql/rpl_filter.cc @@ -156,14 +156,15 @@ Rpl_filter::db_ok(const char* db) DBUG_RETURN(1); // Ok to replicate if the user puts no constraints /* - If the user has specified restrictions on which databases to replicate - and db was not selected, do not replicate. + Previous behaviour "if the user has specified restrictions on which + databases to replicate and db was not selected, do not replicate" has + been replaced with "do replicate". + Since the filtering criteria is not equal to "NULL" the statement should + be logged into binlog. */ if (!db) - { - DBUG_PRINT("exit", ("Don't replicate")); - DBUG_RETURN(0); - } + DBUG_RETURN(1); + if (!do_db.is_empty()) // if the do's are not empty { I_List_iterator<i_string> it(do_db); diff --git a/sql/rpl_gtid.cc b/sql/rpl_gtid.cc index d5e9380296e..4783fb763c8 100644 --- a/sql/rpl_gtid.cc +++ b/sql/rpl_gtid.cc @@ -311,6 +311,18 @@ rpl_slave_state::record_gtid(THD *thd, const rpl_gtid *gtid, uint64 sub_id, ulonglong thd_saved_option= thd->variables.option_bits; Query_tables_list lex_backup; + if (unlikely(!loaded)) + { + /* + Probably the mysql.gtid_slave_pos table is missing (eg. upgrade) or + corrupt. + + We already complained loudly about this, but we can try to continue + until the DBA fixes it. + */ + return 0; + } + if (!in_statement) mysql_reset_thd_for_next_command(thd, 0); @@ -351,6 +363,14 @@ rpl_slave_state::record_gtid(THD *thd, const rpl_gtid *gtid, uint64 sub_id, goto end; } + if(opt_bin_log && + (err= mysql_bin_log.bump_seq_no_counter_if_needed(gtid->domain_id, + gtid->seq_no))) + { + my_error(ER_OUT_OF_RESOURCES, MYF(0)); + goto end; + } + lock(); if ((elem= get_element(gtid->domain_id)) == NULL) { @@ -359,7 +379,30 @@ rpl_slave_state::record_gtid(THD *thd, const rpl_gtid *gtid, uint64 sub_id, err= 1; goto end; } - elist= elem->grab_list(); + if ((elist= elem->grab_list()) != NULL) + { + /* Delete any old stuff, but keep around the most recent one. */ + list_element *cur= elist; + uint64 best_sub_id= cur->sub_id; + list_element **best_ptr_ptr= &elist; + while ((next= cur->next)) + { + if (next->sub_id > best_sub_id) + { + best_sub_id= next->sub_id; + best_ptr_ptr= &cur->next; + } + cur= next; + } + /* + Delete the highest sub_id element from the old list, and put it back as + the single-element new list. + */ + cur= *best_ptr_ptr; + *best_ptr_ptr= cur->next; + cur->next= NULL; + elem->list= cur; + } unlock(); if (!elist) @@ -381,7 +424,7 @@ rpl_slave_state::record_gtid(THD *thd, const rpl_gtid *gtid, uint64 sub_id, DBUG_EXECUTE_IF("gtid_slave_pos_simulate_failed_delete", { err= ENOENT; table->file->print_error(err, MYF(0)); - /* `break' does not work in DBUG_EXECUTE_IF */ + /* `break' does not work inside DBUG_EXECUTE_IF */ goto dbug_break; }); next= elist->next; @@ -408,11 +451,6 @@ rpl_slave_state::record_gtid(THD *thd, const rpl_gtid *gtid, uint64 sub_id, IF_DBUG(dbug_break:, ) table->file->ha_index_end(); - if(!err && opt_bin_log && - (err= mysql_bin_log.bump_seq_no_counter_if_needed(gtid->domain_id, - gtid->seq_no))) - my_error(ER_OUT_OF_RESOURCES, MYF(0)); - end: if (table_opened) @@ -450,9 +488,9 @@ end: uint64 -rpl_slave_state::next_subid(uint32 domain_id) +rpl_slave_state::next_sub_id(uint32 domain_id) { - uint32 sub_id= 0; + uint64 sub_id= 0; element *elem; lock(); @@ -710,7 +748,7 @@ rpl_slave_state::load(THD *thd, char *state_from_master, size_t len, uint64 sub_id; if (gtid_parser_helper(&state_from_master, end, >id) || - !(sub_id= next_subid(gtid.domain_id)) || + !(sub_id= next_sub_id(gtid.domain_id)) || record_gtid(thd, >id, sub_id, false, in_statement) || update(gtid.domain_id, gtid.server_id, sub_id, gtid.seq_no)) return 1; diff --git a/sql/rpl_gtid.h b/sql/rpl_gtid.h index 4d5302020bf..1a94ee76eca 100644 --- a/sql/rpl_gtid.h +++ b/sql/rpl_gtid.h @@ -92,7 +92,7 @@ struct rpl_slave_state int truncate_state_table(THD *thd); int record_gtid(THD *thd, const rpl_gtid *gtid, uint64 sub_id, bool in_transaction, bool in_statement); - uint64 next_subid(uint32 domain_id); + uint64 next_sub_id(uint32 domain_id); int iterate(int (*cb)(rpl_gtid *, void *), void *data, rpl_gtid *extra_gtids, uint32 num_extra); int tostring(String *dest, rpl_gtid *extra_gtids, uint32 num_extra); diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 7c8396ceaae..a455779bb6e 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -1387,9 +1387,11 @@ rpl_load_gtid_slave_state(THD *thd) TABLE *table; bool table_opened= false; bool table_scanned= false; + bool array_inited= false; struct local_element { uint64 sub_id; rpl_gtid gtid; }; - struct local_element *entry; + struct local_element tmp_entry, *entry; HASH hash; + DYNAMIC_ARRAY array; int err= 0; uint32 i; DBUG_ENTER("rpl_load_gtid_slave_state"); @@ -1403,6 +1405,9 @@ rpl_load_gtid_slave_state(THD *thd) my_hash_init(&hash, &my_charset_bin, 32, offsetof(local_element, gtid) + offsetof(rpl_gtid, domain_id), sizeof(uint32), NULL, my_free, HASH_UNIQUE); + if ((err= my_init_dynamic_array(&array, sizeof(local_element), 0, 0, MYF(0)))) + goto end; + array_inited= true; mysql_reset_thd_for_next_command(thd, 0); @@ -1451,6 +1456,16 @@ rpl_load_gtid_slave_state(THD *thd) (unsigned)domain_id, (unsigned)server_id, (ulong)seq_no, (ulong)sub_id)); + tmp_entry.sub_id= sub_id; + tmp_entry.gtid.domain_id= domain_id; + tmp_entry.gtid.server_id= server_id; + tmp_entry.gtid.seq_no= seq_no; + if ((err= insert_dynamic(&array, (uchar *)&tmp_entry))) + { + my_error(ER_OUT_OF_RESOURCES, MYF(0)); + goto end; + } + if ((rec= my_hash_search(&hash, (const uchar *)&domain_id, 0))) { entry= (struct local_element *)rec; @@ -1489,18 +1504,24 @@ rpl_load_gtid_slave_state(THD *thd) rpl_global_gtid_slave_state.unlock(); goto end; } - for (i= 0; i < hash.records; ++i) + + for (i= 0; i < array.elements; ++i) { - entry= (struct local_element *)my_hash_element(&hash, i); - if ((err= rpl_global_gtid_slave_state.update(entry->gtid.domain_id, - entry->gtid.server_id, - entry->sub_id, - entry->gtid.seq_no))) + get_dynamic(&array, (uchar *)&tmp_entry, i); + if ((err= rpl_global_gtid_slave_state.update(tmp_entry.gtid.domain_id, + tmp_entry.gtid.server_id, + tmp_entry.sub_id, + tmp_entry.gtid.seq_no))) { rpl_global_gtid_slave_state.unlock(); my_error(ER_OUT_OF_RESOURCES, MYF(0)); goto end; } + } + + for (i= 0; i < hash.records; ++i) + { + entry= (struct local_element *)my_hash_element(&hash, i); if (opt_bin_log && mysql_bin_log.bump_seq_no_counter_if_needed(entry->gtid.domain_id, entry->gtid.seq_no)) @@ -1510,6 +1531,7 @@ rpl_load_gtid_slave_state(THD *thd) goto end; } } + rpl_global_gtid_slave_state.loaded= true; rpl_global_gtid_slave_state.unlock(); @@ -1527,6 +1549,8 @@ end: close_thread_tables(thd); thd->mdl_context.release_transactional_locks(); } + if (array_inited) + delete_dynamic(&array); my_hash_free(&hash); DBUG_RETURN(err); } diff --git a/sql/set_var.h b/sql/set_var.h index 87a2988bc3d..f248dc2894f 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -13,7 +13,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** @file diff --git a/sql/share/charsets/Index.xml b/sql/share/charsets/Index.xml index f32d8bf6127..e82ffc85ea6 100644 --- a/sql/share/charsets/Index.xml +++ b/sql/share/charsets/Index.xml @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA </copyright> <description> diff --git a/sql/share/charsets/armscii8.xml b/sql/share/charsets/armscii8.xml index 714e57bb12e..52382c83af0 100644 --- a/sql/share/charsets/armscii8.xml +++ b/sql/share/charsets/armscii8.xml @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA </copyright> <charset name="armscii8"> diff --git a/sql/share/charsets/ascii.xml b/sql/share/charsets/ascii.xml index f4fb79ac632..bec34ad525e 100644 --- a/sql/share/charsets/ascii.xml +++ b/sql/share/charsets/ascii.xml @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA </copyright> <charset name="ascii"> diff --git a/sql/share/charsets/cp1250.xml b/sql/share/charsets/cp1250.xml index bd0d7d3f3c0..58e55de9bdc 100644 --- a/sql/share/charsets/cp1250.xml +++ b/sql/share/charsets/cp1250.xml @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA </copyright> <charset name="cp1250"> diff --git a/sql/share/charsets/cp1256.xml b/sql/share/charsets/cp1256.xml index 64cb253145c..806fef961f7 100644 --- a/sql/share/charsets/cp1256.xml +++ b/sql/share/charsets/cp1256.xml @@ -18,7 +18,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA </copyright> <charset name="cp1256"> diff --git a/sql/share/charsets/cp1257.xml b/sql/share/charsets/cp1257.xml index 0c2688c264e..8ae73fdf25a 100644 --- a/sql/share/charsets/cp1257.xml +++ b/sql/share/charsets/cp1257.xml @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA </copyright> <charset name="cp1257"> diff --git a/sql/share/charsets/cp850.xml b/sql/share/charsets/cp850.xml index 4076a5f6a56..198b336daef 100644 --- a/sql/share/charsets/cp850.xml +++ b/sql/share/charsets/cp850.xml @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA </copyright> <charset name="cp850"> diff --git a/sql/share/charsets/cp852.xml b/sql/share/charsets/cp852.xml index 25b622d2a4b..7608296d5b7 100644 --- a/sql/share/charsets/cp852.xml +++ b/sql/share/charsets/cp852.xml @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA </copyright> <charset name="cp852"> diff --git a/sql/share/charsets/cp866.xml b/sql/share/charsets/cp866.xml index fa2e1865de6..d35f3d68b05 100644 --- a/sql/share/charsets/cp866.xml +++ b/sql/share/charsets/cp866.xml @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA </copyright> <charset name="cp866"> diff --git a/sql/share/charsets/dec8.xml b/sql/share/charsets/dec8.xml index 2cd52de464a..66bb421b674 100644 --- a/sql/share/charsets/dec8.xml +++ b/sql/share/charsets/dec8.xml @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA </copyright> <charset name="dec8"> diff --git a/sql/share/charsets/geostd8.xml b/sql/share/charsets/geostd8.xml index 5e3816975d6..a789d07e6d8 100644 --- a/sql/share/charsets/geostd8.xml +++ b/sql/share/charsets/geostd8.xml @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA </copyright> <charset name="geostd8"> diff --git a/sql/share/charsets/greek.xml b/sql/share/charsets/greek.xml index 000019a8ce0..5b66a7ab442 100644 --- a/sql/share/charsets/greek.xml +++ b/sql/share/charsets/greek.xml @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA </copyright> <charset name="greek"> diff --git a/sql/share/charsets/hebrew.xml b/sql/share/charsets/hebrew.xml index 20d68487301..e7f896a3e12 100644 --- a/sql/share/charsets/hebrew.xml +++ b/sql/share/charsets/hebrew.xml @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA </copyright> <charset name="hebrew"> diff --git a/sql/share/charsets/hp8.xml b/sql/share/charsets/hp8.xml index 3ab383ef386..83a076237f7 100644 --- a/sql/share/charsets/hp8.xml +++ b/sql/share/charsets/hp8.xml @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA </copyright> <charset name="hp8"> diff --git a/sql/share/charsets/keybcs2.xml b/sql/share/charsets/keybcs2.xml index 7335a0f428d..a9f305deab8 100644 --- a/sql/share/charsets/keybcs2.xml +++ b/sql/share/charsets/keybcs2.xml @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA </copyright> <charset name="keybcs2"> diff --git a/sql/share/charsets/koi8r.xml b/sql/share/charsets/koi8r.xml index 2d8473f6440..21ebf78b79e 100644 --- a/sql/share/charsets/koi8r.xml +++ b/sql/share/charsets/koi8r.xml @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA </copyright> <charset name="koi8r"> diff --git a/sql/share/charsets/koi8u.xml b/sql/share/charsets/koi8u.xml index 16177627ffe..65145c97593 100644 --- a/sql/share/charsets/koi8u.xml +++ b/sql/share/charsets/koi8u.xml @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA </copyright> <charset name="koi8u"> diff --git a/sql/share/charsets/languages.html b/sql/share/charsets/languages.html index 76af973113e..2b1c44421bf 100644 --- a/sql/share/charsets/languages.html +++ b/sql/share/charsets/languages.html @@ -13,7 +13,7 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA #<pre> ( diff --git a/sql/share/charsets/latin1.xml b/sql/share/charsets/latin1.xml index 88ceff440d5..8963c3481d3 100644 --- a/sql/share/charsets/latin1.xml +++ b/sql/share/charsets/latin1.xml @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA </copyright> <charset name="latin1"> diff --git a/sql/share/charsets/latin2.xml b/sql/share/charsets/latin2.xml index 6b887b927a4..183da7b6cd3 100644 --- a/sql/share/charsets/latin2.xml +++ b/sql/share/charsets/latin2.xml @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA </copyright> <charset name="latin2"> diff --git a/sql/share/charsets/latin5.xml b/sql/share/charsets/latin5.xml index 9c23200a46d..489299564f1 100644 --- a/sql/share/charsets/latin5.xml +++ b/sql/share/charsets/latin5.xml @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA </copyright> <charset name="latin5"> diff --git a/sql/share/charsets/latin7.xml b/sql/share/charsets/latin7.xml index 02d3ff8b17e..fb384b3a5ff 100644 --- a/sql/share/charsets/latin7.xml +++ b/sql/share/charsets/latin7.xml @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA </copyright> <charset name="latin7"> diff --git a/sql/share/charsets/macce.xml b/sql/share/charsets/macce.xml index 21e303609cf..d7242f26297 100644 --- a/sql/share/charsets/macce.xml +++ b/sql/share/charsets/macce.xml @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA </copyright> <charset name="macce"> diff --git a/sql/share/charsets/macroman.xml b/sql/share/charsets/macroman.xml index 2b43fe73b07..a2485cf9379 100644 --- a/sql/share/charsets/macroman.xml +++ b/sql/share/charsets/macroman.xml @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA </copyright> <charset name="macroman"> diff --git a/sql/share/charsets/swe7.xml b/sql/share/charsets/swe7.xml index 17fa6b7d9bc..f12a2238718 100644 --- a/sql/share/charsets/swe7.xml +++ b/sql/share/charsets/swe7.xml @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA </copyright> <charset name="swe7"> diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 5c60de14742..f62f5d917f7 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -1014,53 +1014,53 @@ ER_HANDSHAKE_ERROR 08S01 swe "Fel vid initiering av kommunikationen med klienten" ukr "Невірна установка зв'язку" ER_DBACCESS_DENIED_ERROR 42000 - cze "P-Břístup pro uživatele '%-.48s'@'%-.64s' k databázi '%-.192s' není povolen" - dan "Adgang nægtet bruger: '%-.48s'@'%-.64s' til databasen '%-.192s'" - nla "Toegang geweigerd voor gebruiker: '%-.48s'@'%-.64s' naar database '%-.192s'" - eng "Access denied for user '%-.48s'@'%-.64s' to database '%-.192s'" - jps "ユーザー '%-.48s'@'%-.64s' の '%-.192s' データベースへのアクセスを拒否します", - est "Ligipääs keelatud kasutajale '%-.48s'@'%-.64s' andmebaasile '%-.192s'" - fre "Accès refusé pour l'utilisateur: '%-.48s'@'@%-.64s'. Base '%-.192s'" - ger "Benutzer '%-.48s'@'%-.64s' hat keine Zugriffsberechtigung für Datenbank '%-.192s'" - greek "Δεν επιτέρεται η πρόσβαση στο χρήστη: '%-.48s'@'%-.64s' στη βάση δεδομένων '%-.192s'" - hun "A(z) '%-.48s'@'%-.64s' felhasznalo szamara tiltott eleres az '%-.192s' adabazishoz." - ita "Accesso non consentito per l'utente: '%-.48s'@'%-.64s' al database '%-.192s'" - jpn "ユーザー '%-.48s'@'%-.64s' の '%-.192s' データベースへのアクセスを拒否します" - kor "'%-.48s'@'%-.64s' 사용자는 '%-.192s' 데이타베이스에 접근이 거부 되었습니다." - nor "Tilgang nektet for bruker: '%-.48s'@'%-.64s' til databasen '%-.192s' nektet" - norwegian-ny "Tilgang ikkje tillate for brukar: '%-.48s'@'%-.64s' til databasen '%-.192s' nekta" - por "Acesso negado para o usuário '%-.48s'@'%-.64s' ao banco de dados '%-.192s'" - rum "Acces interzis pentru utilizatorul: '%-.48s'@'%-.64s' la baza de date '%-.192s'" - rus "Для пользователя '%-.48s'@'%-.64s' доступ к базе данных '%-.192s' закрыт" - serbian "Pristup je zabranjen korisniku '%-.48s'@'%-.64s' za bazu '%-.192s'" - slo "Zakázaný prístup pre užívateľa: '%-.48s'@'%-.64s' k databázi '%-.192s'" - spa "Acceso negado para usuario: '%-.48s'@'%-.64s' para la base de datos '%-.192s'" - swe "Användare '%-.48s'@'%-.64s' är ej berättigad att använda databasen %-.192s" - ukr "Доступ заборонено для користувача: '%-.48s'@'%-.64s' до бази данних '%-.192s'" + cze "P-Břístup pro uživatele '%s'@'%s' k databázi '%-.192s' není povolen" + dan "Adgang nægtet bruger: '%s'@'%s' til databasen '%-.192s'" + nla "Toegang geweigerd voor gebruiker: '%s'@'%s' naar database '%-.192s'" + eng "Access denied for user '%s'@'%s' to database '%-.192s'" + jps "ユーザー '%s'@'%s' の '%-.192s' データベースへのアクセスを拒否します", + est "Ligipääs keelatud kasutajale '%s'@'%s' andmebaasile '%-.192s'" + fre "Accès refusé pour l'utilisateur: '%s'@'%s'. Base '%-.192s'" + ger "Benutzer '%s'@'%s' hat keine Zugriffsberechtigung für Datenbank '%-.192s'" + greek "Δεν επιτέρεται η πρόσβαση στο χρήστη: '%s'@'%s' στη βάση δεδομένων '%-.192s'" + hun "A(z) '%s'@'%s' felhasznalo szamara tiltott eleres az '%-.192s' adabazishoz." + ita "Accesso non consentito per l'utente: '%s'@'%s' al database '%-.192s'" + jpn "ユーザー '%s'@'%s' の '%-.192s' データベースへのアクセスを拒否します" + kor "'%s'@'%s' 사용자는 '%-.192s' 데이타베이스에 접근이 거부 되었습니다." + nor "Tilgang nektet for bruker: '%s'@'%s' til databasen '%-.192s' nektet" + norwegian-ny "Tilgang ikkje tillate for brukar: '%s'@'%s' til databasen '%-.192s' nekta" + por "Acesso negado para o usuário '%s'@'%s' ao banco de dados '%-.192s'" + rum "Acces interzis pentru utilizatorul: '%s'@'%s' la baza de date '%-.192s'" + rus "Для пользователя '%s'@'%s' доступ к базе данных '%-.192s' закрыт" + serbian "Pristup je zabranjen korisniku '%s'@'%s' za bazu '%-.192s'" + slo "Zakázaný prístup pre užívateľa: '%s'@'%s' k databázi '%-.192s'" + spa "Acceso negado para usuario: '%s'@'%s' para la base de datos '%-.192s'" + swe "Användare '%s'@'%s' är ej berättigad att använda databasen %-.192s" + ukr "Доступ заборонено для користувача: '%s'@'%s' до бази данних '%-.192s'" ER_ACCESS_DENIED_ERROR 28000 - cze "P-Břístup pro uživatele '%-.48s'@'%-.64s' (s heslem %s)" - dan "Adgang nægtet bruger: '%-.48s'@'%-.64s' (Bruger adgangskode: %s)" - nla "Toegang geweigerd voor gebruiker: '%-.48s'@'%-.64s' (Wachtwoord gebruikt: %s)" - eng "Access denied for user '%-.48s'@'%-.64s' (using password: %s)" - jps "ユーザー '%-.48s'@'%-.64s' を拒否します.uUsing password: %s)", - est "Ligipääs keelatud kasutajale '%-.48s'@'%-.64s' (kasutab parooli: %s)" - fre "Accès refusé pour l'utilisateur: '%-.48s'@'@%-.64s' (mot de passe: %s)" - ger "Benutzer '%-.48s'@'%-.64s' hat keine Zugriffsberechtigung (verwendetes Passwort: %s)" - greek "Δεν επιτέρεται η πρόσβαση στο χρήστη: '%-.48s'@'%-.64s' (χρήση password: %s)" - hun "A(z) '%-.48s'@'%-.64s' felhasznalo szamara tiltott eleres. (Hasznalja a jelszot: %s)" - ita "Accesso non consentito per l'utente: '%-.48s'@'%-.64s' (Password: %s)" - jpn "ユーザー '%-.48s'@'%-.64s' を拒否します.uUsing password: %s)" - kor "'%-.48s'@'%-.64s' 사용자는 접근이 거부 되었습니다. (using password: %s)" - nor "Tilgang nektet for bruker: '%-.48s'@'%-.64s' (Bruker passord: %s)" - norwegian-ny "Tilgang ikke tillate for brukar: '%-.48s'@'%-.64s' (Brukar passord: %s)" - por "Acesso negado para o usuário '%-.48s'@'%-.64s' (senha usada: %s)" - rum "Acces interzis pentru utilizatorul: '%-.48s'@'%-.64s' (Folosind parola: %s)" - rus "Доступ закрыт для пользователя '%-.48s'@'%-.64s' (был использован пароль: %s)" - serbian "Pristup je zabranjen korisniku '%-.48s'@'%-.64s' (koristi lozinku: '%s')" - slo "Zakázaný prístup pre užívateľa: '%-.48s'@'%-.64s' (použitie hesla: %s)" - spa "Acceso negado para usuario: '%-.48s'@'%-.64s' (Usando clave: %s)" - swe "Användare '%-.48s'@'%-.64s' är ej berättigad att logga in (Använder lösen: %s)" - ukr "Доступ заборонено для користувача: '%-.48s'@'%-.64s' (Використано пароль: %s)" + cze "P-Břístup pro uživatele '%s'@'%s' (s heslem %s)" + dan "Adgang nægtet bruger: '%s'@'%s' (Bruger adgangskode: %s)" + nla "Toegang geweigerd voor gebruiker: '%s'@'%s' (Wachtwoord gebruikt: %s)" + eng "Access denied for user '%s'@'%s' (using password: %s)" + jps "ユーザー '%s'@'%s' を拒否します.uUsing password: %s)", + est "Ligipääs keelatud kasutajale '%s'@'%s' (kasutab parooli: %s)" + fre "Accès refusé pour l'utilisateur: '%s'@'%s' (mot de passe: %s)" + ger "Benutzer '%s'@'%s' hat keine Zugriffsberechtigung (verwendetes Passwort: %s)" + greek "Δεν επιτέρεται η πρόσβαση στο χρήστη: '%s'@'%s' (χρήση password: %s)" + hun "A(z) '%s'@'%s' felhasznalo szamara tiltott eleres. (Hasznalja a jelszot: %s)" + ita "Accesso non consentito per l'utente: '%s'@'%s' (Password: %s)" + jpn "ユーザー '%s'@'%s' を拒否します.uUsing password: %s)" + kor "'%s'@'%s' 사용자는 접근이 거부 되었습니다. (using password: %s)" + nor "Tilgang nektet for bruker: '%s'@'%s' (Bruker passord: %s)" + norwegian-ny "Tilgang ikke tillate for brukar: '%s'@'%s' (Brukar passord: %s)" + por "Acesso negado para o usuário '%s'@'%s' (senha usada: %s)" + rum "Acces interzis pentru utilizatorul: '%s'@'%s' (Folosind parola: %s)" + rus "Доступ закрыт для пользователя '%s'@'%s' (был использован пароль: %s)" + serbian "Pristup je zabranjen korisniku '%s'@'%s' (koristi lozinku: '%s')" + slo "Zakázaný prístup pre užívateľa: '%s'@'%s' (použitie hesla: %s)" + spa "Acceso negado para usuario: '%s'@'%s' (Usando clave: %s)" + swe "Användare '%s'@'%s' är ej berättigad att logga in (Använder lösen: %s)" + ukr "Доступ заборонено для користувача: '%s'@'%s' (Використано пароль: %s)" ER_NO_DB_ERROR 3D000 cze "Nebyla vybr-Bána žádná databáze" dan "Ingen database valgt" @@ -3243,45 +3243,45 @@ ER_NONEXISTING_GRANT 42000 swe "Det finns inget privilegium definierat för användare '%-.48s' på '%-.64s'" ukr "Повноважень не визначено для користувача '%-.48s' з хосту '%-.64s'" ER_TABLEACCESS_DENIED_ERROR 42000 - cze "%-.128s p-Bříkaz nepřístupný pro uživatele: '%-.48s'@'%-.64s' pro tabulku '%-.192s'" - dan "%-.128s-kommandoen er ikke tilladt for brugeren '%-.48s'@'%-.64s' for tabellen '%-.192s'" - nla "%-.128s commando geweigerd voor gebruiker: '%-.48s'@'%-.64s' voor tabel '%-.192s'" - eng "%-.128s command denied to user '%-.48s'@'%-.64s' for table '%-.192s'" - jps "コマンド %-.128s は ユーザー '%-.48s'@'%-.64s' ,テーブル '%-.192s' に対して許可されていません", - est "%-.128s käsk ei ole lubatud kasutajale '%-.48s'@'%-.64s' tabelis '%-.192s'" - fre "La commande '%-.128s' est interdite à l'utilisateur: '%-.48s'@'@%-.64s' sur la table '%-.192s'" - ger "%-.128s Befehl nicht erlaubt für Benutzer '%-.48s'@'%-.64s' auf Tabelle '%-.192s'" - hun "%-.128s parancs a '%-.48s'@'%-.64s' felhasznalo szamara nem engedelyezett a '%-.192s' tablaban" - ita "Comando %-.128s negato per l'utente: '%-.48s'@'%-.64s' sulla tabella '%-.192s'" - jpn "コマンド %-.128s は ユーザー '%-.48s'@'%-.64s' ,テーブル '%-.192s' に対して許可されていません" - kor "'%-.128s' 명령은 다음 사용자에게 거부되었습니다. : '%-.48s'@'%-.64s' for 테이블 '%-.192s'" - por "Comando '%-.128s' negado para o usuário '%-.48s'@'%-.64s' na tabela '%-.192s'" - rum "Comanda %-.128s interzisa utilizatorului: '%-.48s'@'%-.64s' pentru tabela '%-.192s'" - rus "Команда %-.128s запрещена пользователю '%-.48s'@'%-.64s' для таблицы '%-.192s'" - serbian "%-.128s komanda zabranjena za korisnika '%-.48s'@'%-.64s' za tabelu '%-.192s'" - spa "%-.128s comando negado para usuario: '%-.48s'@'%-.64s' para tabla '%-.192s'" - swe "%-.128s ej tillåtet för '%-.48s'@'%-.64s' för tabell '%-.192s'" - ukr "%-.128s команда заборонена користувачу: '%-.48s'@'%-.64s' у таблиці '%-.192s'" + cze "%-.32s p-Bříkaz nepřístupný pro uživatele: '%s'@'%s' pro tabulku '%-.192s'" + dan "%-.32s-kommandoen er ikke tilladt for brugeren '%s'@'%s' for tabellen '%-.192s'" + nla "%-.32s commando geweigerd voor gebruiker: '%s'@'%s' voor tabel '%-.192s'" + eng "%-.32s command denied to user '%s'@'%s' for table '%-.192s'" + jps "コマンド %-.32s は ユーザー '%s'@'%s' ,テーブル '%-.192s' に対して許可されていません", + est "%-.32s käsk ei ole lubatud kasutajale '%s'@'%s' tabelis '%-.192s'" + fre "La commande '%-.32s' est interdite à l'utilisateur: '%s'@'%s' sur la table '%-.192s'" + ger "%-.32s Befehl nicht erlaubt für Benutzer '%s'@'%s' auf Tabelle '%-.192s'" + hun "%-.32s parancs a '%s'@'%s' felhasznalo szamara nem engedelyezett a '%-.192s' tablaban" + ita "Comando %-.32s negato per l'utente: '%s'@'%s' sulla tabella '%-.192s'" + jpn "コマンド %-.32s は ユーザー '%s'@'%s' ,テーブル '%-.192s' に対して許可されていません" + kor "'%-.32s' 명령은 다음 사용자에게 거부되었습니다. : '%s'@'%s' for 테이블 '%-.192s'" + por "Comando '%-.32s' negado para o usuário '%s'@'%s' na tabela '%-.192s'" + rum "Comanda %-.32s interzisa utilizatorului: '%s'@'%s' pentru tabela '%-.192s'" + rus "Команда %-.32s запрещена пользователю '%s'@'%s' для таблицы '%-.192s'" + serbian "%-.32s komanda zabranjena za korisnika '%s'@'%s' za tabelu '%-.192s'" + spa "%-.32s comando negado para usuario: '%s'@'%s' para tabla '%-.192s'" + swe "%-.32s ej tillåtet för '%s'@'%s' för tabell '%-.192s'" + ukr "%-.32s команда заборонена користувачу: '%s'@'%s' у таблиці '%-.192s'" ER_COLUMNACCESS_DENIED_ERROR 42000 - cze "%-.128s p-Bříkaz nepřístupný pro uživatele: '%-.48s'@'%-.64s' pro sloupec '%-.192s' v tabulce '%-.192s'" - dan "%-.128s-kommandoen er ikke tilladt for brugeren '%-.48s'@'%-.64s' for kolonne '%-.192s' in tabellen '%-.192s'" - nla "%-.128s commando geweigerd voor gebruiker: '%-.48s'@'%-.64s' voor kolom '%-.192s' in tabel '%-.192s'" - eng "%-.128s command denied to user '%-.48s'@'%-.64s' for column '%-.192s' in table '%-.192s'" - jps "コマンド %-.128s は ユーザー '%-.48s'@'%-.64s'¥n カラム '%-.192s' テーブル '%-.192s' に対して許可されていません", - est "%-.128s käsk ei ole lubatud kasutajale '%-.48s'@'%-.64s' tulbale '%-.192s' tabelis '%-.192s'" - fre "La commande '%-.128s' est interdite à l'utilisateur: '%-.48s'@'@%-.64s' sur la colonne '%-.192s' de la table '%-.192s'" - ger "%-.128s Befehl nicht erlaubt für Benutzer '%-.48s'@'%-.64s' und Feld '%-.192s' in Tabelle '%-.192s'" - hun "%-.128s parancs a '%-.48s'@'%-.64s' felhasznalo szamara nem engedelyezett a '%-.192s' mezo eseten a '%-.192s' tablaban" - ita "Comando %-.128s negato per l'utente: '%-.48s'@'%-.64s' sulla colonna '%-.192s' della tabella '%-.192s'" - jpn "コマンド %-.128s は ユーザー '%-.48s'@'%-.64s'\n カラム '%-.192s' テーブル '%-.192s' に対して許可されていません" - kor "'%-.128s' 명령은 다음 사용자에게 거부되었습니다. : '%-.48s'@'%-.64s' for 칼럼 '%-.192s' in 테이블 '%-.192s'" - por "Comando '%-.128s' negado para o usuário '%-.48s'@'%-.64s' na coluna '%-.192s', na tabela '%-.192s'" - rum "Comanda %-.128s interzisa utilizatorului: '%-.48s'@'%-.64s' pentru coloana '%-.192s' in tabela '%-.192s'" - rus "Команда %-.128s запрещена пользователю '%-.48s'@'%-.64s' для столбца '%-.192s' в таблице '%-.192s'" - serbian "%-.128s komanda zabranjena za korisnika '%-.48s'@'%-.64s' za kolonu '%-.192s' iz tabele '%-.192s'" - spa "%-.128s comando negado para usuario: '%-.48s'@'%-.64s' para columna '%-.192s' en la tabla '%-.192s'" - swe "%-.128s ej tillåtet för '%-.48s'@'%-.64s' för kolumn '%-.192s' i tabell '%-.192s'" - ukr "%-.128s команда заборонена користувачу: '%-.48s'@'%-.64s' для стовбця '%-.192s' у таблиці '%-.192s'" + cze "%-.32s p-Bříkaz nepřístupný pro uživatele: '%s'@'%s' pro sloupec '%-.192s' v tabulce '%-.192s'" + dan "%-.32s-kommandoen er ikke tilladt for brugeren '%s'@'%s' for kolonne '%-.192s' in tabellen '%-.192s'" + nla "%-.32s commando geweigerd voor gebruiker: '%s'@'%s' voor kolom '%-.192s' in tabel '%-.192s'" + eng "%-.32s command denied to user '%s'@'%s' for column '%-.192s' in table '%-.192s'" + jps "コマンド %-.32s は ユーザー '%s'@'%s'¥n カラム '%-.192s' テーブル '%-.192s' に対して許可されていません", + est "%-.32s käsk ei ole lubatud kasutajale '%s'@'%s' tulbale '%-.192s' tabelis '%-.192s'" + fre "La commande '%-.32s' est interdite à l'utilisateur: '%s'@'%s' sur la colonne '%-.192s' de la table '%-.192s'" + ger "%-.32s Befehl nicht erlaubt für Benutzer '%s'@'%s' und Feld '%-.192s' in Tabelle '%-.192s'" + hun "%-.32s parancs a '%s'@'%s' felhasznalo szamara nem engedelyezett a '%-.192s' mezo eseten a '%-.192s' tablaban" + ita "Comando %-.32s negato per l'utente: '%s'@'%s' sulla colonna '%-.192s' della tabella '%-.192s'" + jpn "コマンド %-.32s は ユーザー '%s'@'%s'\n カラム '%-.192s' テーブル '%-.192s' に対して許可されていません" + kor "'%-.32s' 명령은 다음 사용자에게 거부되었습니다. : '%s'@'%s' for 칼럼 '%-.192s' in 테이블 '%-.192s'" + por "Comando '%-.32s' negado para o usuário '%s'@'%s' na coluna '%-.192s', na tabela '%-.192s'" + rum "Comanda %-.32s interzisa utilizatorului: '%s'@'%s' pentru coloana '%-.192s' in tabela '%-.192s'" + rus "Команда %-.32s запрещена пользователю '%s'@'%s' для столбца '%-.192s' в таблице '%-.192s'" + serbian "%-.32s komanda zabranjena za korisnika '%s'@'%s' za kolonu '%-.192s' iz tabele '%-.192s'" + spa "%-.32s comando negado para usuario: '%s'@'%s' para columna '%-.192s' en la tabla '%-.192s'" + swe "%-.32s ej tillåtet för '%s'@'%s' för kolumn '%-.192s' i tabell '%-.192s'" + ukr "%-.32s команда заборонена користувачу: '%s'@'%s' для стовбця '%-.192s' у таблиці '%-.192s'" ER_ILLEGAL_GRANT_FOR_TABLE 42000 cze "Neplatn-Bý příkaz GRANT/REVOKE. Prosím, přečtěte si v manuálu, jaká privilegia je možné použít." dan "Forkert GRANT/REVOKE kommando. Se i brugervejledningen hvilke privilegier der kan specificeres." @@ -4362,18 +4362,18 @@ ER_WRONG_ARGUMENTS swe "Felaktiga argument till %s" ukr "Хибний аргумент для %s" ER_NO_PERMISSION_TO_CREATE_USER 42000 - nla "'%-.48s'@'%-.64s' mag geen nieuwe gebruikers creeren" - eng "'%-.48s'@'%-.64s' is not allowed to create new users" - est "Kasutajal '%-.48s'@'%-.64s' ei ole lubatud luua uusi kasutajaid" - fre "'%-.48s'@'%-.64s' n'est pas autorisé à créer de nouveaux utilisateurs" - ger "'%-.48s'@'%-.64s' ist nicht berechtigt, neue Benutzer hinzuzufügen" - ita "A '%-.48s'@'%-.64s' non e' permesso creare nuovi utenti" - por "Não é permitido a '%-.48s'@'%-.64s' criar novos usuários" - rus "'%-.48s'@'%-.64s' не разрешается создавать новых пользователей" - serbian "Korisniku '%-.48s'@'%-.64s' nije dozvoljeno da kreira nove korisnike" - spa "'%-.48s`@`%-.64s` no es permitido para crear nuevos usuarios" - swe "'%-.48s'@'%-.64s' har inte rättighet att skapa nya användare" - ukr "Користувачу '%-.48s'@'%-.64s' не дозволено створювати нових користувачів" + nla "'%s'@'%s' mag geen nieuwe gebruikers creeren" + eng "'%s'@'%s' is not allowed to create new users" + est "Kasutajal '%s'@'%s' ei ole lubatud luua uusi kasutajaid" + fre "'%s'@'%s' n'est pas autorisé à créer de nouveaux utilisateurs" + ger "'%s'@'%s' ist nicht berechtigt, neue Benutzer hinzuzufügen" + ita "A '%s'@'%s' non e' permesso creare nuovi utenti" + por "Não é permitido a '%s'@'%s' criar novos usuários" + rus "'%s'@'%s' не разрешается создавать новых пользователей" + serbian "Korisniku '%s'@'%s' nije dozvoljeno da kreira nove korisnike" + spa "'%s'@'%s' no es permitido para crear nuevos usuarios" + swe "'%s'@'%s' har inte rättighet att skapa nya användare" + ukr "Користувачу '%s'@'%s' не дозволено створювати нових користувачів" ER_UNION_TABLES_IN_DIFFERENT_DIR nla "Incorrecte tabel definitie; alle MERGE tabellen moeten tot dezelfde database behoren" eng "Incorrect table definition; all MERGE tables must be in the same database" @@ -5252,8 +5252,8 @@ ER_VIEW_CHECK_FAILED rus "проверка CHECK OPTION для VIEW '%-.192s.%-.192s' провалилась" ukr "Перевірка CHECK OPTION для VIEW '%-.192s.%-.192s' не пройшла" ER_PROCACCESS_DENIED_ERROR 42000 - eng "%-.128s command denied to user '%-.48s'@'%-.64s' for routine '%-.192s'" - ger "Befehl %-.128s nicht zulässig für Benutzer '%-.48s'@'%-.64s' in Routine '%-.192s'" + eng "%-.32s command denied to user '%s'@'%s' for routine '%-.192s'" + ger "Befehl %-.32s nicht zulässig für Benutzer '%s'@'%s' in Routine '%-.192s'" ER_RELAY_LOG_FAIL eng "Failed purging old relay logs: %s" ger "Bereinigen alter Relais-Logs fehlgeschlagen: %s" @@ -6084,7 +6084,7 @@ WARN_NO_MASTER_INFO WARN_OPTION_IGNORED eng "<%-.64s> option ignored" ger "Option <%-.64s> ignoriert" -WARN_PLUGIN_DELETE_BUILTIN +ER_PLUGIN_DELETE_BUILTIN eng "Built-in plugins cannot be deleted" ger "Eingebaute Plugins können nicht gelöscht werden" WARN_PLUGIN_BUSY @@ -6316,27 +6316,27 @@ ER_VALUES_IS_NOT_INT_TYPE_ERROR swe "Värden i VALUES för partition '%-.64s' måste ha typen INT" ER_ACCESS_DENIED_NO_PASSWORD_ERROR 28000 - cze "P-Břístup pro uživatele '%-.48s'@'%-.64s'" - dan "Adgang nægtet bruger: '%-.48s'@'%-.64s'" - nla "Toegang geweigerd voor gebruiker: '%-.48s'@'%-.64s'" - eng "Access denied for user '%-.48s'@'%-.64s'" - est "Ligipääs keelatud kasutajale '%-.48s'@'%-.64s'" - fre "Accès refusé pour l'utilisateur: '%-.48s'@'@%-.64s'" - ger "Benutzer '%-.48s'@'%-.64s' hat keine Zugriffsberechtigung" - greek "Δεν επιτέρεται η πρόσβαση στο χρήστη: '%-.48s'@'%-.64s'" - hun "A(z) '%-.48s'@'%-.64s' felhasznalo szamara tiltott eleres." - ita "Accesso non consentito per l'utente: '%-.48s'@'%-.64s'" - kor "'%-.48s'@'%-.64s' 사용자는 접근이 거부 되었습니다." - nor "Tilgang nektet for bruker: '%-.48s'@'%-.64s'" - norwegian-ny "Tilgang ikke tillate for brukar: '%-.48s'@'%-.64s'" - por "Acesso negado para o usuário '%-.48s'@'%-.64s'" - rum "Acces interzis pentru utilizatorul: '%-.48s'@'%-.64s'" - rus "Доступ закрыт для пользователя '%-.48s'@'%-.64s'" - serbian "Pristup je zabranjen korisniku '%-.48s'@'%-.64s'" - slo "Zakázaný prístup pre užívateľa: '%-.48s'@'%-.64s'" - spa "Acceso negado para usuario: '%-.48s'@'%-.64s'" - swe "Användare '%-.48s'@'%-.64s' är ej berättigad att logga in" - ukr "Доступ заборонено для користувача: '%-.48s'@'%-.64s'" + cze "P-Břístup pro uživatele '%s'@'%s'" + dan "Adgang nægtet bruger: '%s'@'%s'" + nla "Toegang geweigerd voor gebruiker: '%s'@'%s'" + eng "Access denied for user '%s'@'%s'" + est "Ligipääs keelatud kasutajale '%s'@'%s'" + fre "Accès refusé pour l'utilisateur: '%s'@'%s'" + ger "Benutzer '%s'@'%s' hat keine Zugriffsberechtigung" + greek "Δεν επιτέρεται η πρόσβαση στο χρήστη: '%s'@'%s'" + hun "A(z) '%s'@'%s' felhasznalo szamara tiltott eleres." + ita "Accesso non consentito per l'utente: '%s'@'%s'" + kor "'%s'@'%s' 사용자는 접근이 거부 되었습니다." + nor "Tilgang nektet for bruker: '%s'@'%s'" + norwegian-ny "Tilgang ikke tillate for brukar: '%s'@'%s'" + por "Acesso negado para o usuário '%s'@'%s'" + rum "Acces interzis pentru utilizatorul: '%s'@'%s'" + rus "Доступ закрыт для пользователя '%s'@'%s'" + serbian "Pristup je zabranjen korisniku '%s'@'%s'" + slo "Zakázaný prístup pre užívateľa: '%s'@'%s'" + spa "Acceso negado para usuario: '%s'@'%s'" + swe "Användare '%s'@'%s' är ej berättigad att logga in" + ukr "Доступ заборонено для користувача: '%s'@'%s'" ER_SET_PASSWORD_AUTH_PLUGIN eng "SET PASSWORD has no significance for users authenticating via plugins" @@ -6773,3 +6773,7 @@ ER_GTID_START_FROM_BINLOG_HOLE eng "The binlog on the master is missing the GTID %u-%u-%llu requested by the slave (even though both a prior and a subsequent sequence number does exist), and GTID strict mode is enabled" ER_SLAVE_UNEXPECTED_MASTER_SWITCH eng "Unexpected GTID received from master after reconnect. This normally indicates that the master server was replaced without restarting the slave threads. %s" +ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_GTID_DOMAIN_ID_SEQ_NO + eng "Cannot modify @@session.gtid_domain_id or @@session.gtid_seq_no inside a transaction" +ER_STORED_FUNCTION_PREVENTS_SWITCH_GTID_DOMAIN_ID_SEQ_NO + eng "Cannot modify @@session.gtid_domain_id or @@session.gtid_seq_no inside a stored function or trigger" diff --git a/sql/slave.cc b/sql/slave.cc index 46a7ddb28f3..55fe53345da 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -166,6 +166,37 @@ static bool send_show_master_info_header(THD *thd, bool full, size_t gtid_pos_length); static bool send_show_master_info_data(THD *thd, Master_info *mi, bool full, String *gtid_pos); +/* + Function to set the slave's max_allowed_packet based on the value + of slave_max_allowed_packet. + + @in_param thd Thread handler for slave + @in_param mysql MySQL connection handle +*/ + +static void set_slave_max_allowed_packet(THD *thd, MYSQL *mysql) +{ + DBUG_ENTER("set_slave_max_allowed_packet"); + // thd and mysql must be valid + DBUG_ASSERT(thd && mysql); + + thd->variables.max_allowed_packet= slave_max_allowed_packet; + thd->net.max_packet_size= slave_max_allowed_packet; + /* + Adding MAX_LOG_EVENT_HEADER_LEN to the max_packet_size on the I/O + thread and the mysql->option max_allowed_packet, since a + replication event can become this much larger than + the corresponding packet (query) sent from client to master. + */ + thd->net.max_packet_size+= MAX_LOG_EVENT_HEADER; + /* + Skipping the setting of mysql->net.max_packet size to slave + max_allowed_packet since this is done during mysql_real_connect. + */ + mysql->options.max_allowed_packet= + slave_max_allowed_packet+MAX_LOG_EVENT_HEADER; + DBUG_VOID_RETURN; +} /* Find out which replications threads are running @@ -887,9 +918,21 @@ int start_slave_threads(bool need_slave_mutex, bool wait_for_start, if (mi->using_gtid != Master_info::USE_GTID_NO && !mi->slave_running && !mi->rli.slave_running) { + /* + purge_relay_logs() clears the mi->rli.group_master_log_pos. + So save and restore them, like we do in CHANGE MASTER. + (We are not going to use them for GTID, but it might be worth to + keep them in case connection with GTID fails and user wants to go + back and continue with previous old-style replication coordinates). + */ + mi->master_log_pos = max(BIN_LOG_HEADER_SIZE, mi->rli.group_master_log_pos); + strmake(mi->master_log_name, mi->rli.group_master_log_name, + sizeof(mi->master_log_name)-1); purge_relay_logs(&mi->rli, NULL, 0, &errmsg); - mi->master_log_name[0]= 0; - mi->master_log_pos= 0; + mi->rli.group_master_log_pos= mi->master_log_pos; + strmake(mi->rli.group_master_log_name, mi->master_log_name, + sizeof(mi->rli.group_master_log_name)-1); + error= rpl_load_gtid_state(&mi->gtid_current_pos, mi->using_gtid == Master_info::USE_GTID_CURRENT_POS); mi->events_queued_since_last_gtid= 0; @@ -2765,12 +2808,6 @@ static int init_slave_thread(THD* thd, Master_info *mi, thd->system_thread = (thd_type == SLAVE_THD_SQL) ? SYSTEM_THREAD_SLAVE_SQL : SYSTEM_THREAD_SLAVE_IO; thd->security_ctx->skip_grants(); -/* - Adding MAX_LOG_EVENT_HEADER_LEN to the max_allowed_packet on all - slave threads, since a replication event can become this much larger - than the corresponding packet (query) sent from client to master. -*/ - thd->variables.max_allowed_packet= slave_max_allowed_packet; thd->slave_thread= 1; thd->connection_name= mi->connection_name; thd->enable_slow_log= opt_log_slow_slave_statements; @@ -3546,7 +3583,13 @@ pthread_handler_t handle_slave_io(void *arg) mi->report(ERROR_LEVEL, thd->stmt_da->sql_errno(), "Unable to load replication GTID slave state from mysql.%s: %s", rpl_gtid_slave_state_table_name.str, thd->stmt_da->message()); - goto err; + /* + If we are using old-style replication, we can continue, even though we + then will not be able to record the GTIDs we receive. But if using GTID, + we must give up. + */ + if (mi->using_gtid != Master_info::USE_GTID_NO || opt_gtid_strict_mode) + goto err; } @@ -3582,14 +3625,6 @@ pthread_handler_t handle_slave_io(void *arg) "replication starts at GTID position '%s'", mi->user, mi->host, mi->port, tmp.c_ptr_safe()); } - - /* - Adding MAX_LOG_EVENT_HEADER_LEN to the max_packet_size on the I/O - thread, since a replication event can become this much larger than - the corresponding packet (query) sent from client to master. - */ - thd->net.max_packet_size= slave_max_allowed_packet; - mysql->net.max_packet_size= thd->net.max_packet_size+= MAX_LOG_EVENT_HEADER; } else { @@ -4151,7 +4186,13 @@ log '%s' at position %s, relay log '%s' position: %s%s", RPL_LOG_NAME, rli->report(ERROR_LEVEL, thd->stmt_da->sql_errno(), "Unable to load replication GTID slave state from mysql.%s: %s", rpl_gtid_slave_state_table_name.str, thd->stmt_da->message()); - goto err; + /* + If we are using old-style replication, we can continue, even though we + then will not be able to record the GTIDs we receive. But if using GTID, + we must give up. + */ + if (mi->using_gtid != Master_info::USE_GTID_NO || opt_gtid_strict_mode) + goto err; } /* execute init_slave variable */ @@ -5069,9 +5110,8 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len) const char *errmsg; Gtid_list_log_event *glev; Log_event *tmp; + uint32 flags; - if (mi->rli.until_condition != Relay_log_info::UNTIL_GTID) - goto default_action; if (!(tmp= Log_event::read_log_event(buf, event_len, &errmsg, mi->rli.relay_log.description_event_for_queue, opt_slave_sql_verify_checksum))) @@ -5080,16 +5120,8 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len) goto err; } glev= static_cast<Gtid_list_log_event *>(tmp); - if (glev->gl_flags & Gtid_list_log_event::FLAG_UNTIL_REACHED) - { - char str_buf[128]; - String str(str_buf, sizeof(str_buf), system_charset_info); - mi->rli.until_gtid_pos.to_string(&str); - sql_print_information("Slave IO thread stops because it reached its" - " UNTIL master_gtid_pos %s", str.c_ptr_safe()); - mi->abort_slave= true; - } event_pos= glev->log_pos; + flags= glev->gl_flags; delete glev; /* @@ -5103,6 +5135,17 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len) inc_pos= 0; else inc_pos= event_pos - mi->master_log_pos; + + if (mi->rli.until_condition == Relay_log_info::UNTIL_GTID && + flags & Gtid_list_log_event::FLAG_UNTIL_REACHED) + { + char str_buf[128]; + String str(str_buf, sizeof(str_buf), system_charset_info); + mi->rli.until_gtid_pos.to_string(&str); + sql_print_information("Slave IO thread stops because it reached its" + " UNTIL master_gtid_pos %s", str.c_ptr_safe()); + mi->abort_slave= true; + } } break; @@ -5415,7 +5458,7 @@ static int connect_to_master(THD* thd, MYSQL* mysql, Master_info* mi, char llbuff[22]; my_bool my_true= 1; DBUG_ENTER("connect_to_master"); - + set_slave_max_allowed_packet(thd, mysql); #ifndef DBUG_OFF mi->events_till_disconnect = disconnect_slave_event_count; #endif @@ -5823,7 +5866,7 @@ static Log_event* next_event(Relay_log_info* rli) if (ev->get_type_code() == GTID_EVENT) { Gtid_log_event *gev= static_cast<Gtid_log_event *>(ev); - uint64 sub_id= rpl_global_gtid_slave_state.next_subid(gev->domain_id); + uint64 sub_id= rpl_global_gtid_slave_state.next_sub_id(gev->domain_id); if (!sub_id) { errmsg = "slave SQL thread aborted because of out-of-memory error"; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 98e807722a3..6b591edca5e 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -41,6 +41,7 @@ #include "sql_parse.h" // cleanup_items #include "sql_base.h" // close_thread_tables #include "transaction.h" // trans_commit_stmt +#include "sql_audit.h" /* Sufficient max length of printed destinations and frame offsets (all uints). @@ -3130,6 +3131,10 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) query_cache_end_of_result(thd); + mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_STATUS, + thd->stmt_da->is_error() ? thd->stmt_da->sql_errno() : 0, + command_name[COM_QUERY].str); + if (!res && unlikely(thd->enable_slow_log)) log_slow_statement(thd); } diff --git a/sql/spatial.cc b/sql/spatial.cc index 2359f4fa271..a01d2c59a49 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -1,6 +1,6 @@ /* - Copyright (c) 2002, 2012, Oracle and/or its affiliates. - Copyright (c) 2011, 2012, Monty Program Ab + Copyright (c) 2002, 2013, Oracle and/or its affiliates. + Copyright (c) 2011, 2013, Monty Program Ab. 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 @@ -818,7 +818,6 @@ int Gis_line_string::store_shapes(Gcalc_shape_transporter *trn) const return trn->complete_line(); } - const Geometry::Class_info *Gis_line_string::get_class_info() const { return &linestring_class; @@ -939,7 +938,9 @@ uint Gis_polygon::init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, if (len < 4) return 0; - n_linear_rings= wkb_get_uint(wkb, bo); + if (!(n_linear_rings= wkb_get_uint(wkb, bo))) + return 0; + if (res->reserve(4, 512)) return 0; wkb+= 4; diff --git a/sql/spatial.h b/sql/spatial.h index 9aaedfe8a20..6df6e37e9b8 100644 --- a/sql/spatial.h +++ b/sql/spatial.h @@ -1,5 +1,6 @@ /* - Copyright (c) 2002, 2010, Oracle and/or its affiliates. + Copyright (c) 2002, 2013, Oracle and/or its affiliates. + Copyright (c) 2009, 2013, Monty Program Ab. 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 @@ -28,7 +29,7 @@ class Gis_read_stream; const uint SRID_SIZE= 4; const uint SIZEOF_STORED_DOUBLE= 8; -const uint POINT_DATA_SIZE= SIZEOF_STORED_DOUBLE*2; +const uint POINT_DATA_SIZE= (SIZEOF_STORED_DOUBLE * 2); const uint WKB_HEADER_SIZE= 1+4; const uint32 GET_SIZE_ERROR= ((uint32) -1); @@ -334,10 +335,36 @@ protected: const char *get_mbr_for_points(MBR *mbr, const char *data, uint offset) const; - inline bool no_data(const char *cur_data, uint32 data_amount) const + /** + Check if there're enough data remaining as requested + + @arg cur_data pointer to the position in the binary form + @arg data_amount number of points expected + @return true if not enough data + */ + inline bool no_data(const char *cur_data, size_t data_amount) const { return (cur_data + data_amount > m_data_end); } + + /** + Check if there're enough points remaining as requested + + Need to perform the calculation in logical units, since multiplication + can overflow the size data type. + + @arg data pointer to the begining of the points array + @arg expected_points number of points expected + @arg extra_point_space extra space for each point element in the array + @return true if there are not enough points + */ + inline bool not_enough_points(const char *data, uint32 expected_points, + uint32 extra_point_space = 0) const + { + return (m_data_end < data || + (expected_points > ((m_data_end - data) / + (POINT_DATA_SIZE + extra_point_space)))); + } const char *m_data; const char *m_data_end; }; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 25548d6b036..e2e3647ff2a 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /* diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index 31e13882515..f287bf47e81 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /* Analyse database */ diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 236d52922d7..e384fbcc32d 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /* Basic functions needed by many modules */ @@ -633,10 +633,8 @@ TABLE_SHARE *get_table_share(THD *thd, const char *db, const char *table_name, mysql_mutex_lock(&share->LOCK_ha_data); mysql_mutex_unlock(&LOCK_open); - if (flags & GTS_FORCE_DISCOVERY) - ha_discover_table(thd, share); // don't read the frm at all - else - open_table_def(thd, share, flags | GTS_FORCE_DISCOVERY); // frm or discover + /* note that get_table_share() *always* uses discovery */ + open_table_def(thd, share, flags | GTS_USE_DISCOVERY); mysql_mutex_unlock(&share->LOCK_ha_data); mysql_mutex_lock(&LOCK_open); @@ -4022,15 +4020,16 @@ recover_from_failed_open(THD *thd) tdc_remove_table(thd, TDC_RT_REMOVE_ALL, m_failed_table->db, m_failed_table->table_name, FALSE); + + thd->warning_info->clear_warning_info(thd->query_id); + thd->clear_error(); // Clear error message + if ((result= !get_table_share(thd, m_failed_table->db, m_failed_table->table_name, GTS_TABLE | GTS_FORCE_DISCOVERY | GTS_NOLOCK))) break; - - thd->warning_info->clear_warning_info(thd->query_id); - thd->clear_error(); // Clear error message thd->mdl_context.release_transactional_locks(); break; } @@ -6004,7 +6003,7 @@ TABLE *open_table_uncached(THD *thd, handlerton *hton, strend(saved_cache_key)+1, tmp_path); share->db_plugin= ha_lock_engine(thd, hton); - if (open_table_def(thd, share, GTS_TABLE | GTS_FORCE_DISCOVERY)) + if (open_table_def(thd, share, GTS_TABLE | GTS_USE_DISCOVERY)) { /* No need to lock share->mutex as this is not needed for tmp tables */ free_table_share(share); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 5c2698531e4..4fc1769ba1f 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1,6 +1,6 @@ /* - Copyright (c) 2000, 2012, Oracle and/or its affiliates. - Copyright (c) 2008, 2013, Monty Program Ab + Copyright (c) 2000, 2013, Oracle and/or its affiliates. + Copyright (c) 2008, 2013, Monty Program Ab. 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 @@ -1465,6 +1465,8 @@ void THD::cleanup(void) } #endif + mysql_ha_cleanup(this); + close_temporary_tables(this); transaction.xid_state.xa_state= XA_NOTR; @@ -1472,7 +1474,6 @@ void THD::cleanup(void) xid_cache_delete(&transaction.xid_state); locked_tables_list.unlock_locked_tables(this); - mysql_ha_cleanup(this); DBUG_ASSERT(open_tables == NULL); /* @@ -1528,7 +1529,6 @@ THD::~THD() /* Ensure that no one is using THD */ mysql_mutex_lock(&LOCK_thd_data); - mysys_var=0; // Safety (shouldn't be needed) mysql_mutex_unlock(&LOCK_thd_data); /* Close connection */ @@ -1763,8 +1763,8 @@ void THD::awake(killed_state state_to_set) mysql_mutex_unlock(mysys_var->current_mutex); break; } + my_sleep(1000000L / WAIT_FOR_KILL_TRY_TIMES); } - my_sleep(1000000L / WAIT_FOR_KILL_TRY_TIMES); } mysql_mutex_unlock(&mysys_var->mutex); } @@ -5071,6 +5071,46 @@ int THD::decide_logging_format(TABLE_LIST *tables) DBUG_PRINT("info", ("decision: logging in %s format", is_current_stmt_binlog_format_row() ? "ROW" : "STATEMENT")); + + if (variables.binlog_format == BINLOG_FORMAT_ROW && + (lex->sql_command == SQLCOM_UPDATE || + lex->sql_command == SQLCOM_UPDATE_MULTI || + lex->sql_command == SQLCOM_DELETE || + lex->sql_command == SQLCOM_DELETE_MULTI)) + { + String table_names; + /* + Generate a warning for UPDATE/DELETE statements that modify a + BLACKHOLE table, as row events are not logged in row format. + */ + for (TABLE_LIST *table= tables; table; table= table->next_global) + { + if (table->placeholder()) + continue; + if (table->table->file->ht->db_type == DB_TYPE_BLACKHOLE_DB && + table->lock_type >= TL_WRITE_ALLOW_WRITE) + { + table_names.append(table->table_name); + table_names.append(","); + } + } + if (!table_names.is_empty()) + { + bool is_update= (lex->sql_command == SQLCOM_UPDATE || + lex->sql_command == SQLCOM_UPDATE_MULTI); + /* + Replace the last ',' with '.' for table_names + */ + table_names.replace(table_names.length()-1, 1, ".", 1); + push_warning_printf(this, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_UNKNOWN_ERROR, + "Row events are not logged for %s statements " + "that modify BLACKHOLE tables in row format. " + "Table(s): '%-.192s'", + is_update ? "UPDATE" : "DELETE", + table_names.c_ptr()); + } + } } #ifndef DBUG_OFF else diff --git a/sql/sql_class.h b/sql/sql_class.h index 5ae777fe817..2e5e87fd232 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -13,7 +13,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef SQL_CLASS_INCLUDED #define SQL_CLASS_INCLUDED @@ -1661,6 +1661,7 @@ public: Protects THD data accessed from other threads: - thd->query and thd->query_length (used by SHOW ENGINE INNODB STATUS and SHOW PROCESSLIST + - thd->db and thd->db_length (used in SHOW PROCESSLIST) - thd->mysys_var (used by KILL statement and shutdown). Is locked when THD is deleted. */ @@ -3051,6 +3052,7 @@ public: bool set_db(const char *new_db, size_t new_db_len) { bool result; + mysql_mutex_lock(&LOCK_thd_data); /* Do not reallocate memory if current chunk is big enough. */ if (db && new_db && db_length >= new_db_len) memcpy(db, new_db, new_db_len+1); @@ -3064,6 +3066,7 @@ public: } db_length= db ? new_db_len : 0; result= new_db && !db; + mysql_mutex_unlock(&LOCK_thd_data); #ifdef HAVE_PSI_THREAD_INTERFACE if (result) PSI_CALL(set_thread_db)(new_db, new_db_len); @@ -3084,11 +3087,16 @@ public: */ void reset_db(char *new_db, size_t new_db_len) { - db= new_db; - db_length= new_db_len; + if (new_db != db || new_db_len != db_length) + { + mysql_mutex_lock(&LOCK_thd_data); + db= new_db; + db_length= new_db_len; + mysql_mutex_unlock(&LOCK_thd_data); #ifdef HAVE_PSI_THREAD_INTERFACE - PSI_CALL(set_thread_db)(new_db, new_db_len); + PSI_CALL(set_thread_db)(new_db, new_db_len); #endif + } } /* Copy the current database to the argument. Use the current arena to @@ -4477,6 +4485,11 @@ inline bool add_order_to_list(THD *thd, Item *item, bool asc) return thd->lex->current_select->add_order_to_list(thd, item, asc); } +inline bool add_gorder_to_list(THD *thd, Item *item, bool asc) +{ + return thd->lex->current_select->add_gorder_to_list(thd, item, asc); +} + inline bool add_group_to_list(THD *thd, Item *item, bool asc) { return thd->lex->current_select->add_group_to_list(thd, item, asc); diff --git a/sql/sql_cmd.h b/sql/sql_cmd.h index 5cf88d2566c..794037a0033 100644 --- a/sql/sql_cmd.h +++ b/sql/sql_cmd.h @@ -91,7 +91,7 @@ enum enum_sql_command { SQLCOM_SHOW_USER_STATS, SQLCOM_SHOW_TABLE_STATS, SQLCOM_SHOW_INDEX_STATS, SQLCOM_SHOW_CLIENT_STATS, SQLCOM_SLAVE_ALL_START, SQLCOM_SLAVE_ALL_STOP, - SQLCOM_SHOW_EXPLAIN, + SQLCOM_SHOW_EXPLAIN, SQLCOM_SHUTDOWN, /* When a command is added here, be sure it's also added in mysqld.cc diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc index 6a664e4d20b..c1820c0187e 100644 --- a/sql/sql_cursor.cc +++ b/sql/sql_cursor.cc @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation /* gcc class implementation */ #endif diff --git a/sql/sql_db.cc b/sql/sql_db.cc index d4f8431beec..39c30959fe4 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -13,7 +13,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /* create and drop of databases */ @@ -48,13 +48,12 @@ #define MAX_DROP_TABLE_Q_LEN 1024 -const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NullS}; +const char *del_exts[]= {".BAK", ".TMD",".opt", NullS}; static TYPELIB deletable_extentions= {array_elements(del_exts)-1,"del_exts", del_exts, NULL}; -static bool find_db_tables_and_rm_known_files(THD *, MY_DIR *, const char *, - const char *, TABLE_LIST **, - bool *); +static bool find_db_tables_and_rm_known_files(THD *, MY_DIR *, char *, + const char *, TABLE_LIST **); long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, const char *org_path); static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error); @@ -757,7 +756,6 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) char path[FN_REFLEN + 16]; MY_DIR *dirp; uint length; - bool found_other_files= false; TABLE_LIST *tables= NULL; TABLE_LIST *table; Drop_table_error_handler err_handler; @@ -789,8 +787,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) } } - if (find_db_tables_and_rm_known_files(thd, dirp, db, path, &tables, - &found_other_files)) + if (find_db_tables_and_rm_known_files(thd, dirp, db, path, &tables)) goto exit; /* @@ -871,10 +868,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) If the directory is a symbolic link, remove the link first, then remove the directory the symbolic link pointed at */ - if (found_other_files) - my_error(ER_DB_DROP_RMDIR, MYF(0), path, EEXIST); - else - error= rm_dir_w_symlink(path, true); + error= rm_dir_w_symlink(path, true); } thd->pop_internal_handler(); @@ -985,18 +979,58 @@ exit: static bool find_db_tables_and_rm_known_files(THD *thd, MY_DIR *dirp, - const char *db, + char *dbname, const char *path, - TABLE_LIST **tables, - bool *found_other_files) + TABLE_LIST **tables) { char filePath[FN_REFLEN]; + LEX_STRING db= { dbname, strlen(dbname) }; TABLE_LIST *tot_list=0, **tot_list_next_local, **tot_list_next_global; DBUG_ENTER("find_db_tables_and_rm_known_files"); DBUG_PRINT("enter",("path: %s", path)); + /* first, get the list of tables */ + Dynamic_array<LEX_STRING*> files(dirp->number_of_files); + Discovered_table_list tl(thd, &files, &null_lex_str); + if (ha_discover_table_names(thd, &db, dirp, &tl, true)) + DBUG_RETURN(1); + + /* Now put the tables in the list */ tot_list_next_local= tot_list_next_global= &tot_list; + for (size_t idx=0; idx < files.elements(); idx++) + { + LEX_STRING *table= files.at(idx); + + /* Drop the table nicely */ + TABLE_LIST *table_list=(TABLE_LIST*)thd->calloc(sizeof(*table_list)); + + if (!table_list) + DBUG_RETURN(true); + table_list->db= db.str; + table_list->db_length= db.length; + table_list->table_name= table->str; + table_list->table_name_length= table->length; + table_list->open_type= OT_BASE_ONLY; + + /* To be able to correctly look up the table in the table cache. */ + if (lower_case_table_names) + table_list->table_name_length= my_casedn_str(files_charset_info, + table_list->table_name); + + table_list->alias= table_list->table_name; // If lower_case_table_names=2 + table_list->mdl_request.init(MDL_key::TABLE, table_list->db, + table_list->table_name, MDL_EXCLUSIVE, + MDL_TRANSACTION); + /* Link into list */ + (*tot_list_next_local)= table_list; + (*tot_list_next_global)= table_list; + tot_list_next_local= &table_list->next_local; + tot_list_next_global= &table_list->next_global; + } + *tables= tot_list; + + /* and at last delete all non-table files */ for (uint idx=0 ; idx < (uint) dirp->number_of_files && !thd->killed ; idx++) @@ -1021,59 +1055,12 @@ static bool find_db_tables_and_rm_known_files(THD *thd, MY_DIR *dirp, DBUG_PRINT("my",("Archive subdir found: %s", newpath)); if ((mysql_rm_arc_files(thd, new_dirp, newpath)) < 0) DBUG_RETURN(true); - continue; } - *found_other_files= true; continue; } if (!(extension= strrchr(file->name, '.'))) extension= strend(file->name); - if (find_type(extension, &deletable_extentions, FIND_TYPE_NO_PREFIX) <= 0) - { - if (find_type(extension, ha_known_exts(), FIND_TYPE_NO_PREFIX) <= 0) - *found_other_files= true; - continue; - } - /* just for safety we use files_charset_info */ - if (db && !my_strcasecmp(files_charset_info, - extension, reg_ext)) - { - /* Drop the table nicely */ - *extension= 0; // Remove extension - TABLE_LIST *table_list=(TABLE_LIST*) - thd->calloc(sizeof(*table_list) + - strlen(db) + 1 + - MYSQL50_TABLE_NAME_PREFIX_LENGTH + - strlen(file->name) + 1); - - if (!table_list) - DBUG_RETURN(true); - table_list->db= (char*) (table_list+1); - table_list->db_length= strmov(table_list->db, db) - table_list->db; - table_list->table_name= table_list->db + table_list->db_length + 1; - table_list->table_name_length= filename_to_tablename(file->name, - table_list->table_name, - MYSQL50_TABLE_NAME_PREFIX_LENGTH + - strlen(file->name) + 1); - table_list->open_type= OT_BASE_ONLY; - - /* To be able to correctly look up the table in the table cache. */ - if (lower_case_table_names) - table_list->table_name_length= my_casedn_str(files_charset_info, - table_list->table_name); - - table_list->alias= table_list->table_name; // If lower_case_table_names=2 - table_list->internal_tmp_table= is_prefix(file->name, tmp_file_prefix); - table_list->mdl_request.init(MDL_key::TABLE, table_list->db, - table_list->table_name, MDL_EXCLUSIVE, - MDL_TRANSACTION); - /* Link into list */ - (*tot_list_next_local)= table_list; - (*tot_list_next_global)= table_list; - tot_list_next_local= &table_list->next_local; - tot_list_next_global= &table_list->next_global; - } - else + if (find_type(extension, &deletable_extentions, FIND_TYPE_NO_PREFIX) > 0) { strxmov(filePath, path, "/", file->name, NullS); /* @@ -1088,7 +1075,7 @@ static bool find_db_tables_and_rm_known_files(THD *thd, MY_DIR *dirp, } } } - *tables= tot_list; + DBUG_RETURN(false); } diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 526d2445d3d..2992bb0da6e 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -87,7 +87,16 @@ mysql_handle_derived(LEX *lex, uint phases) sl && !res; sl= sl->next_select_in_list()) { - for (TABLE_LIST *cursor= sl->get_table_list(); + TABLE_LIST *cursor= sl->get_table_list(); + /* + DT_MERGE_FOR_INSERT is not needed for views/derived tables inside + subqueries. Views and derived tables of subqueries should be + processed normally. + */ + if (phases == DT_MERGE_FOR_INSERT && + cursor && cursor->top_table()->select_lex != &lex->select_lex) + continue; + for (; cursor && !res; cursor= cursor->next_local) { @@ -812,8 +821,7 @@ bool mysql_derived_create(THD *thd, LEX *lex, TABLE_LIST *derived) result->tmp_table_param.start_recinfo, &result->tmp_table_param.recinfo, (unit->first_select()->options | - thd->variables.option_bits | TMP_TABLE_ALL_COLUMNS), - thd->variables.big_tables)) + thd->variables.option_bits | TMP_TABLE_ALL_COLUMNS))) return(TRUE); } if (open_tmp_table(table)) diff --git a/sql/sql_error.cc b/sql/sql_error.cc index 8cfc304e0e7..acb61fe68c5 100644 --- a/sql/sql_error.cc +++ b/sql/sql_error.cc @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /********************************************************************** This file contains the implementation of error and warnings related diff --git a/sql/sql_error.h b/sql/sql_error.h index ae9ef9f8d47..cd1b92a2bcc 100644 --- a/sql/sql_error.h +++ b/sql/sql_error.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef SQL_ERROR_H #define SQL_ERROR_H diff --git a/sql/sql_expression_cache.cc b/sql/sql_expression_cache.cc index 1193c7c27f4..1e64bc10a7c 100644 --- a/sql/sql_expression_cache.cc +++ b/sql/sql_expression_cache.cc @@ -288,7 +288,7 @@ my_bool Expression_cache_tmptable::put_value(Item *value) if (create_internal_tmp_table_from_heap(table_thd, cache_table, cache_table_param.start_recinfo, &cache_table_param.recinfo, - error, 1)) + error, 1, NULL)) goto err; } } diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 06efaea8a5b..3c4804c523a 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /* HANDLER ... commands - direct access to ISAM */ diff --git a/sql/sql_help.cc b/sql/sql_help.cc index 458904ebe1d..d3c36e2c5d7 100644 --- a/sql/sql_help.cc +++ b/sql/sql_help.cc @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "sql_priv.h" #include "unireg.h" diff --git a/sql/sql_hset.h b/sql/sql_hset.h index 2ea70b91da8..f3a1467737f 100644 --- a/sql/sql_hset.h +++ b/sql/sql_hset.h @@ -13,7 +13,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "my_global.h" #include "hash.h" diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index b1354ce38bd..2eda80e8b36 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2011, Oracle and/or its affiliates. + Copyright (c) 2000, 2013, Oracle and/or its affiliates. Copyright (c) 2009, 2013, Monty Program Ab. This program is free software; you can redistribute it and/or modify @@ -95,15 +95,13 @@ static bool check_view_insertability(THD *thd, TABLE_LIST *view); /* Check that insert/update fields are from the same single table of a view. - SYNOPSIS - check_view_single_update() - fields The insert/update fields to be checked. - values Values to use for update - view The view for insert. - map [in/out] The insert table map. + @param fields The insert/update fields to be checked. + @param values The insert/update values to be checked, NULL if + checking is not wanted. + @param view The view for insert. + @param map [in/out] The insert table map. - DESCRIPTION - This function is called in 2 cases: + This function is called in 2 cases: 1. to check insert fields. In this case *map will be set to 0. Insert fields are checked to be all from the same single underlying table of the given view. Otherwise the error is thrown. Found table @@ -113,9 +111,7 @@ static bool check_view_insertability(THD *thd, TABLE_LIST *view); the function to check insert fields. Update fields are checked to be from the same table as the insert fields. - RETURN - 0 OK - 1 Error + @returns false if success. */ bool check_view_single_update(List<Item> &fields, List<Item> *values, @@ -180,21 +176,16 @@ error: /* Check if insert fields are correct. - SYNOPSIS - check_insert_fields() - thd The current thread. - table The table for insert. - fields The insert fields. - values The insert values. - check_unique If duplicate values should be rejected. - fields_and_values_from_different_maps - Set to 1 if fields and values are using - different table maps, like on select ... insert - map Store here table map for used fields - - RETURN - 0 OK - -1 Error + @param thd The current thread. + @param table_list The table we are inserting into (may be view) + @param fields The insert fields. + @param values The insert values. + @param check_unique If duplicate values should be rejected. + @param fields_and_values_from_different_maps If 'values' are allowed to + refer to other tables than those of 'fields' + @param map See check_view_single_update + + @returns 0 if success, -1 if error */ static int check_insert_fields(THD *thd, TABLE_LIST *table_list, @@ -312,28 +303,29 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list, } -/* - Check update fields for the timestamp and auto_increment fields. +/** + Check if update fields are correct. - SYNOPSIS - check_update_fields() - thd The current thread. - insert_table_list The insert table list. - table The table for update. - update_fields The update fields. + @param thd The current thread. + @param insert_table_list The table we are inserting into (may be view) + @param update_fields The update fields. + @param update_values The update values. + @param fields_and_values_from_different_maps If 'update_values' are allowed to + refer to other tables than those of 'update_fields' + @param map See check_view_single_update - NOTE - If the update fields include an autoinc field, set the - table->next_number_field_updated flag. + @note + If the update fields include an autoinc field, set the + table->next_number_field_updated flag. - RETURN - 0 OK - -1 Error + @returns 0 if success, -1 if error */ static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list, List<Item> &update_fields, - List<Item> &update_values, table_map *map) + List<Item> &update_values, + bool fields_and_values_from_different_maps, + table_map *map) { TABLE *table= insert_table_list->table; my_bool autoinc_mark; @@ -358,7 +350,9 @@ static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list, if (insert_table_list->is_view() && insert_table_list->is_merged_derived() && - check_view_single_update(update_fields, &update_values, + check_view_single_update(update_fields, + fields_and_values_from_different_maps ? + (List<Item>*) 0 : &update_values, insert_table_list, map, false)) return -1; @@ -1451,7 +1445,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, { select_lex->no_wrap_view_item= TRUE; res= check_update_fields(thd, context->table_list, update_fields, - update_values, &map); + update_values, false, &map); select_lex->no_wrap_view_item= FALSE; } @@ -3382,9 +3376,16 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u) context->resolve_in_table_list_only(table_list); lex->select_lex.no_wrap_view_item= TRUE; - res= res || check_update_fields(thd, context->table_list, - *info.update_fields, *info.update_values, - &map); + res= res || + check_update_fields(thd, context->table_list, + *info.update_fields, *info.update_values, + /* + In INSERT SELECT ON DUPLICATE KEY UPDATE col=x + 'x' can legally refer to a non-inserted table. + 'x' is not even resolved yet. + */ + true, + &map); lex->select_lex.no_wrap_view_item= FALSE; /* When we are not using GROUP BY and there are no ungrouped aggregate functions diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index c0ebb478056..501d846421d 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. +/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. Copyright (c) 2009, 2013, Monty Program Ab. This program is free software; you can redistribute it and/or modify @@ -1883,9 +1883,11 @@ void st_select_lex::init_query() cond_count= between_count= with_wild= 0; max_equal_elems= 0; ref_pointer_array= 0; + ref_pointer_array_size= 0; select_n_where_fields= 0; select_n_reserved= 0; select_n_having_items= 0; + n_sum_items= 0; n_child_sum_items= 0; subquery_in_having= explicit_limit= 0; is_item_list_lookup= 0; @@ -2246,6 +2248,11 @@ bool st_select_lex::add_order_to_list(THD *thd, Item *item, bool asc) } +bool st_select_lex::add_gorder_to_list(THD *thd, Item *item, bool asc) +{ + return add_to_list(thd, gorder_list, item, asc); +} + bool st_select_lex::add_item_to_list(THD *thd, Item *item) { DBUG_ENTER("st_select_lex::add_item_to_list"); @@ -2316,11 +2323,6 @@ ulong st_select_lex::get_table_join_options() bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num) { - DBUG_ENTER("st_select_lex::setup_ref_array"); - - if (ref_pointer_array) - DBUG_RETURN(0); - // find_order_in_list() may need some extra space, so multiply by two. order_group_num*= 2; @@ -2328,14 +2330,31 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num) We have to create array in prepared statement memory if it is a prepared statement */ - ref_pointer_array= - (Item **)thd->stmt_arena->alloc(sizeof(Item*) * (n_child_sum_items + - item_list.elements + - select_n_reserved + - select_n_having_items + - select_n_where_fields + - order_group_num)*5); - DBUG_RETURN(ref_pointer_array == 0); + Query_arena *arena= thd->stmt_arena; + const uint n_elems= (n_sum_items + + n_child_sum_items + + item_list.elements + + select_n_reserved + + select_n_having_items + + select_n_where_fields + + order_group_num) * 5; + if (ref_pointer_array != NULL) + { + /* + We need to take 'n_sum_items' into account when allocating the array, + and this may actually increase during the optimization phase due to + MIN/MAX rewrite in Item_in_subselect::single_value_transformer. + In the usual case we can reuse the array from the prepare phase. + If we need a bigger array, we must allocate a new one. + */ + if (ref_pointer_array_size >= n_elems) + return false; + } + ref_pointer_array= static_cast<Item**>(arena->alloc(sizeof(Item*) * n_elems)); + if (ref_pointer_array != NULL) + ref_pointer_array_size= n_elems; + + return ref_pointer_array == NULL; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 581315a1cfd..0802adc94aa 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1,4 +1,5 @@ -/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. +/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. + Copyright (c) 2010, 2013, Monty Program Ab. 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 @@ -729,10 +730,11 @@ public: const char *type; /* type of select for EXPLAIN */ SQL_I_List<ORDER> order_list; /* ORDER clause */ - SQL_I_List<ORDER> *gorder_list; + SQL_I_List<ORDER> gorder_list; Item *select_limit, *offset_limit; /* LIMIT clause parameters */ // Arrays of pointers to top elements of all_fields list Item **ref_pointer_array; + size_t ref_pointer_array_size; // Number of elements in array. /* number of items in select_list and HAVING clause used to get number @@ -867,6 +869,7 @@ public: bool add_group_to_list(THD *thd, Item *item, bool asc); bool add_ftfunc_to_list(Item_func_match *func); bool add_order_to_list(THD *thd, Item *item, bool asc); + bool add_gorder_to_list(THD *thd, Item *item, bool asc); TABLE_LIST* add_table_to_list(THD *thd, Table_ident *table, LEX_STRING *alias, ulong table_options, diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 11e23b56f71..78e88e3ede2 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -1426,7 +1426,7 @@ inline int READ_INFO::terminator(char *ptr,uint length) uint i; for (i=1 ; i < length ; i++) { - if ((chr=GET) != *++ptr) + if ((chr=GET) != *(uchar*)++ptr) { break; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index de7e825b7fc..f9554c79305 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1110,6 +1110,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->enable_slow_log= TRUE; thd->query_plan_flags= QPLAN_INIT; thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */ + + DEBUG_SYNC(thd,"dispatch_command_before_set_time"); + thd->set_time(); if (!(server_command_flags[command] & CF_SKIP_QUERY_ID)) thd->set_query_id(next_query_id()); @@ -1289,6 +1292,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->update_server_status(); thd->protocol->end_statement(); query_cache_end_of_result(thd); + + mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_STATUS, + thd->stmt_da->is_error() ? thd->stmt_da->sql_errno() + : 0, command_name[command].str); + ulong length= (ulong)(packet_end - beginning_of_next_stmt); log_slow_statement(thd); @@ -1689,6 +1697,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da()); thd->m_statement_psi= NULL; + thd->set_time(); dec_thread_running(); thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC)); @@ -4130,6 +4139,17 @@ end_with_restore_list: lex->kill_signal); break; } + case SQLCOM_SHUTDOWN: +#ifndef EMBEDDED_LIBRARY + if (check_global_access(thd,SHUTDOWN_ACL)) + goto error; + kill_mysql(); + my_ok(thd); +#else + my_error(ER_NOT_SUPPORTED_YET, MYF(0), "embedded server"); +#endif + break; + #ifndef NO_EMBEDDED_ACCESS_CHECKS case SQLCOM_SHOW_GRANTS: { @@ -6700,6 +6720,8 @@ TABLE_LIST *st_select_lex::nest_last_join(THD *thd) for (uint i=0; i < 2; i++) { TABLE_LIST *table= join_list->pop(); + if (!table) + DBUG_RETURN(NULL); table->join_list= embedded_list; table->embedding= ptr; embedded_list->push_back(table); diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 5bac6643772..f51bba83b75 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /* This file is a container for general functionality related diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 3c827ddda3b..1260fb8cb3a 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -2013,9 +2013,13 @@ static bool finalize_install(THD *thd, TABLE *table, const LEX_STRING *name) ER_CANT_INITIALIZE_UDF, ER(ER_CANT_INITIALIZE_UDF), name->str, "Plugin is disabled"); } + else if (tmp->state != PLUGIN_IS_UNINITIALIZED) + { + /* already installed */ + return 0; + } else { - DBUG_ASSERT(tmp->state == PLUGIN_IS_UNINITIALIZED); if (plugin_initialize(tmp)) { report_error(REPORT_TO_USER, ER_CANT_INITIALIZE_UDF, name->str, @@ -2155,9 +2159,7 @@ static bool do_uninstall(THD *thd, TABLE *table, const LEX_STRING *name) } if (!plugin->plugin_dl) { - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - WARN_PLUGIN_DELETE_BUILTIN, ER(WARN_PLUGIN_DELETE_BUILTIN)); - my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PLUGIN", name->str); + my_error(ER_PLUGIN_DELETE_BUILTIN, MYF(0)); return 1; } if (plugin->load_option == PLUGIN_FORCE_PLUS_PERMANENT) diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 51c3894ec3e..220a2a16db6 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2177,6 +2177,7 @@ static bool check_prepared_statement(Prepared_statement *stmt) case SQLCOM_GRANT: case SQLCOM_REVOKE: case SQLCOM_KILL: + case SQLCOM_SHUTDOWN: break; case SQLCOM_PREPARE: diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 0d6c97842d4..802161a09a9 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -894,7 +894,8 @@ contains_all_slave_gtid(slave_connection_state *st, Gtid_list_log_event *glev) static int check_slave_start_position(THD *thd, slave_connection_state *st, const char **errormsg, rpl_gtid *error_gtid, - slave_connection_state *until_gtid_state) + slave_connection_state *until_gtid_state, + HASH *fake_gtid_hash) { uint32 i; int err; @@ -998,11 +999,30 @@ check_slave_start_position(THD *thd, slave_connection_state *st, &start_gtid) && start_gtid.seq_no > slave_gtid->seq_no) { + rpl_gtid *fake_gtid; /* Start replication within this domain at the first GTID that we logged ourselves after becoming a master. + + Remember that this starting point is in fact a "fake" GTID which may + not exists in the binlog, so that we do not complain about it in + --gtid-strict-mode. */ slave_gtid->server_id= global_system_variables.server_id; + if (!(fake_gtid= (rpl_gtid *)my_malloc(sizeof(*fake_gtid), MYF(0)))) + { + *errormsg= "Out of memory while checking slave start position"; + err= ER_OUT_OF_RESOURCES; + goto end; + } + *fake_gtid= *slave_gtid; + if (my_hash_insert(fake_gtid_hash, (uchar *)fake_gtid)) + { + my_free(fake_gtid); + *errormsg= "Out of memory while checking slave start position"; + err= ER_OUT_OF_RESOURCES; + goto end; + } } else if (mysql_bin_log.lookup_domain_in_binlog_state(slave_gtid->domain_id, &start_gtid)) @@ -1022,8 +1042,8 @@ check_slave_start_position(THD *thd, slave_connection_state *st, */ if (!delete_list) { - if ((delete_list= (rpl_gtid **)my_malloc(sizeof(*delete_list), - MYF(MY_WME)))) + if (!(delete_list= (rpl_gtid **) + my_malloc(sizeof(*delete_list) * st->hash.records, MYF(MY_WME)))) { *errormsg= "Out of memory while checking slave start position"; err= ER_OUT_OF_RESOURCES; @@ -1461,7 +1481,8 @@ send_event_to_slave(THD *thd, NET *net, String* const packet, ushort flags, slave_connection_state *until_gtid_state, enum_gtid_until_state *gtid_until_group, rpl_binlog_state *until_binlog_state, - bool slave_gtid_strict_mode, rpl_gtid *error_gtid) + bool slave_gtid_strict_mode, rpl_gtid *error_gtid, + bool *send_fake_gtid_list, HASH *fake_gtid_hash) { my_off_t pos; size_t len= packet->length(); @@ -1541,7 +1562,9 @@ send_event_to_slave(THD *thd, NET *net, String* const packet, ushort flags, if (event_gtid.server_id == gtid->server_id && event_gtid.seq_no >= gtid->seq_no) { - if (event_gtid.seq_no > gtid->seq_no) + if (slave_gtid_strict_mode && event_gtid.seq_no > gtid->seq_no && + !my_hash_search(fake_gtid_hash, + (const uchar *)&event_gtid.domain_id, 0)) { /* In strict mode, it is an error if the slave requests to start @@ -1549,24 +1572,21 @@ send_event_to_slave(THD *thd, NET *net, String* const packet, ushort flags, exist, even though both the prior and subsequent seq_no exists for same domain_id and server_id. */ - if (slave_gtid_strict_mode) - { - my_errno= ER_GTID_START_FROM_BINLOG_HOLE; - *error_gtid= *gtid; - return "The binlog on the master is missing the GTID requested " - "by the slave (even though both a prior and a subsequent " - "sequence number does exist), and GTID strict mode is enabled."; - } - } - else - { - /* - Send a fake Gtid_list event to the slave. - This allows the slave to update its current binlog position - so MASTER_POS_WAIT() and MASTER_GTID_WAIT() can work. - */ -// send_fake_gtid_list_event(until_binlog_state); + my_errno= ER_GTID_START_FROM_BINLOG_HOLE; + *error_gtid= *gtid; + return "The binlog on the master is missing the GTID requested " + "by the slave (even though both a prior and a subsequent " + "sequence number does exist), and GTID strict mode is enabled."; } + + /* + Send a fake Gtid_list event to the slave. + This allows the slave to update its current binlog position + so MASTER_POS_WAIT() and MASTER_GTID_WAIT() can work. + The fake event will be sent at the end of this event group. + */ + *send_fake_gtid_list= true; + /* Delete this entry if we have reached slave start position (so we will not skip subsequent events and won't have to look them up @@ -1817,7 +1837,9 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, enum_gtid_skip_type gtid_skip_group= GTID_SKIP_NOT; enum_gtid_until_state gtid_until_group= GTID_UNTIL_NOT_DONE; rpl_binlog_state until_binlog_state; - bool slave_gtid_strict_mode; + bool slave_gtid_strict_mode= false; + bool send_fake_gtid_list= false; + HASH fake_gtid_hash; uint8 current_checksum_alg= BINLOG_CHECKSUM_ALG_UNDEF; int old_max_allowed_packet= thd->variables.max_allowed_packet; @@ -1831,6 +1853,9 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, bzero((char*) &log,sizeof(log)); bzero(&error_gtid, sizeof(error_gtid)); + my_hash_init(&fake_gtid_hash, &my_charset_bin, 32, + offsetof(rpl_gtid, domain_id), sizeof(uint32), NULL, my_free, + HASH_UNIQUE); /* heartbeat_period from @master_heartbeat_period user variable */ @@ -1930,7 +1955,8 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, goto err; } if ((error= check_slave_start_position(thd, >id_state, &errmsg, - &error_gtid, until_gtid_state))) + &error_gtid, until_gtid_state, + &fake_gtid_hash))) { my_errno= error; goto err; @@ -2234,11 +2260,25 @@ impossible position"; >id_state, >id_skip_group, until_gtid_state, >id_until_group, &until_binlog_state, - slave_gtid_strict_mode, &error_gtid))) + slave_gtid_strict_mode, &error_gtid, + &send_fake_gtid_list, &fake_gtid_hash))) { errmsg= tmp_msg; goto err; } + if (unlikely(send_fake_gtid_list) && gtid_skip_group == GTID_SKIP_NOT) + { + Gtid_list_log_event glev(&until_binlog_state, 0); + + if (reset_transmit_packet(thd, flags, &ev_offset, &errmsg) || + fake_gtid_list_event(net, packet, &glev, &errmsg, + current_checksum_alg, my_b_tell(&log))) + { + my_errno= ER_UNKNOWN_ERROR; + goto err; + } + send_fake_gtid_list= false; + } if (until_gtid_state && is_until_reached(thd, net, packet, &ev_offset, gtid_until_group, event_type, current_checksum_alg, flags, &errmsg, @@ -2426,13 +2466,27 @@ impossible position"; using_gtid_state, >id_state, >id_skip_group, until_gtid_state, >id_until_group, &until_binlog_state, - slave_gtid_strict_mode, &error_gtid))) + slave_gtid_strict_mode, &error_gtid, + &send_fake_gtid_list, + &fake_gtid_hash))) { errmsg= tmp_msg; goto err; } - if ( - until_gtid_state && + if (unlikely(send_fake_gtid_list) && gtid_skip_group == GTID_SKIP_NOT) + { + Gtid_list_log_event glev(&until_binlog_state, 0); + + if (reset_transmit_packet(thd, flags, &ev_offset, &errmsg) || + fake_gtid_list_event(net, packet, &glev, &errmsg, + current_checksum_alg, my_b_tell(&log))) + { + my_errno= ER_UNKNOWN_ERROR; + goto err; + } + send_fake_gtid_list= false; + } + if (until_gtid_state && is_until_reached(thd, net, packet, &ev_offset, gtid_until_group, event_type, current_checksum_alg, flags, &errmsg, &until_binlog_state, my_b_tell(&log))) @@ -2504,6 +2558,7 @@ impossible position"; end: end_io_cache(&log); mysql_file_close(file, MYF(MY_WME)); + my_hash_free(&fake_gtid_hash); RUN_HOOK(binlog_transmit, transmit_stop, (thd, flags)); my_eof(thd); @@ -2574,6 +2629,7 @@ err: mysql_mutex_unlock(&LOCK_thread_count); if (file >= 0) mysql_file_close(file, MYF(MY_WME)); + my_hash_free(&fake_gtid_hash); thd->variables.max_allowed_packet= old_max_allowed_packet; my_message(my_errno, error_text, MYF(0)); @@ -3297,16 +3353,6 @@ bool change_master(THD* thd, Master_info* mi, bool *master_info_added) ret= TRUE; goto err; } - - if (mi->using_gtid != Master_info::USE_GTID_NO) - { - /* - Clear the position in the master binlogs, so that we request the - correct GTID position. - */ - mi->master_log_name[0]= 0; - mi->master_log_pos= 0; - } } else { @@ -3722,6 +3768,8 @@ bool show_binlogs(THD* thd) if (protocol->write()) goto err; } + if(index_file->error == -1) + goto err; mysql_bin_log.unlock_index(); my_eof(thd); DBUG_RETURN(FALSE); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 737f568fd62..2d80767a141 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** @file @@ -8606,6 +8606,7 @@ JOIN::make_simple_join(JOIN *parent, TABLE *temp_table) join_tab->ref.key = -1; join_tab->read_first_record= join_init_read_record; join_tab->join= this; + join_tab->ref.key_parts= 0; bzero((char*) &join_tab->read_record,sizeof(join_tab->read_record)); temp_table->status=0; temp_table->null_row=0; @@ -9931,7 +9932,7 @@ end_sj_materialize(JOIN *join, JOIN_TAB *join_tab, bool end_of_records) if (table->file->is_fatal_error(error, HA_CHECK_DUP) && create_internal_tmp_table_from_heap(thd, table, sjm->sjm_table_param.start_recinfo, - &sjm->sjm_table_param.recinfo, error, 1)) + &sjm->sjm_table_param.recinfo, error, 1, NULL)) DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ } } @@ -10501,10 +10502,7 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after) join_read_system :join_read_const; if (table->covering_keys.is_set(tab->ref.key) && !table->no_keyread) - { - table->key_read=1; - table->file->extra(HA_EXTRA_KEYREAD); - } + table->enable_keyread(); else if ((!jcl || jcl > 4) && !tab->ref.is_access_triggered()) push_index_cond(tab, tab->ref.key); break; @@ -10513,10 +10511,7 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after) /* fall through */ if (table->covering_keys.is_set(tab->ref.key) && !table->no_keyread) - { - table->key_read=1; - table->file->extra(HA_EXTRA_KEYREAD); - } + table->enable_keyread(); else if ((!jcl || jcl > 4) && !tab->ref.is_access_triggered()) push_index_cond(tab, tab->ref.key); break; @@ -11121,11 +11116,27 @@ void JOIN::cleanup(bool full) else clean_pre_sort_join_tab(); } + /* + Call cleanup() on join tabs used by the join optimization + (join->join_tab may now be pointing to result of make_simple_join + reading from the temporary table) - for (tab= first_linear_tab(this, WITH_CONST_TABLES); tab; - tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS)) + We also need to check table_count to handle various degenerate joins + w/o tables: they don't have some members initialized and + WALK_OPTIMIZATION_TABS may not work correctly for them. + */ + enum enum_exec_or_opt tabs_kind; + if (first_breadth_first_tab(this, WALK_OPTIMIZATION_TABS)) + tabs_kind= WALK_OPTIMIZATION_TABS; + else + tabs_kind= WALK_EXECUTION_TABS; + if (table_count) { - tab->cleanup(); + for (tab= first_breadth_first_tab(this, tabs_kind); tab; + tab= next_breadth_first_tab(this, tabs_kind, tab)) + { + tab->cleanup(); + } } cleaned= true; } @@ -11136,8 +11147,10 @@ void JOIN::cleanup(bool full) { if (tab->table) { - DBUG_PRINT("info", ("close index: %s.%s", tab->table->s->db.str, - tab->table->s->table_name.str)); + DBUG_PRINT("info", ("close index: %s.%s alias: %s", + tab->table->s->db.str, + tab->table->s->table_name.str, + tab->table->alias.c_ptr())); tab->table->file->ha_index_or_rnd_end(); } } @@ -14488,7 +14501,7 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table, if (new_field) new_field->init(table); - if (copy_func && item->is_result_field()) + if (copy_func && item->real_item()->is_result_field()) *((*copy_func)++) = item; // Save for copy_funcs if (modify_item) item->set_result_field(new_field); @@ -15597,8 +15610,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields, if (share->db_type() == TMP_ENGINE_HTON) { if (create_internal_tmp_table(table, param->keyinfo, param->start_recinfo, - ¶m->recinfo, select_options, - thd->variables.big_tables)) + ¶m->recinfo, select_options)) goto err; } if (open_tmp_table(table)) @@ -15816,7 +15828,7 @@ bool open_tmp_table(TABLE *table) bool create_internal_tmp_table(TABLE *table, KEY *keyinfo, TMP_ENGINE_COLUMNDEF *start_recinfo, TMP_ENGINE_COLUMNDEF **recinfo, - ulonglong options, my_bool big_tables) + ulonglong options) { int error; MARIA_KEYDEF keydef; @@ -15909,7 +15921,8 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo, } bzero((char*) &create_info,sizeof(create_info)); - if (big_tables && !(options & SELECT_SMALL_RESULT)) + /* Use long data format, to ensure we never get a 'table is full' error */ + if (!(options & SELECT_SMALL_RESULT)) create_info.data_file_length= ~(ulonglong) 0; /* @@ -15985,7 +15998,7 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo, bool create_internal_tmp_table(TABLE *table, KEY *keyinfo, TMP_ENGINE_COLUMNDEF *start_recinfo, TMP_ENGINE_COLUMNDEF **recinfo, - ulonglong options, my_bool big_tables) + ulonglong options) { int error; MI_KEYDEF keydef; @@ -16072,7 +16085,7 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo, MI_CREATE_INFO create_info; bzero((char*) &create_info,sizeof(create_info)); - if (big_tables && !(options & SELECT_SMALL_RESULT)) + if (!(options & SELECT_SMALL_RESULT)) create_info.data_file_length= ~(ulonglong) 0; if ((error=mi_create(share->table_name.str, share->keys, &keydef, @@ -16095,7 +16108,6 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo, DBUG_RETURN(1); } - #endif /* USE_ARIA_FOR_TMP_TABLES */ @@ -16110,7 +16122,8 @@ create_internal_tmp_table_from_heap(THD *thd, TABLE *table, TMP_ENGINE_COLUMNDEF *start_recinfo, TMP_ENGINE_COLUMNDEF **recinfo, int error, - bool ignore_last_dupp_key_error) + bool ignore_last_dupp_key_error, + bool *is_duplicate) { TABLE new_table; TABLE_SHARE share; @@ -16143,8 +16156,7 @@ create_internal_tmp_table_from_heap(THD *thd, TABLE *table, if (create_internal_tmp_table(&new_table, table->key_info, start_recinfo, recinfo, thd->lex->select_lex.options | - thd->variables.option_bits, - thd->variables.big_tables)) + thd->variables.option_bits)) goto err2; if (open_tmp_table(&new_table)) goto err1; @@ -16188,6 +16200,13 @@ create_internal_tmp_table_from_heap(THD *thd, TABLE *table, if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) || !ignore_last_dupp_key_error) goto err; + if (is_duplicate) + *is_duplicate= TRUE; + } + else + { + if (is_duplicate) + *is_duplicate= FALSE; } /* remove heap table and change to use myisam table */ @@ -16772,7 +16791,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) if (rc != NESTED_LOOP_NO_MORE_ROWS) { error= (*join_tab->read_first_record)(join_tab); - if (join_tab->keep_current_rowid) + if (!error && join_tab->keep_current_rowid) join_tab->table->file->position(join_tab->table->record[0]); rc= evaluate_join_record(join, join_tab, error); } @@ -17689,6 +17708,8 @@ join_read_first(JOIN_TAB *tab) { int error= 0; TABLE *table=tab->table; + DBUG_ENTER("join_read_first"); + if (table->covering_keys.is_set(tab->index) && !table->no_keyread && !table->key_read) table->enable_keyread(); @@ -17705,9 +17726,9 @@ join_read_first(JOIN_TAB *tab) { if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) report_error(table, error); - return -1; + DBUG_RETURN(-1); } - return 0; + DBUG_RETURN(0); } @@ -17727,6 +17748,8 @@ join_read_last(JOIN_TAB *tab) { TABLE *table=tab->table; int error= 0; + DBUG_ENTER("join_read_first"); + if (table->covering_keys.is_set(tab->index) && !table->no_keyread && !table->key_read) table->enable_keyread(); @@ -17740,9 +17763,9 @@ join_read_last(JOIN_TAB *tab) if (!error) error= table->file->prepare_index_scan(); if (error || (error= tab->table->file->ha_index_last(tab->table->record[0]))) - return report_error(table, error); + DBUG_RETURN(report_error(table, error)); - return 0; + DBUG_RETURN(0); } @@ -17856,7 +17879,13 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (!end_of_records) { if (join->table_count && - join->join_tab->is_using_loose_index_scan()) + (join->join_tab->is_using_loose_index_scan() || + /* + When order by used a loose scan as its input, the quick select may + be attached to pre_sort_join_tab. + */ + (join->pre_sort_join_tab && + join->pre_sort_join_tab->is_using_loose_index_scan()))) { /* Copy non-aggregated fields when loose index scan is used. */ copy_fields(&join->tmp_table_param); @@ -18097,11 +18126,14 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), { if (!table->file->is_fatal_error(error, HA_CHECK_DUP)) goto end; + bool is_duplicate; if (create_internal_tmp_table_from_heap(join->thd, table, join->tmp_table_param.start_recinfo, &join->tmp_table_param.recinfo, - error,1)) + error, 1, &is_duplicate)) DBUG_RETURN(NESTED_LOOP_ERROR); // Not a table_is_full error + if (is_duplicate) + goto end; table->s->uniques=0; // To ensure rows are the same } if (++join->send_records >= join->tmp_table_param.end_write_records && @@ -18186,7 +18218,7 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (create_internal_tmp_table_from_heap(join->thd, table, join->tmp_table_param.start_recinfo, &join->tmp_table_param.recinfo, - error, 0)) + error, 0, NULL)) DBUG_RETURN(NESTED_LOOP_ERROR); // Not a table_is_full error /* Change method to update rows */ if ((error= table->file->ha_index_init(0, 0))) @@ -18291,7 +18323,7 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), create_internal_tmp_table_from_heap(join->thd, table, join->tmp_table_param.start_recinfo, &join->tmp_table_param.recinfo, - error, 0)) + error, 0, NULL)) DBUG_RETURN(NESTED_LOOP_ERROR); } if (join->rollup.state != ROLLUP::STATE_NONE) @@ -19697,6 +19729,9 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, MY_THREAD_SPECIFIC)); table->status=0; // May be wrong if quick_select + if (!tab->preread_init_done && tab->preread_init()) + goto err; + // If table has a range, move it to select if (select && !select->quick && tab->ref.key >= 0) { @@ -19733,8 +19768,6 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, get_schema_tables_result(join, PROCESSED_BY_CREATE_SORT_INDEX)) goto err; - if (!tab->preread_init_done && tab->preread_init()) - goto err; if (table->s->tmp_table) table->file->info(HA_STATUS_VARIABLE); // Get record count filesort_retval= filesort(thd, table, join->sortorder, length, @@ -22046,7 +22079,7 @@ int JOIN::rollup_write_data(uint idx, TABLE *table_arg) if (create_internal_tmp_table_from_heap(thd, table_arg, tmp_table_param.start_recinfo, &tmp_table_param.recinfo, - write_error, 0)) + write_error, 0, NULL)) return 1; } } diff --git a/sql/sql_select.h b/sql/sql_select.h index d1f11b8ae71..9ff08a3bc03 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -1319,6 +1319,12 @@ public: pre_sort_join_tab= NULL; emb_sjm_nest= NULL; sjm_lookup_tables= 0; + /* + The following is needed because JOIN::cleanup(true) may be called for + joins for which JOIN::optimize was aborted with an error before a proper + query plan was produced + */ + table_access_tabs= NULL; } int prepare(Item ***rref_pointer_array, TABLE_LIST *tables, uint wind_num, @@ -1836,11 +1842,12 @@ void free_tmp_table(THD *thd, TABLE *entry); bool create_internal_tmp_table_from_heap(THD *thd, TABLE *table, TMP_ENGINE_COLUMNDEF *start_recinfo, TMP_ENGINE_COLUMNDEF **recinfo, - int error, bool ignore_last_dupp_key_error); + int error, bool ignore_last_dupp_key_error, + bool *is_duplicate); bool create_internal_tmp_table(TABLE *table, KEY *keyinfo, TMP_ENGINE_COLUMNDEF *start_recinfo, TMP_ENGINE_COLUMNDEF **recinfo, - ulonglong options, my_bool big_tables); + ulonglong options); bool open_tmp_table(TABLE *table); void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps); double prev_record_reads(POSITION *positions, uint idx, table_map found_ref); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 4a39918988b..d5a52ed0b52 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -831,7 +831,7 @@ find_files(THD *thd, Dynamic_array<LEX_STRING*> *files, LEX_STRING *db, } else { - if (ha_discover_table_names(thd, db, dirp, &tl)) + if (ha_discover_table_names(thd, db, dirp, &tl, false)) goto err; } @@ -2242,10 +2242,10 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) thd_info->host= thd->strdup(tmp_sctx->host_or_ip[0] ? tmp_sctx->host_or_ip : tmp_sctx->host ? tmp_sctx->host : ""); - if ((thd_info->db=tmp->db)) // Safe test - thd_info->db=thd->strdup(thd_info->db); thd_info->command=(int) tmp->get_command(); mysql_mutex_lock(&tmp->LOCK_thd_data); + if ((thd_info->db= tmp->db)) // Safe test + thd_info->db= thd->strdup(thd_info->db); if ((mysys_var= tmp->mysys_var)) mysql_mutex_lock(&mysys_var->mutex); thd_info->proc_info= (char*) (tmp->killed >= KILL_QUERY ? @@ -2500,6 +2500,8 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond) my_hrtime_t unow= my_hrtime(); DBUG_ENTER("fill_schema_processlist"); + DEBUG_SYNC(thd,"fill_schema_processlist_after_unow"); + user= thd->security_ctx->master_access & PROCESS_ACL ? NullS : thd->security_ctx->priv_user; @@ -2558,9 +2560,8 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond) table->field[4]->store(command_name[tmp->get_command()].str, command_name[tmp->get_command()].length, cs); /* MYSQL_TIME */ - const ulonglong utime= (tmp->start_time ? - (unow.val - tmp->start_time * HRTIME_RESOLUTION - - tmp->start_time_sec_part) : 0); + ulonglong start_utime= tmp->start_time * HRTIME_RESOLUTION + tmp->start_time_sec_part; + ulonglong utime= start_utime < unow.val ? unow.val - start_utime : 0; table->field[5]->store(utime / HRTIME_RESOLUTION, TRUE); /* STATE */ if ((val= thread_state_info(tmp))) @@ -2761,12 +2762,11 @@ void remove_status_vars(SHOW_VAR *list) { mysql_mutex_lock(&LOCK_status); SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *); - int a= 0, b= all_status_vars.elements, c= (a+b)/2; for (; list->name; list++) { - int res= 0; - for (a= 0, b= all_status_vars.elements; b-a > 1; c= (a+b)/2) + int res= 0, a= 0, b= all_status_vars.elements, c= (a+b)/2; + for (; b-a > 0; c= (a+b)/2) { res= show_var_cmp(list, all+c); if (res < 0) @@ -2966,6 +2966,14 @@ static bool show_status_array(THD *thd, const char *wild, { if (!(pos= *(char**) value)) pos= ""; + + DBUG_EXECUTE_IF("alter_server_version_str", + if (!my_strcasecmp(system_charset_info, + variables->name, + "version")) { + pos= "some-other-version"; + }); + end= strend(pos); break; } @@ -3369,7 +3377,7 @@ bool schema_table_store_record(THD *thd, TABLE *table) { TMP_TABLE_PARAM *param= table->pos_in_table_list->schema_table_param; if (create_internal_tmp_table_from_heap(thd, table, param->start_recinfo, - ¶m->recinfo, error, 0)) + ¶m->recinfo, error, 0, NULL)) return 1; } @@ -4914,7 +4922,7 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, if (share->db_type() == partition_hton && share->partition_info_str_len) { - tmp_db_type= share->default_part_db_type; + tmp_db_type= plugin_hton(share->default_part_plugin); is_partitioned= TRUE; } #endif @@ -5395,7 +5403,7 @@ static my_bool iter_schema_engines(THD *thd, plugin_ref plugin, void *ptable) { TABLE *table= (TABLE *) ptable; - handlerton *hton= plugin_data(plugin, handlerton *); + handlerton *hton= plugin_hton(plugin); const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS; CHARSET_INFO *scs= system_charset_info; handlerton *default_type= ha_default_handlerton(thd); @@ -5581,7 +5589,7 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table, CHARSET_INFO *cs= system_charset_info; char params_buff[MAX_FIELD_WIDTH], returns_buff[MAX_FIELD_WIDTH], sp_db_buff[NAME_LEN], sp_name_buff[NAME_LEN], path[FN_REFLEN], - definer_buff[USERNAME_LENGTH + HOSTNAME_LENGTH + 1]; + definer_buff[DEFINER_LENGTH + 1]; String params(params_buff, sizeof(params_buff), cs); String returns(returns_buff, sizeof(returns_buff), cs); String sp_db(sp_db_buff, sizeof(sp_db_buff), cs); @@ -5725,7 +5733,7 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table, LEX *lex= thd->lex; CHARSET_INFO *cs= system_charset_info; char sp_db_buff[SAFE_NAME_LEN + 1], sp_name_buff[NAME_LEN + 1], - definer_buff[USERNAME_LENGTH + HOSTNAME_LENGTH + 2], + definer_buff[DEFINER_LENGTH + 1], returns_buff[MAX_FIELD_WIDTH]; String sp_db(sp_db_buff, sizeof(sp_db_buff), cs); @@ -8052,7 +8060,7 @@ static my_bool run_hton_fill_schema_table(THD *thd, plugin_ref plugin, { struct run_hton_fill_schema_table_args *args= (run_hton_fill_schema_table_args *) arg; - handlerton *hton= plugin_data(plugin, handlerton *); + handlerton *hton= plugin_hton(plugin); if (hton->fill_is_table && hton->state == SHOW_OPTION_YES) hton->fill_is_table(hton, thd, args->tables, args->cond, get_schema_table_idx(args->tables->schema_table)); @@ -8297,7 +8305,7 @@ ST_FIELD_INFO events_fields_info[]= SKIP_OPEN_TABLE}, {"EVENT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name", SKIP_OPEN_TABLE}, - {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer", SKIP_OPEN_TABLE}, + {"DEFINER", DEFINER_CHAR_LENGTH, MYSQL_TYPE_STRING, 0, 0, "Definer", SKIP_OPEN_TABLE}, {"TIME_ZONE", 64, MYSQL_TYPE_STRING, 0, 0, "Time zone", SKIP_OPEN_TABLE}, {"EVENT_BODY", 8, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, {"EVENT_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, @@ -8374,7 +8382,7 @@ ST_FIELD_INFO proc_fields_info[]= {"SQL_MODE", 32*256, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, {"ROUTINE_COMMENT", 65535, MYSQL_TYPE_STRING, 0, 0, "Comment", SKIP_OPEN_TABLE}, - {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer", SKIP_OPEN_TABLE}, + {"DEFINER", DEFINER_CHAR_LENGTH, MYSQL_TYPE_STRING, 0, 0, "Definer", SKIP_OPEN_TABLE}, {"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, "character_set_client", SKIP_OPEN_TABLE}, {"COLLATION_CONNECTION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, @@ -8419,7 +8427,7 @@ ST_FIELD_INFO view_fields_info[]= {"VIEW_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY}, {"CHECK_OPTION", 8, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY}, {"IS_UPDATABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, - {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY}, + {"DEFINER", DEFINER_CHAR_LENGTH, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY}, {"SECURITY_TYPE", 7, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY}, {"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY}, @@ -8564,7 +8572,7 @@ ST_FIELD_INFO triggers_fields_info[]= {"ACTION_REFERENCE_NEW_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY}, {"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 1, "Created", OPEN_FRM_ONLY}, {"SQL_MODE", 32*256, MYSQL_TYPE_STRING, 0, 0, "sql_mode", OPEN_FRM_ONLY}, - {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer", OPEN_FRM_ONLY}, + {"DEFINER", DEFINER_CHAR_LENGTH, MYSQL_TYPE_STRING, 0, 0, "Definer", OPEN_FRM_ONLY}, {"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, "character_set_client", OPEN_FRM_ONLY}, {"COLLATION_CONNECTION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, diff --git a/sql/sql_state.c b/sql/sql_state.c index 5acf97f16cc..c733d4b37c0 100644 --- a/sql/sql_state.c +++ b/sql/sql_state.c @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /* Functions to map mysqld errno to sql_state */ diff --git a/sql/sql_string.h b/sql/sql_string.h index 4ce08a5d9e6..1979ac6e4af 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -2,8 +2,8 @@ #define SQL_STRING_INCLUDED /* - Copyright (c) 2000, 2012, Oracle and/or its affiliates. - Copyright (c) 2008, 2011, Monty Program Ab + Copyright (c) 2000, 2013, Oracle and/or its affiliates. + Copyright (c) 2008, 2013, Monty Program Ab. 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 @@ -323,6 +323,7 @@ public: DBUG_ASSERT(!s.uses_buffer_owned_by(this)); free(); Ptr=s.Ptr ; str_length=s.str_length ; Alloced_length=s.Alloced_length; + str_charset=s.str_charset; } return *this; } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 4b3997dec3c..35a486a960a 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -196,7 +196,6 @@ uint explain_filename(THD* thd, uint to_length, enum_explain_filename_mode explain_mode) { - uint res= 0; char *to_p= to; char *end_p= to_p + to_length; const char *db_name= NULL; @@ -207,7 +206,8 @@ uint explain_filename(THD* thd, int part_name_len= 0; const char *subpart_name= NULL; int subpart_name_len= 0; - uint name_variant= NORMAL_PART_NAME; + uint part_type= NORMAL_PART_NAME; + const char *tmp_p; DBUG_ENTER("explain_filename"); DBUG_PRINT("enter", ("from '%s'", from)); @@ -226,17 +226,18 @@ uint explain_filename(THD* thd, table_name= tmp_p; } tmp_p= table_name; - while (!res && (tmp_p= strchr(tmp_p, '#'))) + /* Look if there are partition tokens in the table name. */ + while ((tmp_p= strchr(tmp_p, '#'))) { tmp_p++; switch (tmp_p[0]) { case 'P': case 'p': if (tmp_p[1] == '#') + { part_name= tmp_p + 2; - else - res= 1; - tmp_p+= 2; + tmp_p+= 2; + } break; case 'S': case 's': @@ -246,48 +247,32 @@ uint explain_filename(THD* thd, subpart_name= tmp_p + 3; tmp_p+= 3; } - else if ((tmp_p[1] == 'Q' || tmp_p[1] == 'q') && - (tmp_p[2] == 'L' || tmp_p[2] == 'l') && - tmp_p[3] == '-') - { - tmp_p+= 4; /* sql- prefix found */ - } - else - res= 2; break; case 'T': case 't': if ((tmp_p[1] == 'M' || tmp_p[1] == 'm') && (tmp_p[2] == 'P' || tmp_p[2] == 'p') && tmp_p[3] == '#' && !tmp_p[4]) - name_variant= TEMP_PART_NAME; - else - res= 3; - tmp_p+= 4; + { + part_type= TEMP_PART_NAME; + tmp_p+= 4; + } break; case 'R': case 'r': if ((tmp_p[1] == 'E' || tmp_p[1] == 'e') && (tmp_p[2] == 'N' || tmp_p[2] == 'n') && tmp_p[3] == '#' && !tmp_p[4]) - name_variant= RENAMED_PART_NAME; - else - res= 4; - tmp_p+= 4; + { + part_type= RENAMED_PART_NAME; + tmp_p+= 4; + } break; default: - res= 5; + /* Not partition name part. */ + ; } } - if (res) - { - /* Better to give something back if we fail parsing, than nothing at all */ - DBUG_PRINT("info", ("Error in explain_filename: %u", res)); - sql_print_warning("Invalid (old?) table or database name '%s'", from); - DBUG_RETURN(my_snprintf(to, to_length, - "<result %u when explaining filename '%s'>", - res, from)); - } if (part_name) { table_name_len= part_name - table_name - 3; @@ -295,7 +280,7 @@ uint explain_filename(THD* thd, subpart_name_len= strlen(subpart_name); else part_name_len= strlen(part_name); - if (name_variant != NORMAL_PART_NAME) + if (part_type != NORMAL_PART_NAME) { if (subpart_name) subpart_name_len-= 5; @@ -337,9 +322,9 @@ uint explain_filename(THD* thd, to_p= strnmov(to_p, " ", end_p - to_p); else to_p= strnmov(to_p, ", ", end_p - to_p); - if (name_variant != NORMAL_PART_NAME) + if (part_type != NORMAL_PART_NAME) { - if (name_variant == TEMP_PART_NAME) + if (part_type == TEMP_PART_NAME) to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_TEMPORARY_NAME), end_p - to_p); else @@ -391,31 +376,14 @@ uint filename_to_tablename(const char *from, char *to, uint to_length DBUG_ENTER("filename_to_tablename"); DBUG_PRINT("enter", ("from '%s'", from)); - if (!strncmp(from, tmp_file_prefix, tmp_file_prefix_length)) + res= strconvert(&my_charset_filename, from, + system_charset_info, to, to_length, &errors); + if (errors) // Old 5.0 name { - /* Temporary table name. */ - res= (strnmov(to, from, to_length) - to); - } - else - { - res= strconvert(&my_charset_filename, from, - system_charset_info, to, to_length, &errors); - if (errors) // Old 5.0 name - { - res= (strxnmov(to, to_length, MYSQL50_TABLE_NAME_PREFIX, from, NullS) - - to); -#ifndef DBUG_OFF - if (!stay_quiet) { -#endif /* DBUG_OFF */ - sql_print_error("Invalid (old?) table or database name '%s'", from); -#ifndef DBUG_OFF - } -#endif /* DBUG_OFF */ - /* - TODO: add a stored procedure for fix table and database names, - and mention its name in error log. - */ - } + res= (strxnmov(to, to_length, MYSQL50_TABLE_NAME_PREFIX, from, NullS) - + to); + if (IF_DBUG(!stay_quiet,0)) + sql_print_error("Invalid (old?) table or database name '%s'", from); } DBUG_PRINT("exit", ("to '%s'", to)); @@ -967,7 +935,7 @@ static int execute_ddl_log_action(THD *thd, DDL_LOG_ENTRY *ddl_log_entry) my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), ddl_log_entry->handler_name); goto error; } - hton= plugin_data(plugin, handlerton*); + hton= plugin_hton(plugin); file= get_new_handler((TABLE_SHARE*)0, &mem_root, hton); if (!file) { @@ -2234,9 +2202,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, alias= (lower_case_table_names == 2) ? table->alias : table->table_name; /* remove .frm file and engine files */ path_length= build_table_filename(path, sizeof(path) - 1, db, alias, - reg_ext, - table->internal_tmp_table ? - FN_IS_TMP : 0); + reg_ext, 0); /* This handles the case where a "DROP" was executed and a regular @@ -2270,8 +2236,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, } DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table"); error= 0; - if (!table->internal_tmp_table && - (drop_temporary || !ha_table_exists(thd, db, alias, &table_type) || + if ((drop_temporary || !ha_table_exists(thd, db, alias, &table_type) || (!drop_view && table_type == view_pseudo_hton))) { /* @@ -2280,10 +2245,6 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, . "DROP" but table was not found on disk and table can't be created from engine. . ./sql/datadict.cc +32 /Alfranio - TODO: We need to test this. - - Table->internal_tmp_table is set when one of the #sql-xxx files - was left in the datadir after a crash during ALTER TABLE. - See Bug#30152. */ if (if_exists) push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, @@ -2298,7 +2259,6 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, else { char *end; - /* It could happen that table's share in the table_def_cache is the only thing that keeps the engine plugin loaded @@ -2379,8 +2339,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, } else { - PSI_CALL_drop_table_share(table->internal_tmp_table, - table->db, table->db_length, + PSI_CALL_drop_table_share(false, table->db, table->db_length, table->table_name, table->table_name_length); mysql_audit_drop_table(thd, table); } @@ -2523,8 +2482,10 @@ bool quick_rm_table(handlerton *base,const char *db, error|= ha_delete_table(current_thd, base, path, db, table_name, 0); if (likely(error == 0)) + { PSI_CALL_drop_table_share(flags & FN_IS_TMP, db, strlen(db), table_name, strlen(table_name)); + } DBUG_RETURN(error); } @@ -6366,13 +6327,16 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, mysql_ha_rm_tables(thd, table_list); - mysql_audit_alter_table(thd, table_list); - /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */ if (alter_info->tablespace_op != NO_TABLESPACE_OP) + { + mysql_audit_alter_table(thd, table_list); + /* Conditionally writes to binlog. */ - DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list, - alter_info->tablespace_op)); + bool ret= mysql_discard_or_import_tablespace(thd,table_list, + alter_info->tablespace_op); + DBUG_RETURN(ret); + } /* Code below can handle only base tables so ensure that we won't open a view. @@ -6570,6 +6534,9 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, new_db, new_name); goto err; } + + if (table->s->tmp_table == NO_TMP_TABLE) + mysql_audit_alter_table(thd, table_list); THD_STAGE_INFO(thd, stage_setup); if (!(alter_info->flags & ~(ALTER_RENAME | ALTER_KEYS_ONOFF)) && diff --git a/sql/sql_time.cc b/sql/sql_time.cc index ff2ec62f815..a67768d4c34 100644 --- a/sql/sql_time.cc +++ b/sql/sql_time.cc @@ -330,7 +330,7 @@ str_to_datetime_with_warn(CHARSET_INFO *cs, @param nr integer part of the number to convert @param sec_part microsecond part of the number @param ltime converted value will be written here - @param fuzzydate conversion flags (TIME_FUZZY_DATE, etc) + @param fuzzydate conversion flags (TIME_INVALID_DATE, etc) @param str original number, as an ErrConv. For the warning @param field_name field name or NULL if not a field. For the warning @@ -347,6 +347,7 @@ static bool number_to_time_with_warn(bool neg, ulonglong nr, ulong sec_part, if (fuzzydate & TIME_TIME_ONLY) { + fuzzydate= TIME_TIME_ONLY; // clear other flags f_type= MYSQL_TYPE_TIME; res= number_to_time(neg, nr, sec_part, ltime, &was_cut); } @@ -356,7 +357,7 @@ static bool number_to_time_with_warn(bool neg, ulonglong nr, ulong sec_part, res= neg ? -1 : number_to_datetime(nr, sec_part, ltime, fuzzydate, &was_cut); } - if (res < 0 || (was_cut && !(fuzzydate & TIME_FUZZY_DATE))) + if (res < 0 || (was_cut && (fuzzydate & TIME_NO_ZERO_IN_DATE))) { make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, str, diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 35a4464b9e2..022c4ff4ea5 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #define MYSQL_LEX 1 diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 106c134223e..3cf7f576cbf 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -83,13 +83,16 @@ int select_union::send_data(List<Item> &values) */ return -1; } + bool is_duplicate; /* create_internal_tmp_table_from_heap will generate error if needed */ if (table->file->is_fatal_error(write_err, HA_CHECK_DUP) && create_internal_tmp_table_from_heap(thd, table, tmp_table_param.start_recinfo, &tmp_table_param.recinfo, - write_err, 1)) + write_err, 1, &is_duplicate)) return 1; + if (is_duplicate) + return -1; } return 0; } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 8413f612111..5edccd4e937 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1,5 +1,5 @@ -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. - Copyright (c) 2011 Monty Program Ab +/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. + Copyright (c) 2011, 2013, Monty Program Ab. 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 @@ -527,7 +527,10 @@ int mysql_update(THD *thd, /* If quick select is used, initialize it before retrieving rows. */ if (select && select->quick && select->quick->reset()) + { + close_cached_file(&tempfile); goto err; + } table->file->try_semi_consistent_read(1); /* @@ -579,13 +582,18 @@ int mysql_update(THD *thd, } else { - table->file->unlock_row(); + /* + Don't try unlocking the row if skip_record reported an error since in + this case the transaction might have been rolled back already. + */ if (error < 0) { /* Fatal error from select->skip_record() */ error= 1; break; } + else + table->file->unlock_row(); } } if (thd->killed && !error) @@ -822,8 +830,17 @@ int mysql_update(THD *thd, } } } - else + /* + Don't try unlocking the row if skip_record reported an error since in + this case the transaction might have been rolled back already. + */ + else if (!thd->is_error()) table->file->unlock_row(); + else + { + error= 1; + break; + } thd->warning_info->inc_current_row_for_warning(); if (thd->is_error()) { @@ -1990,7 +2007,7 @@ int multi_update::send_data(List<Item> ¬_used_values) create_internal_tmp_table_from_heap(thd, tmp_table, tmp_table_param[offset].start_recinfo, &tmp_table_param[offset].recinfo, - error, 1)) + error, 1, NULL)) { do_update= 0; DBUG_RETURN(1); // Not a table_is_full error diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 63df46c7094..01bbd5ecb9f 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #define MYSQL_LEX 1 diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 0dc8ed7037e..da8750a7ba4 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -892,6 +892,7 @@ static bool sp_create_assignment_instr(THD *thd, bool no_lookahead) Diag_condition_item_name diag_condition_item_name; DYNCALL_CREATE_DEF *dyncol_def; List<DYNCALL_CREATE_DEF> *dyncol_def_list; + bool is_not_empty; } %{ @@ -900,10 +901,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %pure_parser /* We have threads */ /* - Currently there are 167 shift/reduce conflicts. + Currently there are 189 shift/reduce conflicts. We should not introduce new conflicts any more. */ -%expect 167 +%expect 189 /* Comments for TOKENS. @@ -1758,7 +1759,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); precision subselect_start opt_and charset subselect_end select_var_list select_var_list_init help field_length opt_field_length - opt_extended_describe + opt_extended_describe shutdown prepare prepare_src execute deallocate statement sp_suid sp_c_chistics sp_a_chistics sp_chistic sp_c_chistic xa @@ -1797,7 +1798,7 @@ END_OF_INPUT %type <lex> sp_cursor_stmt %type <spname> sp_name %type <index_hint> index_hint_type -%type <num> index_hint_clause +%type <num> index_hint_clause normal_join inner_join %type <filetype> data_or_xml %type <NONE> signal_stmt resignal_stmt @@ -1808,7 +1809,7 @@ END_OF_INPUT ',' '!' '{' '}' '&' '|' AND_SYM OR_SYM OR_OR_SYM BETWEEN_SYM CASE_SYM THEN_SYM WHEN_SYM DIV_SYM MOD_SYM OR2_SYM AND_AND_SYM DELETE_SYM -%type <num> normal_join inner_join +%type <is_not_empty> opt_union_order_or_limit %% @@ -1936,6 +1937,7 @@ statement: | set | signal_stmt | show + | shutdown | slave | start | truncate @@ -5504,7 +5506,7 @@ storage_engines: plugin_ref plugin= ha_resolve_by_name(YYTHD, &$1); if (plugin) - $$= plugin_data(plugin, handlerton*); + $$= plugin_hton(plugin); else { if (YYTHD->variables.sql_mode & MODE_NO_ENGINE_SUBSTITUTION) @@ -5526,7 +5528,7 @@ known_storage_engines: { plugin_ref plugin; if ((plugin= ha_resolve_by_name(YYTHD, &$1))) - $$= plugin_data(plugin, handlerton*); + $$= plugin_hton(plugin); else { my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), $1.str); @@ -9767,6 +9769,7 @@ sum_expr: if ($$ == NULL) MYSQL_YYABORT; $5->empty(); + sel->gorder_list.empty(); } ; @@ -9836,18 +9839,27 @@ opt_gconcat_separator: opt_gorder_clause: /* empty */ + | ORDER_SYM BY { - Select->gorder_list = NULL; - } - | order_clause - { - SELECT_LEX *select= Select; - select->gorder_list= new (YYTHD->mem_root) - SQL_I_List<ORDER>(select->order_list); - if (select->gorder_list == NULL) + LEX *lex= Lex; + SELECT_LEX *sel= lex->current_select; + if (sel->linkage != GLOBAL_OPTIONS_TYPE && + sel->olap != UNSPECIFIED_OLAP_TYPE && + (sel->linkage != UNION_TYPE || sel->braces)) + { + my_error(ER_WRONG_USAGE, MYF(0), + "CUBE/ROLLUP", "ORDER BY"); MYSQL_YYABORT; - select->order_list.empty(); + } } + gorder_list; + ; + +gorder_list: + gorder_list ',' order_ident order_dir + { if (add_gorder_to_list(YYTHD, $3,(bool) $4)) MYSQL_YYABORT; } + | order_ident order_dir + { if (add_gorder_to_list(YYTHD, $1,(bool) $2)) MYSQL_YYABORT; } ; in_sum_expr: @@ -9980,7 +9992,10 @@ table_ref: { LEX *lex= Lex; if (!($$= lex->current_select->nest_last_join(lex->thd))) + { + my_parse_error(ER(ER_SYNTAX_ERROR)); MYSQL_YYABORT; + } } ; @@ -10245,12 +10260,16 @@ table_factor: lex->pop_context(); lex->nest_level--; } - else if (($3->select_lex && + /*else if (($3->select_lex && $3->select_lex->master_unit()->is_union() && ($3->select_lex->master_unit()->first_select() == - $3->select_lex || !$3->lifted)) || $5) + $3->select_lex || !$3->lifted)) || $5)*/ + else if ($5 != NULL) { - /* simple nested joins cannot have aliases or unions */ + /* + Tables with or without joins within parentheses cannot + have aliases, and we ruled out derived tables above. + */ my_parse_error(ER(ER_SYNTAX_ERROR)); MYSQL_YYABORT; } @@ -10263,8 +10282,34 @@ table_factor: } ; +/* + This rule accepts just about anything. The reason is that we have + empty-producing rules in the beginning of rules, in this case + subselect_start. This forces bison to take a decision which rules to + reduce by long before it has seen any tokens. This approach ties us + to a very limited class of parseable languages, and unfortunately + SQL is not one of them. The chosen 'solution' was this rule, which + produces just about anything, even complete bogus statements, for + instance ( table UNION SELECT 1 ). + Fortunately, we know that the semantic value returned by + select_derived is NULL if it contained a derived table, and a pointer to + the base table's TABLE_LIST if it was a base table. So in the rule + regarding union's, we throw a parse error manually and pretend it + was bison that did it. + + Also worth noting is that this rule concerns query expressions in + the from clause only. Top level select statements and other types of + subqueries have their own union rules. +*/ select_derived_union: select_derived opt_union_order_or_limit + { + if ($1 && $2) + { + my_parse_error(ER(ER_SYNTAX_ERROR)); + MYSQL_YYABORT; + } + } | select_derived_union UNION_SYM union_option @@ -10281,6 +10326,13 @@ select_derived_union: Lex->pop_context(); } opt_union_order_or_limit + { + if ($1 != NULL) + { + my_parse_error(ER(ER_SYNTAX_ERROR)); + MYSQL_YYABORT; + } + } ; /* The equivalent of select_init2 for nested queries. */ @@ -11754,7 +11806,9 @@ show: bzero((char*) &lex->create_info,sizeof(lex->create_info)); } show_param - {} + { + Select->parsing_place= NO_MATTER; + } ; show_param: @@ -12167,7 +12221,10 @@ describe: if (prepare_schema_table(YYTHD, lex, $2, SCH_COLUMNS)) MYSQL_YYABORT; } - opt_describe_column {} + opt_describe_column + { + Select->parsing_place= NO_MATTER; + } | describe_command opt_extended_describe { Lex->describe|= DESCRIBE_NORMAL; } select @@ -12422,6 +12479,11 @@ kill_expr: } ; + +shutdown: + SHUTDOWN { Lex->sql_command= SQLCOM_SHUTDOWN; } + ; + /* change database */ use: @@ -14993,8 +15055,8 @@ union_opt: ; opt_union_order_or_limit: - /* Empty */ - | union_order_or_limit + /* Empty */{ $$= false; } + | union_order_or_limit { $$= true; } ; union_order_or_limit: diff --git a/sql/strfunc.cc b/sql/strfunc.cc index aa6d2535b0d..48c77c7c99f 100644 --- a/sql/strfunc.cc +++ b/sql/strfunc.cc @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /* Some useful string utility functions used by the MySQL server */ diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 01745eba252..34ff98f3e78 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -349,7 +349,7 @@ static Sys_var_ulonglong Sys_binlog_cache_size( "you can increase this to get more performance", GLOBAL_VAR(binlog_cache_size), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(IO_SIZE, ULONGLONG_MAX), DEFAULT(32768), BLOCK_SIZE(IO_SIZE)); + VALID_RANGE(IO_SIZE, SIZE_T_MAX), DEFAULT(32768), BLOCK_SIZE(IO_SIZE)); static Sys_var_ulonglong Sys_binlog_stmt_cache_size( "binlog_stmt_cache_size", "The size of the statement cache for " @@ -358,7 +358,7 @@ static Sys_var_ulonglong Sys_binlog_stmt_cache_size( "you can increase this to get more performance", GLOBAL_VAR(binlog_stmt_cache_size), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(IO_SIZE, ULONGLONG_MAX), DEFAULT(32768), BLOCK_SIZE(IO_SIZE)); + VALID_RANGE(IO_SIZE, SIZE_T_MAX), DEFAULT(32768), BLOCK_SIZE(IO_SIZE)); /* Some variables like @sql_log_bin and @binlog_format change how/if binlogging @@ -491,7 +491,7 @@ static Sys_var_ulonglong Sys_bulk_insert_buff_size( "bulk_insert_buffer_size", "Size of tree cache used in bulk " "insert optimisation. Note that this is a limit per thread!", SESSION_VAR(bulk_insert_buff_size), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(0, ULONGLONG_MAX), DEFAULT(8192*1024), BLOCK_SIZE(1)); + VALID_RANGE(0, SIZE_T_MAX), DEFAULT(8192*1024), BLOCK_SIZE(1)); static Sys_var_charptr Sys_character_sets_dir( "character_sets_dir", "Directory where character sets are", @@ -983,7 +983,7 @@ static Sys_var_ulonglong Sys_join_buffer_size( "join_buffer_size", "The size of the buffer that is used for joins", SESSION_VAR(join_buff_size), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(128, ULONGLONG_MAX), DEFAULT(128*1024), BLOCK_SIZE(128)); + VALID_RANGE(128, SIZE_T_MAX), DEFAULT(128*1024), BLOCK_SIZE(128)); static Sys_var_keycache Sys_key_buffer_size( "key_buffer_size", "The size of the buffer used for " @@ -1223,16 +1223,16 @@ static Sys_var_ulonglong Sys_max_binlog_cache_size( "max_binlog_cache_size", "Sets the total size of the transactional cache", GLOBAL_VAR(max_binlog_cache_size), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(IO_SIZE, ULONGLONG_MAX), - DEFAULT((ULONGLONG_MAX/IO_SIZE)*IO_SIZE), + VALID_RANGE(IO_SIZE, SIZE_T_MAX), + DEFAULT((SIZE_T_MAX/IO_SIZE)*IO_SIZE), BLOCK_SIZE(IO_SIZE)); static Sys_var_ulonglong Sys_max_binlog_stmt_cache_size( "max_binlog_stmt_cache_size", "Sets the total size of the statement cache", GLOBAL_VAR(max_binlog_stmt_cache_size), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(IO_SIZE, ULONGLONG_MAX), - DEFAULT((ULONGLONG_MAX/IO_SIZE)*IO_SIZE), + VALID_RANGE(IO_SIZE, SIZE_T_MAX), + DEFAULT((SIZE_T_MAX/IO_SIZE)*IO_SIZE), BLOCK_SIZE(IO_SIZE)); static bool fix_max_binlog_size(sys_var *self, THD *thd, enum_var_type type) @@ -1333,6 +1333,21 @@ static Sys_var_ulong Sys_pseudo_thread_id( BLOCK_SIZE(1), NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_has_super)); +static bool +check_gtid_domain_id(sys_var *self, THD *thd, set_var *var) +{ + if (check_has_super(self, thd, var)) + return true; + if (var->type != OPT_GLOBAL && + error_if_in_trans_or_substatement(thd, + ER_STORED_FUNCTION_PREVENTS_SWITCH_GTID_DOMAIN_ID_SEQ_NO, + ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_GTID_DOMAIN_ID_SEQ_NO)) + return true; + + return false; +} + + static Sys_var_uint Sys_gtid_domain_id( "gtid_domain_id", "Used with global transaction ID to identify logically independent " @@ -1343,7 +1358,7 @@ static Sys_var_uint Sys_gtid_domain_id( SESSION_VAR(gtid_domain_id), CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, UINT_MAX32), DEFAULT(0), BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, - ON_CHECK(check_has_super)); + ON_CHECK(check_gtid_domain_id)); static bool check_gtid_seq_no(sys_var *self, THD *thd, set_var *var) @@ -1353,6 +1368,11 @@ static bool check_gtid_seq_no(sys_var *self, THD *thd, set_var *var) if (check_has_super(self, thd, var)) return true; + if (error_if_in_trans_or_substatement(thd, + ER_STORED_FUNCTION_PREVENTS_SWITCH_GTID_DOMAIN_ID_SEQ_NO, + ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_GTID_DOMAIN_ID_SEQ_NO)) + return true; + domain_id= thd->variables.gtid_domain_id; server_id= thd->variables.server_id; seq_no= (uint64)var->value->val_uint(); @@ -2254,7 +2274,7 @@ static Sys_var_ulonglong Sys_query_cache_size( "query_cache_size", "The memory allocated to store results from old queries", GLOBAL_VAR(query_cache_size), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(0, ULONGLONG_MAX), DEFAULT(0), BLOCK_SIZE(1024), + VALID_RANGE(0, ULONG_MAX), DEFAULT(0), BLOCK_SIZE(1024), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_query_cache_size), ON_UPDATE(fix_query_cache_size)); @@ -2461,7 +2481,7 @@ static Sys_var_ulonglong Sys_sort_buffer( "sort_buffer_size", "Each thread that needs to do a sort allocates a buffer of this size", SESSION_VAR(sortbuff_size), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(MIN_SORT_MEMORY, ULONGLONG_MAX), DEFAULT(MAX_SORT_MEMORY), + VALID_RANGE(MIN_SORT_MEMORY, SIZE_T_MAX), DEFAULT(MAX_SORT_MEMORY), BLOCK_SIZE(1)); export ulonglong expand_sql_mode(ulonglong sql_mode) @@ -3327,7 +3347,7 @@ static Sys_var_ulonglong Sys_group_concat_max_len( "group_concat_max_len", "The maximum length of the result of function GROUP_CONCAT()", SESSION_VAR(group_concat_max_len), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(4, ULONGLONG_MAX), DEFAULT(1024), BLOCK_SIZE(1)); + VALID_RANGE(4, SIZE_T_MAX), DEFAULT(1024), BLOCK_SIZE(1)); static char *glob_hostname_ptr; static Sys_var_charptr Sys_hostname( diff --git a/sql/table.cc b/sql/table.cc index 32a841ffd46..0be93aaec65 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -13,7 +13,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /* Some general useful functions */ @@ -454,6 +454,7 @@ void TABLE_SHARE::destroy() ha_data_destroy= NULL; } #ifdef WITH_PARTITION_STORAGE_ENGINE + plugin_unlock(NULL, default_part_plugin); if (ha_part_data_destroy) { ha_part_data_destroy(ha_part_data); @@ -605,10 +606,19 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags) share->error= OPEN_FRM_OPEN_ERROR; strxmov(path, share->normalized_path.str, reg_ext, NullS); - file= mysql_file_open(key_file_frm, path, O_RDONLY | O_SHARE, MYF(0)); + if (flags & GTS_FORCE_DISCOVERY) + { + DBUG_ASSERT(flags & GTS_TABLE); + DBUG_ASSERT(flags & GTS_USE_DISCOVERY); + mysql_file_delete_with_symlink(key_file_frm, path, MYF(0)); + file= -1; + } + else + file= mysql_file_open(key_file_frm, path, O_RDONLY | O_SHARE, MYF(0)); + if (file < 0) { - if ((flags & GTS_TABLE) && (flags & GTS_FORCE_DISCOVERY)) + if ((flags & GTS_TABLE) && (flags & GTS_USE_DISCOVERY)) { ha_discover_table(thd, share); error_given= true; @@ -798,6 +808,16 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, options= extra2; options_len= length; break; + case EXTRA2_DEFAULT_PART_ENGINE: +#ifdef WITH_PARTITION_STORAGE_ENGINE + { + LEX_STRING name= { (char*)extra2, length }; + share->default_part_plugin= ha_resolve_by_name(NULL, &name); + if (!share->default_part_plugin) + goto err; + } +#endif + break; default: /* abort frm parsing if it's an unknown but important extra2 value */ if (type >= EXTRA2_ENGINE_IMPORTANT) @@ -828,11 +848,14 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, share->frm_version= FRM_VER_TRUE_VARCHAR; #ifdef WITH_PARTITION_STORAGE_ENGINE - if (frm_image[61] && - !(share->default_part_db_type= - ha_checktype(thd, (enum legacy_db_type) (uint) frm_image[61], 1, 0))) - goto err; - DBUG_PRINT("info", ("default_part_db_type = %u", frm_image[61])); + if (frm_image[61] && !share->default_part_plugin) + { + enum legacy_db_type db_type= (enum legacy_db_type) (uint) frm_image[61]; + share->default_part_plugin= + ha_lock_engine(NULL, ha_checktype(thd, db_type, 1, 0)); + if (!share->default_part_plugin) + goto err; + } #endif legacy_db_type= (enum legacy_db_type) (uint) frm_image[3]; /* @@ -1333,7 +1356,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, /* Allocate handler */ if (!(handler_file= get_new_handler(share, thd->mem_root, - plugin_data(se_plugin, handlerton *)))) + plugin_hton(se_plugin)))) goto err; record= share->default_values-1; /* Fieldstart = 1 */ @@ -2071,17 +2094,11 @@ int TABLE_SHARE::init_from_sql_statement_string(THD *thd, bool write, lex_start(thd); - if ((error= parse_sql(thd, & parser_state, NULL))) + if ((error= parse_sql(thd, & parser_state, NULL) || + sql_unusable_for_discovery(thd, sql_copy))) goto ret; - if (sql_unusable_for_discovery(thd, sql_copy)) - { - my_error(ER_SQL_DISCOVER_ERROR, MYF(0), plugin_name(db_plugin)->str, - db.str, table_name.str, sql_copy); - goto ret; - } - - thd->lex->create_info.db_type= plugin_data(db_plugin, handlerton *); + thd->lex->create_info.db_type= plugin_hton(db_plugin); if (tabledef_version.str) thd->lex->create_info.tabledef_version= tabledef_version; @@ -2111,8 +2128,10 @@ ret: if (thd->is_error() || error) { thd->clear_error(); - my_error(ER_NO_SUCH_TABLE, MYF(0), db.str, table_name.str); - DBUG_RETURN(HA_ERR_NOT_A_TABLE); + my_error(ER_SQL_DISCOVER_ERROR, MYF(0), + plugin_name(db_plugin)->str, db.str, table_name.str, + sql_copy); + DBUG_RETURN(HA_ERR_GENERIC); } DBUG_RETURN(0); } @@ -2125,7 +2144,7 @@ bool TABLE_SHARE::write_frm_image(const uchar *frm, size_t len) bool TABLE_SHARE::read_frm_image(const uchar **frm, size_t *len) { - if (partition_info_str) // cannot discover a partition + if (IF_PARTITIONING(partition_info_str, 0)) // cannot discover a partition { DBUG_ASSERT(db_type()->discover_table == 0); return 1; @@ -2697,7 +2716,7 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share, tmp= mysql_unpack_partition(thd, share->partition_info_str, share->partition_info_str_len, outparam, is_create_table, - share->default_part_db_type, + plugin_hton(share->default_part_plugin), &work_part_info_used); if (tmp) { @@ -2793,8 +2812,22 @@ partititon_err: !(ha_open_flags & HA_OPEN_FOR_REPAIR)); outparam->file->print_error(ha_err, MYF(0)); error_reported= TRUE; + if (ha_err == HA_ERR_TABLE_DEF_CHANGED) error= OPEN_FRM_DISCOVER; + + /* + We're here, because .frm file was successfully opened. + + But if the table doesn't exist in the engine and the engine + supports discovery, we force rediscover to discover + the fact that table doesn't in fact exist and remove + the stray .frm file. + */ + if (share->db_type()->discover_table && + (ha_err == ENOENT || ha_err == HA_ERR_NO_SUCH_TABLE)) + error= OPEN_FRM_DISCOVER; + goto err; } } @@ -4155,6 +4188,7 @@ bool TABLE_LIST::prep_where(THD *thd, Item **conds, bool no_where_clause) { DBUG_ENTER("TABLE_LIST::prep_where"); + bool res= FALSE; for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local) { @@ -4203,10 +4237,11 @@ bool TABLE_LIST::prep_where(THD *thd, Item **conds, if (tbl == 0) { if (*conds && !(*conds)->fixed) - (*conds)->fix_fields(thd, conds); - *conds= and_conds(*conds, where->copy_andor_structure(thd)); - if (*conds && !(*conds)->fixed) - (*conds)->fix_fields(thd, conds); + res= (*conds)->fix_fields(thd, conds); + if (!res) + *conds= and_conds(*conds, where->copy_andor_structure(thd)); + if (*conds && !(*conds)->fixed && !res) + res= (*conds)->fix_fields(thd, conds); } if (arena) thd->restore_active_arena(arena, &backup); @@ -4214,7 +4249,7 @@ bool TABLE_LIST::prep_where(THD *thd, Item **conds, } } - DBUG_RETURN(FALSE); + DBUG_RETURN(res); } /** diff --git a/sql/table.h b/sql/table.h index af79bffd437..c7282cee093 100644 --- a/sql/table.h +++ b/sql/table.h @@ -672,8 +672,7 @@ struct TABLE_SHARE inline handlerton *db_type() const /* table_type for handler */ { return is_view ? view_pseudo_hton : - db_plugin ? plugin_data(db_plugin, handlerton*) - : NULL; + db_plugin ? plugin_hton(db_plugin) : NULL; } enum row_type row_type; /* How rows are stored */ enum tmp_table_type tmp_table; @@ -742,7 +741,7 @@ struct TABLE_SHARE char *partition_info_str; uint partition_info_str_len; uint partition_info_buffer_size; - handlerton *default_part_db_type; + plugin_ref default_part_plugin; #endif /** @@ -1983,7 +1982,6 @@ struct TABLE_LIST /* For transactional locking. */ int lock_timeout; /* NOWAIT or WAIT [X] */ bool lock_transactional; /* If transactional lock requested. */ - bool internal_tmp_table; /** TRUE if an alias for this table was specified in the SQL. */ bool is_alias; /** TRUE if the table is referred to in the statement using a fully @@ -2497,7 +2495,8 @@ enum get_table_share_flags { GTS_TABLE = 1, GTS_VIEW = 2, GTS_NOLOCK = 4, - GTS_FORCE_DISCOVERY = 8 + GTS_USE_DISCOVERY = 8, + GTS_FORCE_DISCOVERY = 16 }; size_t max_row_length(TABLE *table, const uchar *data); diff --git a/sql/threadpool_common.cc b/sql/threadpool_common.cc index 147a59df9b7..5be06f0bdc8 100644 --- a/sql/threadpool_common.cc +++ b/sql/threadpool_common.cc @@ -72,14 +72,18 @@ struct Worker_thread_context void save() { +#ifdef HAVE_PSI_INTERFACE psi_thread= PSI_server?PSI_server->get_thread():0; +#endif mysys_var= (st_my_thread_var *)pthread_getspecific(THR_KEY_mysys); } void restore() { +#ifdef HAVE_PSI_INTERFACE if (PSI_server) PSI_server->set_thread(psi_thread); +#endif pthread_setspecific(THR_KEY_mysys,mysys_var); pthread_setspecific(THR_THD, 0); pthread_setspecific(THR_MALLOC, 0); @@ -95,8 +99,10 @@ static bool thread_attach(THD* thd) pthread_setspecific(THR_KEY_mysys,thd->mysys_var); thd->thread_stack=(char*)&thd; thd->store_globals(); +#ifdef HAVE_PSI_INTERFACE if (PSI_server) PSI_server->set_thread(thd->event_scheduler.m_psi); +#endif return 0; } @@ -123,11 +129,13 @@ int threadpool_add_connection(THD *thd) } /* Create new PSI thread for use with the THD. */ +#ifdef HAVE_PSI_INTERFACE if (PSI_server) { thd->event_scheduler.m_psi = PSI_server->new_thread(key_thread_one_connection, thd, thd->thread_id); } +#endif /* Login. */ diff --git a/sql/threadpool_unix.cc b/sql/threadpool_unix.cc index 658a04d877e..0f88d4920b8 100644 --- a/sql/threadpool_unix.cc +++ b/sql/threadpool_unix.cc @@ -52,6 +52,7 @@ static bool threadpool_started= false; */ +#ifdef HAVE_PSI_INTERFACE static PSI_mutex_key key_group_mutex; static PSI_mutex_key key_timer_mutex; static PSI_mutex_info mutex_list[]= @@ -79,6 +80,9 @@ static PSI_thread_info thread_list[] = /* Macro to simplify performance schema registration */ #define PSI_register(X) \ if(PSI_server) PSI_server->register_ ## X("threadpool", X ## _list, array_elements(X ## _list)) +#else +#define PSI_register(X) /* no-op */ +#endif struct thread_group_t; diff --git a/sql/transaction.cc b/sql/transaction.cc index 9a1952427d8..09de480e236 100644 --- a/sql/transaction.cc +++ b/sql/transaction.cc @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifdef USE_PRAGMA_IMPLEMENTATION diff --git a/sql/unireg.cc b/sql/unireg.cc index 04af09fd31c..388aa2863af 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -46,6 +46,38 @@ static bool pack_fields(uchar *, List<Create_field> &, ulong); static size_t packed_fields_length(List<Create_field> &); static bool make_empty_rec(THD *, uchar *, uint, List<Create_field> &, uint, ulong); +static uchar *extra2_write_len(uchar *pos, size_t len) +{ + if (len < 255) + *pos++= len; + else + { + /* + At the moment we support options_len up to 64K. + We can easily extend it in the future, if the need arises. + */ + DBUG_ASSERT(len <= 65535); + int2store(pos + 1, len); + pos+= 3; + } + return pos; +} + +static uchar *extra2_write(uchar *pos, enum extra2_frm_value_type type, + LEX_STRING *str) +{ + *pos++ = type; + pos= extra2_write_len(pos, str->length); + memcpy(pos, str->str, str->length); + return pos + str->length; +} + +static uchar *extra2_write(uchar *pos, enum extra2_frm_value_type type, + LEX_CUSTRING *str) +{ + return extra2_write(pos, type, reinterpret_cast<LEX_STRING *>(str)); +} + /** Create a frm (table definition) file @@ -72,9 +104,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, ulong filepos, data_offset; uint options_len; uchar fileinfo[FRM_HEADER_SIZE],forminfo[FRM_FORMINFO_SIZE]; -#ifdef WITH_PARTITION_STORAGE_ENGINE - partition_info *part_info= thd->work_part_info; -#endif + const partition_info *part_info= IF_PARTITIONING(thd->work_part_info, 0); int error; uchar *frm_ptr, *pos; LEX_CUSTRING frm= {0,0}; @@ -106,12 +136,8 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, => Total 6 byte */ create_info->extra_size+= 6; -#ifdef WITH_PARTITION_STORAGE_ENGINE if (part_info) - { create_info->extra_size+= part_info->part_info_len; - } -#endif for (i= 0; i < keys; i++) { @@ -205,6 +231,9 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, if (options_len) extra2_size+= 1 + (options_len > 255 ? 3 : 1) + options_len; + if (part_info) + extra2_size+= 1 + 1 + hton_name(part_info->default_engine_type)->length; + key_buff_length= uint4korr(fileinfo+47); frm.length= FRM_HEADER_SIZE; // fileinfo; @@ -228,27 +257,17 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, /* write the extra2 segment */ pos = frm_ptr + 64; compile_time_assert(EXTRA2_TABLEDEF_VERSION != '/'); - *pos++ = EXTRA2_TABLEDEF_VERSION; // old servers write '/' here - *pos++ = create_info->tabledef_version.length; - memcpy(pos, create_info->tabledef_version.str, - create_info->tabledef_version.length); - pos+= create_info->tabledef_version.length; + pos= extra2_write(pos, EXTRA2_TABLEDEF_VERSION, + &create_info->tabledef_version); + + if (part_info) + pos= extra2_write(pos, EXTRA2_DEFAULT_PART_ENGINE, + hton_name(part_info->default_engine_type)); if (options_len) { *pos++= EXTRA2_ENGINE_TABLEOPTS; - if (options_len < 255) - *pos++= options_len; - else - { - /* - At the moment we support options_len up to 64K. - We can easily extend it in the future, if the need arises. - */ - DBUG_ASSERT(options_len <= 65535); - int2store(pos + 1, options_len); - pos+= 3; - } + pos= extra2_write_len(pos, options_len); pos= engine_table_options_frm_image(pos, create_info->option_list, create_fields, keys, key_info); } @@ -265,13 +284,12 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, (create_info->min_rows == 1) && (keys == 0)); int2store(fileinfo+28,key_info_length); -#ifdef WITH_PARTITION_STORAGE_ENGINE if (part_info) { fileinfo[61]= (uchar) ha_legacy_type(part_info->default_engine_type); DBUG_PRINT("info", ("part_db_type = %d", fileinfo[61])); } -#endif + int2store(fileinfo+59,db_file->extra_rec_buf_length()); memcpy(frm_ptr, fileinfo, FRM_HEADER_SIZE); @@ -291,7 +309,6 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, memcpy(pos, str_db_type.str, str_db_type.length); pos+= str_db_type.length; -#ifdef WITH_PARTITION_STORAGE_ENGINE if (part_info) { char auto_partitioned= part_info->is_auto_partitioned ? 1 : 0; @@ -302,7 +319,6 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, *pos++= auto_partitioned; } else -#endif { pos+= 6; } diff --git a/sql/unireg.h b/sql/unireg.h index 5e232becbb2..c867f50197d 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -15,7 +15,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "my_global.h" /* ulonglong */ @@ -181,6 +181,7 @@ */ enum extra2_frm_value_type { EXTRA2_TABLEDEF_VERSION=0, + EXTRA2_DEFAULT_PART_ENGINE=1, #define EXTRA2_ENGINE_IMPORTANT 128 |