summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMats Kindahl <mats@mysql.com>2008-08-20 10:42:39 +0200
committerMats Kindahl <mats@mysql.com>2008-08-20 10:42:39 +0200
commit7207b18b25c5b0627a9a5c5b4261bd9a55cdd722 (patch)
treeb6dadeb82cb80c268ee4966cb063a39024131014 /sql
parentbe0acc4bcb9fe038c3e10ddc33b708bd346502cf (diff)
parent09271b1e130eb67e072b6b41ed68f15a528785d7 (diff)
downloadmariadb-git-7207b18b25c5b0627a9a5c5b4261bd9a55cdd722.tar.gz
Merging with 5.1-rpl.
Diffstat (limited to 'sql')
-rw-r--r--sql/field.h5
-rw-r--r--sql/handler.cc2
-rw-r--r--sql/item.cc12
-rw-r--r--sql/item.h4
-rw-r--r--sql/item_cmpfunc.cc12
-rw-r--r--sql/item_func.cc15
-rw-r--r--sql/log.cc4
-rw-r--r--sql/mysql_priv.h1
-rw-r--r--sql/share/errmsg.txt2
-rw-r--r--sql/sp_head.cc2
-rw-r--r--sql/sql_acl.cc1
-rw-r--r--sql/sql_base.cc2
-rw-r--r--sql/sql_binlog.cc1
-rw-r--r--sql/sql_class.cc24
-rw-r--r--sql/sql_class.h19
-rw-r--r--sql/sql_cursor.cc2
-rw-r--r--sql/sql_insert.cc3
-rw-r--r--sql/sql_lex.h4
-rw-r--r--sql/sql_list.h4
-rw-r--r--sql/sql_parse.cc40
-rw-r--r--sql/sql_select.cc6
-rw-r--r--sql/sql_show.cc27
-rw-r--r--sql/sql_show.h2
-rw-r--r--sql/sql_string.h2
-rw-r--r--sql/sql_table.cc5
-rw-r--r--sql/table.cc22
-rw-r--r--sql/table.h3
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;