summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <serg@serg.mylan>2003-08-21 10:45:43 +0200
committerunknown <serg@serg.mylan>2003-08-21 10:45:43 +0200
commit943233632e6afb8ad5da2c654cd2462b53db2563 (patch)
tree07366defe2bd16c540a1dc344f5517406d2f2fe1 /sql
parentc7f517b53f0074ca131e5747e176ebce18cc6171 (diff)
parentfd9b1775642e4da09697fd46a7bbb98d59b9843f (diff)
downloadmariadb-git-943233632e6afb8ad5da2c654cd2462b53db2563.tar.gz
Merge bk-internal:/home/bk/mysql-4.0/
into serg.mylan:/usr/home/serg/Abk/mysql-4.0
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc7
-rw-r--r--sql/ha_innodb.cc1
-rw-r--r--sql/item_cmpfunc.cc17
-rw-r--r--sql/item_sum.cc67
-rw-r--r--sql/item_sum.h32
-rw-r--r--sql/item_uniq.h2
-rw-r--r--sql/log.cc4
-rw-r--r--sql/log_event.cc74
-rw-r--r--sql/log_event.h26
-rw-r--r--sql/mysqld.cc2
-rw-r--r--sql/net_serv.cc27
-rw-r--r--sql/repl_failsafe.cc15
-rw-r--r--sql/slave.cc81
-rw-r--r--sql/sql_class.cc1
-rw-r--r--sql/sql_class.h1
-rw-r--r--sql/sql_load.cc4
-rw-r--r--sql/sql_parse.cc1
-rw-r--r--sql/sql_repl.cc2
-rw-r--r--sql/sql_select.cc2
-rw-r--r--sql/sql_union.cc65
20 files changed, 254 insertions, 177 deletions
diff --git a/sql/field.cc b/sql/field.cc
index e56d53b1bda..592252bb294 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -4147,8 +4147,11 @@ void Field_blob::store(const char *from,uint len)
}
}
#endif /* USE_TIS620 */
- value.copy(from,len);
- from=value.ptr();
+ if (from != value.ptr()) // For valgrind
+ {
+ value.copy(from, len);
+ from= value.ptr();
+ }
#ifdef USE_TIS620
my_free(th_ptr,MYF(MY_ALLOW_ZERO_PTR));
#endif
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 09119a4eb54..3619fefdd1b 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -28,7 +28,6 @@ InnoDB */
#include "mysql_priv.h"
#include "slave.h"
-#include "sql_cache.h"
#ifdef HAVE_INNOBASE_DB
#include <m_ctype.h>
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 8c58c58a67d..7415fc5b98e 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1045,15 +1045,18 @@ void Item_func_in::fix_length_and_dec()
array= new in_double(arg_count);
break;
}
- uint j=0;
- for (uint i=0 ; i < arg_count ; i++)
+ if (array && !(current_thd->fatal_error)) // If not EOM
{
- array->set(j,args[i]);
- if (!args[i]->null_value) // Skip NULL values
- j++;
+ uint j=0;
+ for (uint i=0 ; i < arg_count ; i++)
+ {
+ array->set(j,args[i]);
+ if (!args[i]->null_value) // Skip NULL values
+ j++;
+ }
+ if ((array->used_count=j))
+ array->sort();
}
- if ((array->used_count=j))
- array->sort();
}
else
{
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index d88894d4fb4..08385bb9ca6 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -300,15 +300,15 @@ void Item_sum_std::reset_field()
}
}
-void Item_sum_std::update_field(int offset)
+void Item_sum_std::update_field()
{
double nr,old_nr,old_sqr;
longlong field_count;
char *res=result_field->ptr;
- float8get(old_nr,res+offset);
- float8get(old_sqr,res+offset+sizeof(double));
- field_count=sint8korr(res+offset+sizeof(double)*2);
+ float8get(old_nr, res);
+ float8get(old_sqr, res+sizeof(double));
+ field_count=sint8korr(res+sizeof(double)*2);
nr=args[0]->val();
if (!args[0]->null_value)
@@ -619,12 +619,12 @@ void Item_sum_bit::reset_field()
** calc next value and merge it with field_value
*/
-void Item_sum_sum::update_field(int offset)
+void Item_sum_sum::update_field()
{
double old_nr,nr;
char *res=result_field->ptr;
- float8get(old_nr,res+offset);
+ float8get(old_nr,res);
nr=args[0]->val();
if (!args[0]->null_value)
{
@@ -635,12 +635,12 @@ void Item_sum_sum::update_field(int offset)
}
-void Item_sum_count::update_field(int offset)
+void Item_sum_count::update_field()
{
longlong nr;
char *res=result_field->ptr;
- nr=sint8korr(res+offset);
+ nr=sint8korr(res);
if (!args[0]->maybe_null)
nr++;
else
@@ -653,14 +653,14 @@ void Item_sum_count::update_field(int offset)
}
-void Item_sum_avg::update_field(int offset)
+void Item_sum_avg::update_field()
{
double nr,old_nr;
longlong field_count;
char *res=result_field->ptr;
- float8get(old_nr,res+offset);
- field_count=sint8korr(res+offset+sizeof(double));
+ float8get(old_nr,res);
+ field_count=sint8korr(res+sizeof(double));
nr=args[0]->val();
if (!args[0]->null_value)
@@ -673,78 +673,66 @@ void Item_sum_avg::update_field(int offset)
int8store(res,field_count);
}
-void Item_sum_hybrid::update_field(int offset)
+void Item_sum_hybrid::update_field()
{
if (hybrid_type == STRING_RESULT)
- min_max_update_str_field(offset);
+ min_max_update_str_field();
else if (hybrid_type == INT_RESULT)
- min_max_update_int_field(offset);
+ min_max_update_int_field();
else
- min_max_update_real_field(offset);
+ min_max_update_real_field();
}
void
-Item_sum_hybrid::min_max_update_str_field(int offset)
+Item_sum_hybrid::min_max_update_str_field()
{
String *res_str=args[0]->val_str(&value);
- if (args[0]->null_value)
- result_field->copy_from_tmp(offset); // Use old value
- else
+ if (!args[0]->null_value)
{
res_str->strip_sp();
- result_field->ptr+=offset; // Get old max/min
result_field->val_str(&tmp_value,&tmp_value);
- result_field->ptr-=offset;
if (result_field->is_null() ||
(cmp_sign * (binary ? stringcmp(res_str,&tmp_value) :
sortcmp(res_str,&tmp_value)) < 0))
result_field->store(res_str->ptr(),res_str->length());
- else
- { // Use old value
- char *res=result_field->ptr;
- memcpy(res,res+offset,result_field->pack_length());
- }
result_field->set_notnull();
}
}
void
-Item_sum_hybrid::min_max_update_real_field(int offset)
+Item_sum_hybrid::min_max_update_real_field()
{
double nr,old_nr;
- result_field->ptr+=offset;
old_nr=result_field->val_real();
nr=args[0]->val();
if (!args[0]->null_value)
{
- if (result_field->is_null(offset) ||
+ if (result_field->is_null(0) ||
(cmp_sign > 0 ? old_nr > nr : old_nr < nr))
old_nr=nr;
result_field->set_notnull();
}
- else if (result_field->is_null(offset))
+ else if (result_field->is_null(0))
result_field->set_null();
- result_field->ptr-=offset;
result_field->store(old_nr);
}
void
-Item_sum_hybrid::min_max_update_int_field(int offset)
+Item_sum_hybrid::min_max_update_int_field()
{
longlong nr,old_nr;
- result_field->ptr+=offset;
old_nr=result_field->val_int();
nr=args[0]->val_int();
if (!args[0]->null_value)
{
- if (result_field->is_null(offset))
+ if (result_field->is_null(0))
old_nr=nr;
else
{
@@ -757,30 +745,29 @@ Item_sum_hybrid::min_max_update_int_field(int offset)
}
result_field->set_notnull();
}
- else if (result_field->is_null(offset))
+ else if (result_field->is_null(0))
result_field->set_null();
- result_field->ptr-=offset;
result_field->store(old_nr);
}
-void Item_sum_or::update_field(int offset)
+void Item_sum_or::update_field()
{
ulonglong nr;
char *res=result_field->ptr;
- nr=uint8korr(res+offset);
+ nr=uint8korr(res);
nr|= (ulonglong) args[0]->val_int();
int8store(res,nr);
}
-void Item_sum_and::update_field(int offset)
+void Item_sum_and::update_field()
{
ulonglong nr;
char *res=result_field->ptr;
- nr=uint8korr(res+offset);
+ nr=uint8korr(res);
nr&= (ulonglong) args[0]->val_int();
int8store(res,nr);
}
diff --git a/sql/item_sum.h b/sql/item_sum.h
index 2369b5d1d7e..5189566fdfb 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -56,7 +56,7 @@ public:
virtual void reset()=0;
virtual bool add()=0;
virtual void reset_field()=0;
- virtual void update_field(int offset)=0;
+ virtual void update_field()=0;
virtual bool keep_field_type(void) const { return 0; }
virtual void fix_length_and_dec() { maybe_null=1; null_value=1; }
virtual const char *func_name() const { return "?"; }
@@ -116,7 +116,7 @@ class Item_sum_sum :public Item_sum_num
bool add();
double val();
void reset_field();
- void update_field(int offset);
+ void update_field();
void no_rows_in_result() {}
const char *func_name() const { return "sum"; }
unsigned int size_of() { return sizeof(*this);}
@@ -141,7 +141,7 @@ class Item_sum_count :public Item_sum_int
void make_const(longlong count_arg) { count=count_arg; used_table_cache=0; }
longlong val_int();
void reset_field();
- void update_field(int offset);
+ void update_field();
const char *func_name() const { return "count"; }
unsigned int size_of() { return sizeof(*this);}
};
@@ -193,7 +193,7 @@ class Item_sum_count_distinct :public Item_sum_int
bool add();
longlong val_int();
void reset_field() { return ;} // Never called
- void update_field(int offset) { return ; } // Never called
+ void update_field() { return ; } // Never called
const char *func_name() const { return "count_distinct"; }
bool setup(THD *thd);
void no_rows_in_result() {}
@@ -235,7 +235,7 @@ class Item_sum_avg :public Item_sum_num
bool add();
double val();
void reset_field();
- void update_field(int offset);
+ void update_field();
Item *result_item(Field *field)
{ return new Item_avg_field(this); }
const char *func_name() const { return "avg"; }
@@ -273,7 +273,7 @@ class Item_sum_std :public Item_sum_num
bool add();
double val();
void reset_field();
- void update_field(int offset);
+ void update_field();
Item *result_item(Field *field)
{ return new Item_std_field(this); }
const char *func_name() const { return "std"; }
@@ -316,10 +316,10 @@ class Item_sum_hybrid :public Item_sum
void make_const() { used_table_cache=0; }
bool keep_field_type(void) const { return 1; }
enum Item_result result_type () const { return hybrid_type; }
- void update_field(int offset);
- void min_max_update_str_field(int offset);
- void min_max_update_real_field(int offset);
- void min_max_update_int_field(int offset);
+ void update_field();
+ void min_max_update_str_field();
+ void min_max_update_real_field();
+ void min_max_update_int_field();
unsigned int size_of() { return sizeof(*this);}
};
@@ -371,7 +371,7 @@ class Item_sum_or :public Item_sum_bit
public:
Item_sum_or(Item *item_par) :Item_sum_bit(item_par,LL(0)) {}
bool add();
- void update_field(int offset);
+ void update_field();
const char *func_name() const { return "bit_or"; }
unsigned int size_of() { return sizeof(*this);}
};
@@ -382,7 +382,7 @@ class Item_sum_and :public Item_sum_bit
public:
Item_sum_and(Item *item_par) :Item_sum_bit(item_par, ~(ulonglong) LL(0)) {}
bool add();
- void update_field(int offset);
+ void update_field();
const char *func_name() const { return "bit_and"; }
unsigned int size_of() { return sizeof(*this);}
};
@@ -414,7 +414,7 @@ public:
void reset();
bool add();
void reset_field() {};
- void update_field(int offset_arg) {};
+ void update_field() {};
unsigned int size_of() { return sizeof(*this);}
};
@@ -482,7 +482,7 @@ class Item_sum_udf_float :public Item_sum_num
double val() { return 0.0; }
void reset() {}
bool add() { return 0; }
- void update_field(int offset) {}
+ void update_field() {}
};
@@ -497,7 +497,7 @@ public:
double val() { return 0; }
void reset() {}
bool add() { return 0; }
- void update_field(int offset) {}
+ void update_field() {}
};
@@ -515,7 +515,7 @@ public:
enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
void reset() {}
bool add() { return 0; }
- void update_field(int offset) {}
+ void update_field() {}
};
#endif /* HAVE_DLOPEN */
diff --git a/sql/item_uniq.h b/sql/item_uniq.h
index cc087832f49..de239d3a8ec 100644
--- a/sql/item_uniq.h
+++ b/sql/item_uniq.h
@@ -42,7 +42,7 @@ public:
void reset() {}
bool add() { return 0; }
void reset_field() {}
- void update_field(int offset) {}
+ void update_field() {}
bool fix_fields(THD *thd,struct st_table_list *tlist) { return 0;}
unsigned int size_of() { return sizeof(*this);}
};
diff --git a/sql/log.cc b/sql/log.cc
index 4dce26d23ea..ee774ea3700 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -263,7 +263,8 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
an extension for the binary log files.
In this case we write a standard header to it.
*/
- if (my_b_safe_write(&log_file, (byte*) BINLOG_MAGIC, BIN_LOG_HEADER_SIZE))
+ if (my_b_safe_write(&log_file, (byte*) BINLOG_MAGIC,
+ BIN_LOG_HEADER_SIZE))
goto err;
bytes_written += BIN_LOG_HEADER_SIZE;
write_file_name_to_index_file=1;
@@ -1067,6 +1068,7 @@ bool MYSQL_LOG::write(Log_event* event_info)
#else
IO_CACHE *file = &log_file;
#endif
+ DBUG_PRINT("info",("event type=%d",event_info->get_type_code()));
/*
In the future we need to add to the following if tests like
"do the involved tables match (to be implemented)
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 2a1669737f8..9e7546dd635 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -119,12 +119,11 @@ const char* Log_event::get_type_str()
#ifndef MYSQL_CLIENT
Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans)
- :temp_buf(0), exec_time(0), cached_event_len(0), flags(flags_arg),
- thd(thd_arg)
+ :log_pos(0), temp_buf(0), exec_time(0), cached_event_len(0),
+ flags(flags_arg), thd(thd_arg)
{
server_id = thd->server_id;
when = thd->start_time;
- log_pos = thd->log_pos;
cache_stmt= (using_trans &&
(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)));
}
@@ -1606,11 +1605,12 @@ void Create_file_log_event::pack_info(String* packet)
#endif
#ifndef MYSQL_CLIENT
-Append_block_log_event::Append_block_log_event(THD* thd_arg, char* block_arg,
+Append_block_log_event::Append_block_log_event(THD* thd_arg, const char* db_arg,
+ char* block_arg,
uint block_len_arg,
bool using_trans)
:Log_event(thd_arg,0, using_trans), block(block_arg),
- block_len(block_len_arg), file_id(thd_arg->file_id)
+ block_len(block_len_arg), file_id(thd_arg->file_id), db(db_arg)
{
}
#endif
@@ -1654,8 +1654,9 @@ void Append_block_log_event::pack_info(String* packet)
net_store_data(packet, buf1);
}
-Delete_file_log_event::Delete_file_log_event(THD* thd_arg, bool using_trans)
- :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id)
+Delete_file_log_event::Delete_file_log_event(THD* thd_arg, const char* db_arg,
+ bool using_trans)
+ :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg)
{
}
#endif
@@ -1700,8 +1701,9 @@ void Delete_file_log_event::pack_info(String* packet)
#ifndef MYSQL_CLIENT
-Execute_load_log_event::Execute_load_log_event(THD* thd_arg, bool using_trans)
- :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id)
+Execute_load_log_event::Execute_load_log_event(THD* thd_arg, const char* db_arg,
+ bool using_trans)
+ :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg)
{
}
#endif
@@ -1905,7 +1907,19 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
DBUG_ASSERT(thd->query == 0);
thd->query = 0; // Should not be needed
thd->query_error = 0;
-
+
+ /*
+ We test replicate_*_db rules. Note that we have already prepared the file to
+ load, even if we are going to ignore and delete it now. So it is possible
+ that we did a lot of disk writes for nothing. In other words, a big LOAD
+ DATA INFILE on the master will still consume a lot of space on the slave
+ (space in the relay log + space of temp files: twice the space of the file
+ to load...) even if it will finally be ignored.
+ TODO: fix this; this can be done by testing rules in
+ Create_file_log_event::exec_event() and then discarding Append_block and
+ al. Another way is do the filtering in the I/O thread (more efficient: no
+ disk writes at all).
+ */
if (db_ok(thd->db, replicate_do_db, replicate_ignore_db))
{
thd->set_time((time_t)when);
@@ -2210,7 +2224,7 @@ int Create_file_log_event::exec_event(struct st_relay_log_info* rli)
init_io_cache(&file, fd, IO_SIZE, WRITE_CACHE, (my_off_t)0, 0,
MYF(MY_WME|MY_NABP)))
{
- slave_print_error(rli,my_errno, "Could not open file '%s'", fname_buf);
+ slave_print_error(rli,my_errno, "Error in Create_file event: could not open file '%s'", fname_buf);
goto err;
}
@@ -2221,7 +2235,7 @@ int Create_file_log_event::exec_event(struct st_relay_log_info* rli)
if (write_base(&file))
{
strmov(p, ".info"); // to have it right in the error message
- slave_print_error(rli,my_errno, "Could not write to file '%s'", fname_buf);
+ slave_print_error(rli,my_errno, "Error in Create_file event: could not write to file '%s'", fname_buf);
goto err;
}
end_io_cache(&file);
@@ -2231,16 +2245,14 @@ int Create_file_log_event::exec_event(struct st_relay_log_info* rli)
if ((fd = my_open(fname_buf, O_WRONLY|O_CREAT|O_BINARY|O_TRUNC,
MYF(MY_WME))) < 0)
{
- slave_print_error(rli,my_errno, "Could not open file '%s'", fname_buf);
+ slave_print_error(rli,my_errno, "Error in Create_file event: could not open file '%s'", fname_buf);
goto err;
}
if (my_write(fd, (byte*) block, block_len, MYF(MY_WME+MY_NABP)))
{
- slave_print_error(rli,my_errno, "Write to '%s' failed", fname_buf);
+ slave_print_error(rli,my_errno, "Error in Create_file event: write to '%s' failed", fname_buf);
goto err;
}
- if (mysql_bin_log.is_open())
- mysql_bin_log.write(this);
error=0; // Everything is ok
err:
@@ -2259,8 +2271,6 @@ int Delete_file_log_event::exec_event(struct st_relay_log_info* rli)
(void) my_delete(fname, MYF(MY_WME));
memcpy(p, ".info", 6);
(void) my_delete(fname, MYF(MY_WME));
- if (mysql_bin_log.is_open())
- mysql_bin_log.write(this);
return Log_event::exec_event(rli);
}
@@ -2274,16 +2284,14 @@ int Append_block_log_event::exec_event(struct st_relay_log_info* rli)
memcpy(p, ".data", 6);
if ((fd = my_open(fname, O_WRONLY|O_APPEND|O_BINARY, MYF(MY_WME))) < 0)
{
- slave_print_error(rli,my_errno, "Could not open file '%s'", fname);
+ slave_print_error(rli,my_errno, "Error in Append_block event: could not open file '%s'", fname);
goto err;
}
if (my_write(fd, (byte*) block, block_len, MYF(MY_WME+MY_NABP)))
{
- slave_print_error(rli,my_errno, "Write to '%s' failed", fname);
+ slave_print_error(rli,my_errno, "Error in Append_block event: write to '%s' failed", fname);
goto err;
}
- if (mysql_bin_log.is_open())
- mysql_bin_log.write(this);
error=0;
err:
@@ -2298,7 +2306,6 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli)
char *p= slave_load_file_stem(fname, file_id, server_id);
int fd;
int error = 1;
- ulong save_options;
IO_CACHE file;
Load_log_event* lev = 0;
@@ -2307,7 +2314,7 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli)
init_io_cache(&file, fd, IO_SIZE, READ_CACHE, (my_off_t)0, 0,
MYF(MY_WME|MY_NABP)))
{
- slave_print_error(rli,my_errno, "Could not open file '%s'", fname);
+ slave_print_error(rli,my_errno, "Error in Exec_load event: could not open file '%s'", fname);
goto err;
}
if (!(lev = (Load_log_event*)Log_event::read_log_event(&file,
@@ -2315,21 +2322,16 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli)
(bool)0)) ||
lev->get_type_code() != NEW_LOAD_EVENT)
{
- slave_print_error(rli,0, "File '%s' appears corrupted", fname);
+ slave_print_error(rli,0, "Error in Exec_load event: file '%s' appears corrupted", fname);
goto err;
}
- /*
- We want to disable binary logging in slave thread because we need the file
- events to appear in the same order as they do on the master relative to
- other events, so that we can preserve ascending order of log sequence
- numbers - needed to handle failover .
- */
- save_options = thd->options;
- thd->options &= ~ (ulong) (OPTION_BIN_LOG);
+
lev->thd = thd;
/*
lev->exec_event should use rli only for errors
- i.e. should not advance rli's position
+ i.e. should not advance rli's position.
+ lev->exec_event is the place where the table is loaded (it calls
+ mysql_load()).
*/
if (lev->exec_event(0,rli,1))
{
@@ -2350,15 +2352,11 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli)
tmp, fname);
my_free(tmp,MYF(0));
}
- thd->options= save_options;
goto err;
}
- thd->options = save_options;
(void) my_delete(fname, MYF(MY_WME));
memcpy(p, ".data", 6);
(void) my_delete(fname, MYF(MY_WME));
- if (mysql_bin_log.is_open())
- mysql_bin_log.write(this);
error = 0;
err:
diff --git a/sql/log_event.h b/sql/log_event.h
index 1031b940528..227c0243b9c 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -687,9 +687,20 @@ public:
char* block;
uint block_len;
uint file_id;
-
+ /*
+ 'db' is filled when the event is created in mysql_load() (the event needs to
+ have a 'db' member to be well filtered by binlog-*-db rules). 'db' is not
+ written to the binlog (it's not used by Append_block_log_event::write()), so
+ it can't be read in the Append_block_log_event(const char* buf, int
+ event_len) constructor.
+ In other words, 'db' is used only for filtering by binlog-*-db rules.
+ Create_file_log_event is different: its 'db' (which is inherited from
+ Load_log_event) is written to the binlog and can be re-read.
+ */
+ const char* db;
+
#ifndef MYSQL_CLIENT
- Append_block_log_event(THD* thd, char* block_arg,
+ Append_block_log_event(THD* thd, const char* db_arg, char* block_arg,
uint block_len_arg, bool using_trans);
int exec_event(struct st_relay_log_info* rli);
void pack_info(String* packet);
@@ -703,6 +714,7 @@ public:
int get_data_size() { return block_len + APPEND_BLOCK_HEADER_LEN ;}
bool is_valid() { return block != 0; }
int write_data(IO_CACHE* file);
+ const char* get_db() { return db; }
};
@@ -710,9 +722,10 @@ class Delete_file_log_event: public Log_event
{
public:
uint file_id;
+ const char* db; /* see comment in Append_block_log_event */
#ifndef MYSQL_CLIENT
- Delete_file_log_event(THD* thd, bool using_trans);
+ Delete_file_log_event(THD* thd, const char* db_arg, bool using_trans);
void pack_info(String* packet);
int exec_event(struct st_relay_log_info* rli);
#else
@@ -725,15 +738,17 @@ public:
int get_data_size() { return DELETE_FILE_HEADER_LEN ;}
bool is_valid() { return file_id != 0; }
int write_data(IO_CACHE* file);
+ const char* get_db() { return db; }
};
class Execute_load_log_event: public Log_event
{
public:
uint file_id;
-
+ const char* db; /* see comment in Append_block_log_event */
+
#ifndef MYSQL_CLIENT
- Execute_load_log_event(THD* thd, bool using_trans);
+ Execute_load_log_event(THD* thd, const char* db_arg, bool using_trans);
void pack_info(String* packet);
int exec_event(struct st_relay_log_info* rli);
#else
@@ -746,6 +761,7 @@ public:
int get_data_size() { return EXEC_LOAD_HEADER_LEN ;}
bool is_valid() { return file_id != 0; }
int write_data(IO_CACHE* file);
+ const char* get_db() { return db; }
};
#ifdef MYSQL_CLIENT
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index d9ba97ad11a..b90ab1a4a3a 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -3833,7 +3833,7 @@ replicating a LOAD DATA INFILE command",
"Max packetlength to send/receive from to server.",
(gptr*) &global_system_variables.max_allowed_packet,
(gptr*) &max_system_variables.max_allowed_packet, 0, GET_ULONG,
- REQUIRED_ARG, 1024*1024L, 80, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
+ REQUIRED_ARG, 1024*1024L, 1024, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
{"max_binlog_cache_size", OPT_MAX_BINLOG_CACHE_SIZE,
"Can be used to restrict the total size used to cache a multi-transaction query.",
(gptr*) &max_binlog_cache_size, (gptr*) &max_binlog_cache_size, 0,
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index 13f786e0e75..8f0d659daf2 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -215,10 +215,12 @@ int net_flush(NET *net)
*****************************************************************************/
/*
-** Write a logical packet with packet header
-** Format: Packet length (3 bytes), packet number(1 byte)
-** When compression is used a 3 byte compression length is added
-** NOTE: If compression is used the original package is modified!
+ Write a logical packet with packet header
+ Format: Packet length (3 bytes), packet number(1 byte)
+ When compression is used a 3 byte compression length is added
+
+ NOTE
+ If compression is used the original package is modified!
*/
int
@@ -315,8 +317,8 @@ net_write_command(NET *net,uchar command,const char *packet,ulong len)
The cached buffer can be sent as it is with 'net_flush()'.
In this code we have to be careful to not send a packet longer than
- MAX_PACKET_LENGTH to net_real_write() if we are using the compressed protocol
- as we store the length of the compressed packet in 3 bytes.
+ MAX_PACKET_LENGTH to net_real_write() if we are using the compressed
+ protocol as we store the length of the compressed packet in 3 bytes.
RETURN
0 ok
@@ -821,20 +823,23 @@ my_net_read(NET *net)
{
/* We are using the compressed protocol */
- ulong buf_length= net->buf_length;
- ulong start_of_packet= net->buf_length - net->remain_in_buf;
- ulong first_packet_offset=start_of_packet;
+ ulong buf_length;
+ ulong start_of_packet;
+ ulong first_packet_offset;
uint read_length, multi_byte_packet=0;
if (net->remain_in_buf)
{
+ buf_length= net->buf_length; // Data left in old packet
+ first_packet_offset= start_of_packet= (net->buf_length -
+ net->remain_in_buf);
/* Restore the character that was overwritten by the end 0 */
- net->buff[start_of_packet]=net->save_char;
+ net->buff[start_of_packet]= net->save_char;
}
else
{
/* reuse buffer, as there is nothing in it that we need */
- buf_length=start_of_packet=first_packet_offset=0;
+ buf_length= start_of_packet= first_packet_offset= 0;
}
for (;;)
{
diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc
index 0a5f90617d1..dc3f3c87dde 100644
--- a/sql/repl_failsafe.cc
+++ b/sql/repl_failsafe.cc
@@ -249,6 +249,18 @@ static int find_target_pos(LEX_MASTER_INFO *mi, IO_CACHE *log, char *errmsg)
/* Impossible */
}
+/*
+ Before 4.0.15 we had a member of THD called log_pos, it was meant for
+ failsafe replication code in repl_failsafe.cc which is disabled until
+ it is reworked. Event's log_pos used to be preserved through
+ log-slave-updates to make code in repl_failsafe.cc work (this
+ function, SHOW NEW MASTER); but on the other side it caused unexpected
+ values in Exec_master_log_pos in A->B->C replication setup,
+ synchronization problems in master_pos_wait(), ... So we
+ (Dmitri & Guilhem) removed it.
+
+ So for now this function is broken.
+*/
int translate_master(THD* thd, LEX_MASTER_INFO* mi, char* errmsg)
{
@@ -414,6 +426,9 @@ static Slave_log_event* find_slave_event(IO_CACHE* log,
return (Slave_log_event*)ev;
}
+/*
+ This function is broken now. See comment for translate_master().
+ */
int show_new_master(THD* thd)
{
diff --git a/sql/slave.cc b/sql/slave.cc
index 85a9bc0d49e..32ed228e119 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -2253,7 +2253,6 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
if (!ev->when)
ev->when = time(NULL);
ev->thd = thd;
- thd->log_pos = ev->log_pos;
exec_res = ev->exec_event(rli);
DBUG_ASSERT(rli->sql_thd==thd);
delete ev;
@@ -2758,7 +2757,7 @@ static int process_io_create_file(MASTER_INFO* mi, Create_file_log_event* cev)
if (unlikely(net_request_file(net,cev->fname)))
{
sql_print_error("Slave I/O: failed requesting download of '%s'",
- cev->fname);
+ cev->fname);
goto err;
}
@@ -2768,56 +2767,56 @@ static int process_io_create_file(MASTER_INFO* mi, Create_file_log_event* cev)
in the loop
*/
{
- Append_block_log_event aev(thd,0,0,0);
+ Append_block_log_event aev(thd,0,0,0,0);
for (;;)
{
if (unlikely((num_bytes=my_net_read(net)) == packet_error))
{
- sql_print_error("Network read error downloading '%s' from master",
- cev->fname);
- goto err;
+ sql_print_error("Network read error downloading '%s' from master",
+ cev->fname);
+ goto err;
}
if (unlikely(!num_bytes)) /* eof */
{
- send_ok(net); /* 3.23 master wants it */
- Execute_load_log_event xev(thd,0);
- xev.log_pos = mi->master_log_pos;
- if (unlikely(mi->rli.relay_log.append(&xev)))
- {
- sql_print_error("Slave I/O: error writing Exec_load event to \
+ send_ok(net); /* 3.23 master wants it */
+ Execute_load_log_event xev(thd,0,0);
+ xev.log_pos = mi->master_log_pos;
+ if (unlikely(mi->rli.relay_log.append(&xev)))
+ {
+ sql_print_error("Slave I/O: error writing Exec_load event to \
relay log");
- goto err;
- }
- mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total);
- break;
+ goto err;
+ }
+ mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total);
+ break;
}
if (unlikely(cev_not_written))
{
- cev->block = (char*)net->read_pos;
- cev->block_len = num_bytes;
- cev->log_pos = mi->master_log_pos;
- if (unlikely(mi->rli.relay_log.append(cev)))
- {
- sql_print_error("Slave I/O: error writing Create_file event to \
+ cev->block = (char*)net->read_pos;
+ cev->block_len = num_bytes;
+ cev->log_pos = mi->master_log_pos;
+ if (unlikely(mi->rli.relay_log.append(cev)))
+ {
+ sql_print_error("Slave I/O: error writing Create_file event to \
relay log");
- goto err;
- }
- cev_not_written=0;
- mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total);
+ goto err;
+ }
+ cev_not_written=0;
+ mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total);
}
else
{
- aev.block = (char*)net->read_pos;
- aev.block_len = num_bytes;
- aev.log_pos = mi->master_log_pos;
- if (unlikely(mi->rli.relay_log.append(&aev)))
- {
- sql_print_error("Slave I/O: error writing Append_block event to \
+ aev.block = (char*)net->read_pos;
+ aev.block_len = num_bytes;
+ aev.log_pos = mi->master_log_pos;
+ if (unlikely(mi->rli.relay_log.append(&aev)))
+ {
+ sql_print_error("Slave I/O: error writing Append_block event to \
relay log");
- goto err;
- }
- mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total) ;
+ goto err;
+ }
+ mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total) ;
}
}
}
@@ -2901,6 +2900,12 @@ static int queue_old_event(MASTER_INFO *mi, const char *buf,
tmp_buf[event_len]=0; // Create_file constructor wants null-term buffer
buf = (const char*)tmp_buf;
}
+ /*
+ This will transform LOAD_EVENT into CREATE_FILE_EVENT, ask the master to
+ send the loaded file, and write it to the relay log in the form of
+ Append_block/Exec_load (the SQL thread needs the data, as that thread is not
+ connected to the master).
+ */
Log_event *ev = Log_event::read_log_event(buf,event_len, &errmsg,
1 /*old format*/ );
if (unlikely(!ev))
@@ -2930,6 +2935,12 @@ static int queue_old_event(MASTER_INFO *mi, const char *buf,
inc_pos= 0;
break;
case CREATE_FILE_EVENT:
+ /*
+ Yes it's possible to have CREATE_FILE_EVENT here, even if we're in
+ queue_old_event() which is for 3.23 events which don't comprise
+ CREATE_FILE_EVENT. This is because read_log_event() above has just
+ transformed LOAD_EVENT into CREATE_FILE_EVENT.
+ */
{
/* We come here when and only when tmp_buf != 0 */
DBUG_ASSERT(tmp_buf);
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 2a65291c273..132e0d7745f 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -125,7 +125,6 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
where="field list";
server_id = ::server_id;
slave_net = 0;
- log_pos = 0;
command=COM_CONNECT;
set_query_id=1;
db_access=NO_ACCESS;
diff --git a/sql/sql_class.h b/sql/sql_class.h
index c4511652b23..49a364856eb 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -472,7 +472,6 @@ public:
*/
ulong slave_proxy_id;
NET* slave_net; // network connection from slave -> m.
- my_off_t log_pos;
/* Used by the sys_var class to store temporary values */
union
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index ee573672c35..593cfb82b1c 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -299,7 +299,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
which is nonsense.
*/
read_info.end_io_cache();
- Delete_file_log_event d(thd, log_delayed);
+ Delete_file_log_event d(thd, db, log_delayed);
mysql_bin_log.write(&d);
}
}
@@ -331,7 +331,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
read_info.end_io_cache(); // make sure last block gets logged
if (lf_info.wrote_create_file)
{
- Execute_load_log_event e(thd, log_delayed);
+ Execute_load_log_event e(thd, db, log_delayed);
mysql_bin_log.write(&e);
}
}
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 1d82ac6110b..1479a611b5a 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1458,6 +1458,7 @@ mysql_execute_command(void)
{
if (check_global_access(thd, REPL_SLAVE_ACL))
goto error;
+ /* This query don't work now. See comment in repl_failsafe.cc */
#ifndef WORKING_NEW_MASTER
net_printf(&thd->net, ER_NOT_SUPPORTED_YET, "SHOW NEW MASTER");
res= 1;
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index cdd0bca4a0e..5a42614dff4 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -1216,7 +1216,7 @@ int log_loaded_block(IO_CACHE* file)
lf_info->last_pos_in_file = file->pos_in_file;
if (lf_info->wrote_create_file)
{
- Append_block_log_event a(lf_info->thd, buffer, block_len,
+ Append_block_log_event a(lf_info->thd, lf_info->db, buffer, block_len,
lf_info->log_delayed);
mysql_bin_log.write(&a);
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 7922af04ea8..560f5f5dc79 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -7224,7 +7224,7 @@ update_tmptable_sum_func(Item_sum **func_ptr,
{
Item_sum *func;
while ((func= *(func_ptr++)))
- func->update_field(0);
+ func->update_field();
}
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index bd7bc7027d3..34acd79f18b 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -31,9 +31,10 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
ORDER *order;
List<Item> item_list;
TABLE *table;
- int describe=(lex->select_lex.options & SELECT_DESCRIBE) ? 1 : 0;
int res;
- bool found_rows_for_union= lex->select_lex.options & OPTION_FOUND_ROWS;
+ ulonglong add_rows= 0;
+ ulong found_rows_for_union= lex->select_lex.options & OPTION_FOUND_ROWS;
+ ulong describe= lex->select_lex.options & SELECT_DESCRIBE;
TABLE_LIST result_table_list;
TABLE_LIST *first_table=(TABLE_LIST *)lex->select_lex.table_list.first;
TMP_TABLE_PARAM tmp_table_param;
@@ -135,14 +136,44 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
union_result->tmp_table_param=&tmp_table_param;
for (sl= &lex->select_lex; sl; sl=sl->next)
{
+ ha_rows records_at_start;
lex->select=sl;
- thd->offset_limit=sl->offset_limit;
- thd->select_limit=sl->select_limit+sl->offset_limit;
+ /* Don't use offset for the last union if there is no braces */
+ if (sl != lex_sl)
+ {
+ thd->offset_limit= sl->offset_limit;
+ thd->select_limit=sl->select_limit+sl->offset_limit;
+ }
+ else
+ {
+ thd->offset_limit= 0;
+ /*
+ We can't use LIMIT at this stage if we are using ORDER BY for the
+ whole query
+ */
+ thd->select_limit= HA_POS_ERROR;
+ if (! sl->order_list.first)
+ thd->select_limit= sl->select_limit+sl->offset_limit;
+ }
if (thd->select_limit < sl->select_limit)
thd->select_limit= HA_POS_ERROR; // no limit
+
+ /*
+ When using braces, SQL_CALC_FOUND_ROWS affects the whole query.
+ We don't calculate found_rows() per union part
+ */
if (thd->select_limit == HA_POS_ERROR || sl->braces)
sl->options&= ~OPTION_FOUND_ROWS;
+ else
+ {
+ /*
+ We are doing an union without braces. In this case
+ SQL_CALC_FOUND_ROWS should be done on all sub parts
+ */
+ sl->options|= found_rows_for_union;
+ }
+ records_at_start= table->file->records;
res=mysql_select(thd, (describe && sl->linkage==NOT_A_SELECT) ?
first_table : (TABLE_LIST*) sl->table_list.first,
sl->item_list,
@@ -153,10 +184,23 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
sl->having,
(ORDER*) NULL,
sl->options | thd->options | SELECT_NO_UNLOCK |
- ((describe) ? SELECT_DESCRIBE : 0),
+ describe,
union_result);
if (res)
goto exit;
+ /* Needed for the following test and for records_at_start in next loop */
+ table->file->info(HA_STATUS_VARIABLE);
+ if (found_rows_for_union & sl->options)
+ {
+ /*
+ This is a union without braces. Remember the number of rows that could
+ also have been part of the result set.
+ We get this from the difference of between total number of possible
+ rows and actual rows added to the temporary table.
+ */
+ add_rows+= (ulonglong) (thd->limit_found_rows - (table->file->records -
+ records_at_start));
+ }
}
if (union_result->flush())
{
@@ -172,19 +216,14 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
/* Create a list of fields in the temporary table */
List_iterator<Item> it(item_list);
Field **field;
-#if 0
- List<Item_func_match> ftfunc_list;
- ftfunc_list.empty();
-#else
thd->lex.select_lex.ftfunc_list.empty();
-#endif
for (field=table->field ; *field ; field++)
{
(void) it++;
(void) it.replace(new Item_field(*field));
}
- if (!thd->fatal_error) // Check if EOM
+ if (!thd->fatal_error) // Check if EOM
{
if (lex_sl)
{
@@ -209,8 +248,8 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
item_list, NULL, (describe) ? 0 : order,
(ORDER*) NULL, NULL, (ORDER*) NULL,
thd->options, result);
- if (found_rows_for_union && !res)
- thd->limit_found_rows = (ulonglong)table->file->records;
+ if (!res)
+ thd->limit_found_rows = (ulonglong)table->file->records + add_rows;
}
}