diff options
author | Mats Kindahl <mats@mysql.com> | 2008-08-20 10:42:39 +0200 |
---|---|---|
committer | Mats Kindahl <mats@mysql.com> | 2008-08-20 10:42:39 +0200 |
commit | 7207b18b25c5b0627a9a5c5b4261bd9a55cdd722 (patch) | |
tree | b6dadeb82cb80c268ee4966cb063a39024131014 /sql | |
parent | be0acc4bcb9fe038c3e10ddc33b708bd346502cf (diff) | |
parent | 09271b1e130eb67e072b6b41ed68f15a528785d7 (diff) | |
download | mariadb-git-7207b18b25c5b0627a9a5c5b4261bd9a55cdd722.tar.gz |
Merging with 5.1-rpl.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.h | 5 | ||||
-rw-r--r-- | sql/handler.cc | 2 | ||||
-rw-r--r-- | sql/item.cc | 12 | ||||
-rw-r--r-- | sql/item.h | 4 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 12 | ||||
-rw-r--r-- | sql/item_func.cc | 15 | ||||
-rw-r--r-- | sql/log.cc | 4 | ||||
-rw-r--r-- | sql/mysql_priv.h | 1 | ||||
-rw-r--r-- | sql/share/errmsg.txt | 2 | ||||
-rw-r--r-- | sql/sp_head.cc | 2 | ||||
-rw-r--r-- | sql/sql_acl.cc | 1 | ||||
-rw-r--r-- | sql/sql_base.cc | 2 | ||||
-rw-r--r-- | sql/sql_binlog.cc | 1 | ||||
-rw-r--r-- | sql/sql_class.cc | 24 | ||||
-rw-r--r-- | sql/sql_class.h | 19 | ||||
-rw-r--r-- | sql/sql_cursor.cc | 2 | ||||
-rw-r--r-- | sql/sql_insert.cc | 3 | ||||
-rw-r--r-- | sql/sql_lex.h | 4 | ||||
-rw-r--r-- | sql/sql_list.h | 4 | ||||
-rw-r--r-- | sql/sql_parse.cc | 40 | ||||
-rw-r--r-- | sql/sql_select.cc | 6 | ||||
-rw-r--r-- | sql/sql_show.cc | 27 | ||||
-rw-r--r-- | sql/sql_show.h | 2 | ||||
-rw-r--r-- | sql/sql_string.h | 2 | ||||
-rw-r--r-- | sql/sql_table.cc | 5 | ||||
-rw-r--r-- | sql/table.cc | 22 | ||||
-rw-r--r-- | sql/table.h | 3 |
27 files changed, 178 insertions, 48 deletions
diff --git a/sql/field.h b/sql/field.h index 7d312dbd2b8..36f494f6e50 100644 --- a/sql/field.h +++ b/sql/field.h @@ -13,7 +13,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - /* Because of the function new_field() all field classes that have static variables must declare the size_of() member function. @@ -51,7 +50,8 @@ class Field Field(const Item &); /* Prevent use of these */ void operator=(Field &); public: - static void *operator new(size_t size) {return sql_alloc(size); } + static void *operator new(size_t size) throw () + { return sql_alloc(size); } static void operator delete(void *ptr_arg, size_t size) { TRASH(ptr_arg, size); } uchar *ptr; // Position to field in record @@ -1669,6 +1669,7 @@ public: } int reset(void) { bzero(ptr, packlength+sizeof(uchar*)); return 0; } void reset_fields() { bzero((uchar*) &value,sizeof(value)); } + uint32 get_field_buffer_size(void) { return value.alloced_length(); } #ifndef WORDS_BIGENDIAN static #endif diff --git a/sql/handler.cc b/sql/handler.cc index fe4944ed836..9894b89f823 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -4393,6 +4393,8 @@ static int write_locked_table_maps(THD *thd) (long) thd, (long) thd->lock, (long) thd->locked_tables, (long) thd->extra_lock)); + DBUG_PRINT("debug", ("get_binlog_table_maps(): %d", thd->get_binlog_table_maps())); + if (thd->get_binlog_table_maps() == 0) { MYSQL_LOCK *locks[3]; diff --git a/sql/item.cc b/sql/item.cc index 5ee394fcbe0..48fcb232bab 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -437,8 +437,11 @@ uint Item::decimal_precision() const Item_result restype= result_type(); if ((restype == DECIMAL_RESULT) || (restype == INT_RESULT)) - return min(my_decimal_length_to_precision(max_length, decimals, unsigned_flag), - DECIMAL_MAX_PRECISION); + { + uint prec= + my_decimal_length_to_precision(max_length, decimals, unsigned_flag); + return min(prec, DECIMAL_MAX_PRECISION); + } return min(max_length, DECIMAL_MAX_PRECISION); } @@ -6995,8 +6998,9 @@ bool Item_type_holder::join_types(THD *thd, Item *item) if (Field::result_merge_type(fld_type) == DECIMAL_RESULT) { decimals= min(max(decimals, item->decimals), DECIMAL_MAX_SCALE); - int precision= min(max(prev_decimal_int_part, item->decimal_int_part()) - + decimals, DECIMAL_MAX_PRECISION); + int item_int_part= item->decimal_int_part(); + int item_prec = max(prev_decimal_int_part, item_int_part) + decimals; + int precision= min(item_prec, DECIMAL_MAX_PRECISION); unsigned_flag&= item->unsigned_flag; max_length= my_decimal_precision_to_length(precision, decimals, unsigned_flag); diff --git a/sql/item.h b/sql/item.h index 465d6f4d54c..2c9af80195b 100644 --- a/sql/item.h +++ b/sql/item.h @@ -467,9 +467,9 @@ class Item { Item(const Item &); /* Prevent use of these */ void operator=(Item &); public: - static void *operator new(size_t size) + static void *operator new(size_t size) throw () { return sql_alloc(size); } - static void *operator new(size_t size, MEM_ROOT *mem_root) + static void *operator new(size_t size, MEM_ROOT *mem_root) throw () { return alloc_root(mem_root, size); } static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); } static void operator delete(void *ptr, MEM_ROOT *mem_root) {} diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 28e55eef5bd..c76bbececef 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2163,8 +2163,11 @@ Item_func_ifnull::fix_length_and_dec() uint Item_func_ifnull::decimal_precision() const { - int max_int_part=max(args[0]->decimal_int_part(),args[1]->decimal_int_part()); - return min(max_int_part + decimals, DECIMAL_MAX_PRECISION); + int arg0_int_part= args[0]->decimal_int_part(); + int arg1_int_part= args[1]->decimal_int_part(); + int max_int_part= max(arg0_int_part, arg1_int_part); + int precision= max_int_part + decimals; + return min(precision, DECIMAL_MAX_PRECISION); } @@ -2345,8 +2348,9 @@ Item_func_if::fix_length_and_dec() uint Item_func_if::decimal_precision() const { - int precision=(max(args[1]->decimal_int_part(),args[2]->decimal_int_part())+ - decimals); + int arg1_prec= args[1]->decimal_int_part(); + int arg2_prec= args[2]->decimal_int_part(); + int precision=max(arg1_prec,arg2_prec) + decimals; return min(precision, DECIMAL_MAX_PRECISION); } diff --git a/sql/item_func.cc b/sql/item_func.cc index a17c1eff5dd..8bb6bb30117 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1139,9 +1139,10 @@ my_decimal *Item_func_plus::decimal_op(my_decimal *decimal_value) void Item_func_additive_op::result_precision() { decimals= max(args[0]->decimals, args[1]->decimals); - int max_int_part= max(args[0]->decimal_precision() - args[0]->decimals, - args[1]->decimal_precision() - args[1]->decimals); - int precision= min(max_int_part + 1 + decimals, DECIMAL_MAX_PRECISION); + int arg1_int= args[0]->decimal_precision() - args[0]->decimals; + int arg2_int= args[1]->decimal_precision() - args[1]->decimals; + int est_prec= max(arg1_int, arg2_int) + 1 + decimals; + int precision= min(est_prec, DECIMAL_MAX_PRECISION); /* Integer operations keep unsigned_flag if one of arguments is unsigned */ if (result_type() == INT_RESULT) @@ -1252,8 +1253,8 @@ void Item_func_mul::result_precision() else unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag; decimals= min(args[0]->decimals + args[1]->decimals, DECIMAL_MAX_SCALE); - int precision= min(args[0]->decimal_precision() + args[1]->decimal_precision(), - DECIMAL_MAX_PRECISION); + uint est_prec = args[0]->decimal_precision() + args[1]->decimal_precision(); + uint precision= min(est_prec, DECIMAL_MAX_PRECISION); max_length= my_decimal_precision_to_length(precision, decimals,unsigned_flag); } @@ -1300,8 +1301,8 @@ my_decimal *Item_func_div::decimal_op(my_decimal *decimal_value) void Item_func_div::result_precision() { - uint precision=min(args[0]->decimal_precision() + prec_increment, - DECIMAL_MAX_PRECISION); + uint arg_prec= args[0]->decimal_precision() + prec_increment; + uint precision=min(arg_prec, DECIMAL_MAX_PRECISION); /* Integer operations keep unsigned_flag if one of arguments is unsigned */ if (result_type() == INT_RESULT) unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag; diff --git a/sql/log.cc b/sql/log.cc index 30575b5befd..a6f3192b061 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1377,6 +1377,8 @@ binlog_end_trans(THD *thd, binlog_trx_data *trx_data, FLAGSTR(thd->options, OPTION_NOT_AUTOCOMMIT), FLAGSTR(thd->options, OPTION_BEGIN))); + thd->binlog_flush_pending_rows_event(TRUE); + /* NULL denotes ROLLBACK with nothing to replicate: i.e., rollback of only transactional tables. If the transaction contain changes to @@ -1395,8 +1397,6 @@ binlog_end_trans(THD *thd, binlog_trx_data *trx_data, were, we would have to ensure that we're not ending a statement inside a stored function. */ - thd->binlog_flush_pending_rows_event(TRUE); - error= mysql_bin_log.write(thd, &trx_data->trans_log, end_ev); trx_data->reset(); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index e150ffd18f8..f6ba5fc9739 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -2130,6 +2130,7 @@ int writefrm(const char* name, const uchar* data, size_t len); int closefrm(TABLE *table, bool free_share); int read_string(File file, uchar* *to, size_t length); void free_blobs(TABLE *table); +void free_field_buffers_larger_than(TABLE *table, uint32 size); int set_zone(int nr,int min_zone,int max_zone); ulong convert_period_to_month(ulong period); ulong convert_month_to_period(ulong month); diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 426290714eb..84eb5f5ba64 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -4718,7 +4718,7 @@ ER_SLAVE_IGNORED_TABLE swe "Slav SQL tråden ignorerade frågan pga en replicate-*-table regel" ER_INCORRECT_GLOBAL_LOCAL_VAR eng "Variable '%-.192s' is a %s variable" - serbian "Incorrect foreign key definition for '%-.192s': %s" + serbian "Promenljiva '%-.192s' je %s promenljiva" ger "Variable '%-.192s' ist eine %s-Variable" nla "Variabele '%-.192s' is geen %s variabele" spa "Variable '%-.192s' es una %s variable" diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 92dcafa7aa8..d1f920fd3a5 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -475,7 +475,7 @@ sp_head::operator new(size_t size) throw() init_sql_alloc(&own_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC); sp= (sp_head *) alloc_root(&own_root, size); if (sp == NULL) - return NULL; + DBUG_RETURN(NULL); sp->main_mem_root= own_root; DBUG_PRINT("info", ("mem_root 0x%lx", (ulong) &sp->mem_root)); DBUG_RETURN(sp); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 3704639a80d..226d41e0fb5 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -5701,7 +5701,6 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list) while ((tmp_user_name= user_list++)) { - user_name= get_current_user(thd, tmp_user_name); if (!(user_name= get_current_user(thd, tmp_user_name))) { result= TRUE; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index d25057789ac..39dd815e738 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1369,6 +1369,8 @@ bool close_thread_table(THD *thd, TABLE **table_ptr) DBUG_ASSERT(!table->is_children_attached()); /* Free memory and reset for next loop */ + free_field_buffers_larger_than(table,MAX_TDC_BLOB_SIZE); + table->file->ha_reset(); table->in_use=0; if (unused_tables) diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc index a6d0c8c9e9b..7ca7bef3a56 100644 --- a/sql/sql_binlog.cc +++ b/sql/sql_binlog.cc @@ -208,6 +208,7 @@ void mysql_client_binlog_statement(THD* thd) #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) if (apply_event_and_update_pos(ev, thd, thd->rli_fake, FALSE)) { + delete ev; /* TODO: Maybe a better error message since the BINLOG statement now contains several events. diff --git a/sql/sql_class.cc b/sql/sql_class.cc index c83ca0d1899..b6070c61974 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -3528,6 +3528,24 @@ int THD::binlog_flush_pending_rows_event(bool stmt_end) } +static const char * +show_query_type(THD::enum_binlog_query_type qtype) +{ + switch (qtype) { + case THD::ROW_QUERY_TYPE: + return "ROW"; + case THD::STMT_QUERY_TYPE: + return "STMT"; + case THD::MYSQL_QUERY_TYPE: + return "MYSQL"; + } + + static char buf[64]; + sprintf(buf, "UNKNOWN#%d", qtype); + return buf; +} + + /* Member function that will log query, either row-based or statement-based depending on the value of the 'current_stmt_binlog_row_based' @@ -3556,7 +3574,8 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg, THD::killed_state killed_status_arg) { DBUG_ENTER("THD::binlog_query"); - DBUG_PRINT("enter", ("qtype: %d query: '%s'", qtype, query_arg)); + DBUG_PRINT("enter", ("qtype: %s query: '%s'", + show_query_type(qtype), query_arg)); DBUG_ASSERT(query_arg && mysql_bin_log.is_open()); /* @@ -3595,6 +3614,9 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg, switch (qtype) { case THD::ROW_QUERY_TYPE: + DBUG_PRINT("debug", + ("current_stmt_binlog_row_based: %d", + current_stmt_binlog_row_based)); if (current_stmt_binlog_row_based) DBUG_RETURN(0); /* Otherwise, we fall through */ diff --git a/sql/sql_class.h b/sql/sql_class.h index 8ceb93940ab..7381930dc93 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -996,6 +996,21 @@ enum enum_thread_type SYSTEM_THREAD_EVENT_WORKER= 32 }; +inline char const * +show_system_thread(enum_thread_type thread) +{ +#define RETURN_NAME_AS_STRING(NAME) case (NAME): return #NAME + switch (thread) { + RETURN_NAME_AS_STRING(NON_SYSTEM_THREAD); + RETURN_NAME_AS_STRING(SYSTEM_THREAD_DELAYED_INSERT); + RETURN_NAME_AS_STRING(SYSTEM_THREAD_SLAVE_IO); + RETURN_NAME_AS_STRING(SYSTEM_THREAD_SLAVE_SQL); + RETURN_NAME_AS_STRING(SYSTEM_THREAD_NDBCLUSTER_BINLOG); + RETURN_NAME_AS_STRING(SYSTEM_THREAD_EVENT_SCHEDULER); + RETURN_NAME_AS_STRING(SYSTEM_THREAD_EVENT_WORKER); + } +#undef RETURN_NAME_AS_STRING +} /** This class represents the interface for internal error handlers. @@ -2084,6 +2099,10 @@ public: Don't reset binlog format for NDB binlog injector thread. */ + DBUG_PRINT("debug", + ("temporary_tables: %d, in_sub_stmt: %d, system_thread: %s", + (int) temporary_tables, in_sub_stmt, + show_system_thread(system_thread))); if ((temporary_tables == NULL) && (in_sub_stmt == 0) && (system_thread != SYSTEM_THREAD_NDBCLUSTER_BINLOG)) { diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc index d33680e1e0b..7c530cb9013 100644 --- a/sql/sql_cursor.cc +++ b/sql/sql_cursor.cc @@ -155,6 +155,7 @@ int mysql_open_cursor(THD *thd, uint flags, select_result *result, if (! (sensitive_cursor= new (thd->mem_root) Sensitive_cursor(thd, result))) { delete result_materialize; + result_materialize= NULL; return 1; } @@ -212,6 +213,7 @@ int mysql_open_cursor(THD *thd, uint flags, select_result *result, if ((rc= materialized_cursor->open(0))) { delete materialized_cursor; + materialized_cursor= NULL; goto err_open; } diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 9e3c591ae2a..df7b76491e0 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -3616,7 +3616,8 @@ select_create::binlog_show_create_table(TABLE **tables, uint count) tmp_table_list.table = *tables; query.length(0); // Have to zero it since constructor doesn't - result= store_create_info(thd, &tmp_table_list, &query, create_info); + result= store_create_info(thd, &tmp_table_list, &query, create_info, + /* show_database */ TRUE); DBUG_ASSERT(result == 0); /* store_create_info() always return 0 */ thd->binlog_query(THD::STMT_QUERY_TYPE, diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 5af22a895a7..bb3dc00fc8d 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -417,11 +417,11 @@ public: bool no_table_names_allowed; /* used for global order by */ bool no_error; /* suppress error message (convert it to warnings) */ - static void *operator new(size_t size) + static void *operator new(size_t size) throw () { return sql_alloc(size); } - static void *operator new(size_t size, MEM_ROOT *mem_root) + static void *operator new(size_t size, MEM_ROOT *mem_root) throw () { return (void*) alloc_root(mem_root, (uint) size); } static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); } static void operator delete(void *ptr, MEM_ROOT *mem_root) {} diff --git a/sql/sql_list.h b/sql/sql_list.h index 2e068f7f961..0d267111dad 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -29,7 +29,7 @@ public: { return sql_alloc(size); } - static void *operator new[](size_t size) + static void *operator new[](size_t size) throw () { return sql_alloc(size); } @@ -450,7 +450,7 @@ public: struct ilink { struct ilink **prev,*next; - static void *operator new(size_t size) + static void *operator new(size_t size) throw () { return (void*)my_malloc((uint)size, MYF(MY_WME | MY_FAE)); } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index b1c9afa3842..51e76f73d57 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5467,6 +5467,10 @@ void mysql_reset_thd_for_next_command(THD *thd) */ thd->reset_current_stmt_binlog_row_based(); + DBUG_PRINT("debug", + ("current_stmt_binlog_row_based: %d", + thd->current_stmt_binlog_row_based)); + DBUG_VOID_RETURN; } @@ -6530,15 +6534,24 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, thd->store_globals(); lex_start(thd); } + if (thd) { - if (acl_reload(thd)) - result= 1; - if (grant_reload(thd)) + bool reload_acl_failed= acl_reload(thd); + bool reload_grants_failed= grant_reload(thd); + bool reload_servers_failed= servers_reload(thd); + + if (reload_acl_failed || reload_grants_failed || reload_servers_failed) + { result= 1; - if (servers_reload(thd)) - result= 1; /* purecov: inspected */ + /* + When an error is returned, my_message may have not been called and + the client will hang waiting for a response. + */ + my_error(ER_UNKNOWN_ERROR, MYF(0), "FLUSH PRIVILEGES failed"); + } } + if (tmp_thd) { delete tmp_thd; @@ -6627,8 +6640,10 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, tmp_write_to_binlog= 0; if (lock_global_read_lock(thd)) return 1; // Killed - result= close_cached_tables(thd, tables, FALSE, (options & REFRESH_FAST) ? - FALSE : TRUE, TRUE); + if (close_cached_tables(thd, tables, FALSE, (options & REFRESH_FAST) ? + FALSE : TRUE, TRUE)) + result= 1; + if (make_global_read_lock_block_commit(thd)) // Killed { /* Don't leave things in a half-locked state */ @@ -6637,8 +6652,11 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, } } else - result= close_cached_tables(thd, tables, FALSE, (options & REFRESH_FAST) ? - FALSE : TRUE, FALSE); + { + if (close_cached_tables(thd, tables, FALSE, (options & REFRESH_FAST) ? + FALSE : TRUE, FALSE)) + result= 1; + } my_dbopt_cleanup(); } if (options & REFRESH_HOSTS) @@ -6661,8 +6679,8 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, #ifdef OPENSSL if (options & REFRESH_DES_KEY_FILE) { - if (des_key_file) - result=load_des_key_file(des_key_file); + if (des_key_file && load_des_key_file(des_key_file)) + result= 1; } #endif #ifdef HAVE_REPLICATION diff --git a/sql/sql_select.cc b/sql/sql_select.cc index c5e8286409c..4d8dbfe287b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6754,6 +6754,12 @@ void JOIN::cleanup(bool full) if (tmp_join) tmp_table_param.copy_field= 0; group_fields.delete_elements(); + /* + Ensure that the above delete_elements() would not be called + twice for the same list. + */ + if (tmp_join && tmp_join != this) + tmp_join->group_fields= group_fields; /* We can't call delete_elements() on copy_funcs as this will cause problems in free_elements() as some of the elements are then deleted. diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 16a0342cb1f..698f41ac85a 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -619,7 +619,8 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) if ((table_list->view ? view_store_create_info(thd, table_list, &buffer) : - store_create_info(thd, table_list, &buffer, NULL))) + store_create_info(thd, table_list, &buffer, NULL, + FALSE /* show_database */))) DBUG_RETURN(TRUE); List<Item> field_list; @@ -810,7 +811,8 @@ mysqld_dump_create_info(THD *thd, TABLE_LIST *table_list, int fd) DBUG_PRINT("enter",("table: %s",table_list->table->s->table_name.str)); protocol->prepare_for_resend(); - if (store_create_info(thd, table_list, packet, NULL)) + if (store_create_info(thd, table_list, packet, NULL, + FALSE /* show_database */)) DBUG_RETURN(-1); if (fd < 0) @@ -1062,7 +1064,7 @@ static bool get_field_default_value(THD *thd, TABLE *table, */ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, - HA_CREATE_INFO *create_info_arg) + HA_CREATE_INFO *create_info_arg, bool show_database) { List<Item> field_list; char tmp[MAX_FIELD_WIDTH], *for_str, buff[128], def_value_buf[MAX_FIELD_WIDTH]; @@ -1110,6 +1112,25 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, alias= share->table_name.str; } } + + /* + Print the database before the table name if told to do that. The + database name is only printed in the event that it is different + from the current database. The main reason for doing this is to + avoid having to update gazillions of tests and result files, but + it also saves a few bytes of the binary log. + */ + if (show_database) + { + const LEX_STRING *const db= + table_list->schema_table ? &INFORMATION_SCHEMA_NAME : &table->s->db; + if (strcmp(db->str, thd->db) != 0) + { + append_identifier(thd, packet, db->str, db->length); + packet->append(STRING_WITH_LEN(".")); + } + } + append_identifier(thd, packet, alias, strlen(alias)); packet->append(STRING_WITH_LEN(" (\n")); /* diff --git a/sql/sql_show.h b/sql/sql_show.h index d63217584b2..3baaef00a7d 100644 --- a/sql/sql_show.h +++ b/sql/sql_show.h @@ -33,7 +33,7 @@ find_files_result find_files(THD *thd, List<LEX_STRING> *files, const char *db, const char *path, const char *wild, bool dir); int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, - HA_CREATE_INFO *create_info_arg); + HA_CREATE_INFO *create_info_arg, bool show_database); int view_store_create_info(THD *thd, TABLE_LIST *table, String *buff); int copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table); diff --git a/sql/sql_string.h b/sql/sql_string.h index b4d76a1779a..be11fea70dc 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -79,7 +79,7 @@ public: Alloced_length=str.Alloced_length; alloced=0; str_charset=str.str_charset; } - static void *operator new(size_t size, MEM_ROOT *mem_root) + static void *operator new(size_t size, MEM_ROOT *mem_root) throw () { return (void*) alloc_root(mem_root, (uint) size); } static void operator delete(void *ptr_arg,size_t size) { TRASH(ptr_arg, size); } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 2b3b5ef67d9..1de16338c40 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4956,8 +4956,9 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, } VOID(pthread_mutex_unlock(&LOCK_open)); - IF_DBUG(int result=) store_create_info(thd, table, &query, - create_info); + IF_DBUG(int result=) + store_create_info(thd, table, &query, + create_info, FALSE /* show_database */); DBUG_ASSERT(result == 0); // store_create_info() always return 0 write_bin_log(thd, TRUE, query.ptr(), query.length()); diff --git a/sql/table.cc b/sql/table.cc index ebf3dfd748e..58cbde74822 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1999,6 +1999,28 @@ void free_blobs(register TABLE *table) } +/** + Reclaim temporary blob storage which is bigger than + a threshold. + + @param table A handle to the TABLE object containing blob fields + @param size The threshold value. + +*/ + +void free_field_buffers_larger_than(TABLE *table, uint32 size) +{ + uint *ptr, *end; + for (ptr= table->s->blob_field, end=ptr + table->s->blob_fields ; + ptr != end ; + ptr++) + { + Field_blob *blob= (Field_blob*) table->field[*ptr]; + if (blob->get_field_buffer_size() > size) + blob->free(); + } +} + /* Find where a form starts */ /* if formname is NullS then only formnames is read */ diff --git a/sql/table.h b/sql/table.h index 75ddaf69c10..da0e089794f 100644 --- a/sql/table.h +++ b/sql/table.h @@ -935,6 +935,9 @@ typedef struct st_schema_table #define VIEW_CHECK_ERROR 1 #define VIEW_CHECK_SKIP 2 +/** The threshold size a blob field buffer before it is freed */ +#define MAX_TDC_BLOB_SIZE 65536 + struct st_lex; class select_union; class TMP_TABLE_PARAM; |