summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libmysqld/lib_sql.cc40
-rw-r--r--mysql-test/r/temp_table.result5
-rw-r--r--sql/handler.cc4
-rw-r--r--sql/mysql_priv.h4
-rw-r--r--sql/mysqld.cc15
-rw-r--r--sql/set_var.cc19
-rw-r--r--sql/set_var.h16
-rw-r--r--sql/sql_select.cc10
-rw-r--r--sql/sql_select.h3
-rw-r--r--sql/sql_update.cc18
10 files changed, 109 insertions, 25 deletions
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
index 94f30e5061b..14d293d91e3 100644
--- a/libmysqld/lib_sql.cc
+++ b/libmysqld/lib_sql.cc
@@ -275,11 +275,39 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
}
+/*
+ Make a copy of array and the strings array points to
+*/
+
+char **copy_arguments(int argc, char **argv)
+{
+ uint length= 0;
+ char **from, **res, **end= argv+argc;
+
+ for (from=argv ; from != end ; from++)
+ length+= strlen(*from);
+
+ if ((res= (char**) my_malloc(sizeof(argv)*(argc+1)+length+argc,
+ MYF(MY_WME))))
+ {
+ char **to= res, *to_str= (char*) (res+argc+1);
+ for (from=argv ; from != end ;)
+ {
+ *to++= to_str;
+ to_str= strmov(to_str, *from++)+1;
+ }
+ *to= 0; // Last ptr should be null
+ }
+ return res;
+}
+
+
extern "C"
{
static my_bool inited, org_my_init_done;
ulong max_allowed_packet, net_buffer_length;
+char ** copy_arguments_ptr= 0;
int STDCALL mysql_server_init(int argc, char **argv, char **groups)
{
@@ -303,7 +331,7 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups)
argvp = (char ***) &fake_argv;
}
if (!groups)
- groups = (char**) fake_groups;
+ groups = (char**) fake_groups;
my_umask=0660; // Default umask for new files
my_umask_dir=0700; // Default umask for new directories
@@ -319,6 +347,14 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups)
MY_INIT((char *)"mysql_embedded"); // init my_sys library & pthreads
}
+ /*
+ Make a copy of the arguments to guard against applications that
+ may change or move the initial arguments.
+ */
+ if (argvp == &argv)
+ if (!(copy_arguments_ptr= argv= copy_arguments(argc, argv)))
+ return 1;
+
tzset(); // Set tzname
start_time=time((time_t*) 0);
@@ -566,6 +602,8 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups)
void STDCALL mysql_server_end()
{
+ my_free((char*) copy_arguments_ptr, MYF(MY_ALLOW_ZERO_PTR));
+ copy_arguments_ptr=0;
clean_up(0);
#ifdef THREAD
/* Don't call my_thread_end() if the application is using MY_INIT() */
diff --git a/mysql-test/r/temp_table.result b/mysql-test/r/temp_table.result
index 45f879e182b..7c8d10cf0a6 100644
--- a/mysql-test/r/temp_table.result
+++ b/mysql-test/r/temp_table.result
@@ -72,6 +72,11 @@ id val elt(two.val,'one','two')
2 1 one
4 2 two
drop table t1,t2;
+create temporary table t1 (a int not null);
+insert into t1 values (1),(1);
+alter table t1 add primary key (a);
+Duplicate entry '1' for key 1
+drop table t1;
drop table if exists t1;
CREATE TABLE t1 (
d datetime default NULL
diff --git a/sql/handler.cc b/sql/handler.cc
index c4e742ef519..d4fd45613d4 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -883,13 +883,13 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
void ha_key_cache(void)
{
if (keybuff_size)
- (void) init_key_cache(keybuff_size);
+ (void) init_key_cache((ulong) keybuff_size);
}
void ha_resize_key_cache(void)
{
- (void) resize_key_cache(keybuff_size);
+ (void) resize_key_cache((ulong) keybuff_size);
}
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index ffdf74b412f..3cf6bb2c1a5 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -625,6 +625,7 @@ extern char glob_hostname[FN_REFLEN], mysql_home[FN_REFLEN];
extern char pidfile_name[FN_REFLEN], time_zone[30], *opt_init_file;
extern char blob_newline;
extern double log_10[32];
+extern ulonglong keybuff_size;
extern ulong refresh_version,flush_version, thread_id,query_id,opened_tables;
extern ulong created_tmp_tables, created_tmp_disk_tables;
extern ulong aborted_threads,aborted_connects;
@@ -643,8 +644,7 @@ extern ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count;
extern ulong ha_read_key_count, ha_read_next_count, ha_read_prev_count;
extern ulong ha_read_first_count, ha_read_last_count;
extern ulong ha_read_rnd_count, ha_read_rnd_next_count;
-extern ulong ha_commit_count, ha_rollback_count;
-extern ulong keybuff_size,table_cache_size;
+extern ulong ha_commit_count, ha_rollback_count,table_cache_size;
extern ulong max_connections,max_connect_errors, connect_timeout;
extern ulong max_insert_delayed_threads, max_user_connections;
extern ulong long_query_count, what_to_log,flush_time,opt_sql_mode;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index ecde4bc8645..2c15b21ac7d 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -318,7 +318,8 @@ ulong thd_startup_options=(OPTION_UPDATE_LOG | OPTION_AUTO_IS_NULL |
uint protocol_version=PROTOCOL_VERSION;
struct system_variables global_system_variables;
struct system_variables max_system_variables;
-ulong keybuff_size,table_cache_size,
+ulonglong keybuff_size;
+ulong table_cache_size,
thread_stack,
thread_stack_min,what_to_log= ~ (1L << (uint) COM_TIME),
query_buff_size,
@@ -1372,7 +1373,7 @@ or misconfigured. This error can also be caused by malfunctioning hardware.\n",
We will try our best to scrape up some info that will hopefully help diagnose\n\
the problem, but since we have already crashed, something is definitely wrong\n\
and this may fail.\n\n");
- fprintf(stderr, "key_buffer_size=%ld\n", keybuff_size);
+ fprintf(stderr, "key_buffer_size=%lu\n", (ulong) keybuff_size);
fprintf(stderr, "read_buffer_size=%ld\n", global_system_variables.read_buff_size);
fprintf(stderr, "sort_buffer_size=%ld\n", thd->variables.sortbuff_size);
fprintf(stderr, "max_used_connections=%ld\n", max_used_connections);
@@ -1380,8 +1381,9 @@ and this may fail.\n\n");
fprintf(stderr, "threads_connected=%d\n", thread_count);
fprintf(stderr, "It is possible that mysqld could use up to \n\
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_connections = %ld K\n\
-bytes of memory\n", (keybuff_size + (global_system_variables.read_buff_size +
- thd->variables.sortbuff_size) *
+bytes of memory\n", ((ulong) keybuff_size +
+ (global_system_variables.read_buff_size +
+ thd->variables.sortbuff_size) *
max_connections)/ 1024);
fprintf(stderr, "Hope that's ok; if not, decrease some variables in the equation.\n\n");
@@ -3509,8 +3511,9 @@ struct my_option my_long_options[] =
IO_SIZE, 0},
{"key_buffer_size", OPT_KEY_BUFFER_SIZE,
"The size of the buffer used for index blocks. Increase this to get better index handling (for all reads and multiple writes) to as much as you can afford; 64M on a 256M machine that mainly runs MySQL is quite common.",
- (gptr*) &keybuff_size, (gptr*) &keybuff_size, 0, GET_ULONG, REQUIRED_ARG,
- KEY_CACHE_SIZE, MALLOC_OVERHEAD, (long) ~0, MALLOC_OVERHEAD, IO_SIZE, 0},
+ (gptr*) &keybuff_size, (gptr*) &keybuff_size, 0, GET_ULL,
+ REQUIRED_ARG, KEY_CACHE_SIZE, MALLOC_OVERHEAD, (long) ~0, MALLOC_OVERHEAD,
+ IO_SIZE, 0},
{"long_query_time", OPT_LONG_QUERY_TIME,
"Log all queries that have taken more than long_query_time seconds to execute to file.",
(gptr*) &global_system_variables.long_query_time,
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 0675f7b4286..28222740c14 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -119,7 +119,7 @@ sys_var_thd_ulong sys_interactive_timeout("interactive_timeout",
&SV::net_interactive_timeout);
sys_var_thd_ulong sys_join_buffer_size("join_buffer_size",
&SV::join_buff_size);
-sys_var_long_ptr sys_key_buffer_size("key_buffer_size",
+sys_var_ulonglong_ptr sys_key_buffer_size("key_buffer_size",
&keybuff_size,
fix_key_buffer_size);
sys_var_bool_ptr sys_local_infile("local_infile",
@@ -669,6 +669,23 @@ void sys_var_long_ptr::set_default(THD *thd, enum_var_type type)
}
+bool sys_var_ulonglong_ptr::update(THD *thd, set_var *var)
+{
+ ulonglong tmp= var->value->val_int();
+ if (option_limits)
+ *value= (ulonglong) getopt_ull_limit_value(tmp, option_limits);
+ else
+ *value= (ulonglong) tmp;
+ return 0;
+}
+
+
+void sys_var_ulonglong_ptr::set_default(THD *thd, enum_var_type type)
+{
+ *value= (ulonglong) option_limits->def_value;
+}
+
+
bool sys_var_bool_ptr::update(THD *thd, set_var *var)
{
*value= (my_bool) var->save_result.ulong_value;
diff --git a/sql/set_var.h b/sql/set_var.h
index a171c4f5e76..3edd0373db9 100644
--- a/sql/set_var.h
+++ b/sql/set_var.h
@@ -85,6 +85,22 @@ public:
};
+class sys_var_ulonglong_ptr :public sys_var
+{
+public:
+ ulonglong *value;
+ sys_var_ulonglong_ptr(const char *name_arg, ulonglong *value_ptr)
+ :sys_var(name_arg),value(value_ptr) {}
+ sys_var_ulonglong_ptr(const char *name_arg, ulonglong *value_ptr,
+ sys_after_update_func func)
+ :sys_var(name_arg,func), value(value_ptr) {}
+ bool update(THD *thd, set_var *var);
+ void set_default(THD *thd, enum_var_type type);
+ SHOW_TYPE type() { return SHOW_LONGLONG; }
+ byte *value_ptr(THD *thd, enum_var_type type) { return (byte*) value; }
+};
+
+
class sys_var_bool_ptr :public sys_var
{
public:
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 80b1ceb0538..c4bc10a8b2a 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -2848,9 +2848,7 @@ join_free(JOIN *join)
}
join->group_fields.delete_elements();
join->tmp_table_param.copy_funcs.delete_elements();
- if (join->tmp_table_param.copy_field) // Because of bug in ecc
- delete [] join->tmp_table_param.copy_field;
- join->tmp_table_param.copy_field=0;
+ join->tmp_table_param.cleanup();
DBUG_VOID_RETURN;
}
@@ -3699,13 +3697,13 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
NullS))
{
bitmap_clear_bit(&temp_pool, temp_pool_slot);
- DBUG_RETURN(NULL); /* purecov: inspected */
+ DBUG_RETURN(NULL); /* purecov: inspected */
}
if (!(param->copy_field=copy=new Copy_field[field_count]))
{
bitmap_clear_bit(&temp_pool, temp_pool_slot);
- my_free((gptr) table,MYF(0)); /* purecov: inspected */
- DBUG_RETURN(NULL); /* purecov: inspected */
+ my_free((gptr) table,MYF(0)); /* purecov: inspected */
+ DBUG_RETURN(NULL); /* purecov: inspected */
}
param->funcs=copy_func;
strmov(tmpname,path);
diff --git a/sql/sql_select.h b/sql/sql_select.h
index d0e10f75727..40eb4d8ef51 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -115,7 +115,8 @@ typedef struct st_position { /* Used in find_best */
/* Param to create temporary tables when doing SELECT:s */
-class TMP_TABLE_PARAM {
+class TMP_TABLE_PARAM :public Sql_alloc
+{
public:
List<Item> copy_funcs;
List_iterator_fast<Item> copy_funcs_it;
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 887d4e0acc0..4eab38bebad 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -412,9 +412,10 @@ end:
multi_update::multi_update(THD *thd_arg, TABLE_LIST *table_list,
List<Item> *field_list, List<Item> *value_list,
enum enum_duplicates handle_duplicates_arg)
- :all_tables(table_list), thd(thd_arg), tmp_tables(0), updated(0),
- found(0), fields(field_list), values(value_list), table_count(0),
- handle_duplicates(handle_duplicates_arg), do_update(1)
+ :all_tables(table_list), update_tables(0), thd(thd_arg), tmp_tables(0),
+ updated(0), found(0), fields(field_list), values(value_list),
+ table_count(0), copy_field(0), handle_duplicates(handle_duplicates_arg),
+ do_update(1), trans_safe(0)
{}
@@ -594,9 +595,14 @@ multi_update::~multi_update()
if (tmp_tables)
{
- for (uint counter = 0; counter < table_count; counter++)
- if (tmp_tables[counter])
- free_tmp_table(thd,tmp_tables[counter]);
+ for (uint cnt = 0; cnt < table_count; cnt++)
+ {
+ if (tmp_tables[cnt])
+ {
+ free_tmp_table(thd, tmp_tables[cnt]);
+ tmp_table_param[cnt].cleanup();
+ }
+ }
}
if (copy_field)
delete [] copy_field;