summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <monty@hundin.mysql.fi>2002-11-07 04:02:37 +0200
committerunknown <monty@hundin.mysql.fi>2002-11-07 04:02:37 +0200
commit72413e7f81cb87327d8bb2094a43d66578cd1632 (patch)
treee27391c030124332f69b62384e7e47e39f8e1818 /sql
parent23f4865b163293006bbedbc2b69bc55ba1081baa (diff)
downloadmariadb-git-72413e7f81cb87327d8bb2094a43d66578cd1632.tar.gz
Put temporary files in binlog cache when using BEGIN/COMMIT
Let MySQL 4.0 read 4.1 .frm files without 4.1 specific extensions New variables @@rand_seed1 and @@rand_seed2 (used by replication) DROP TEMPORARY TABLE mysql-test/r/rpl_log.result: Update of results after last replication change mysql-test/r/variables.result: Test of new variables @@rand_seed1 and @@rand_seed2 mysql-test/t/variables.test: Test of new variables @@rand_seed1 and @@rand_seed2 sql/field.cc: Let MySQL 4.0 read 4.1 .frm files without 4.1 specific extensions sql/field.h: Let MySQL 4.0 read 4.1 .frm files without 4.1 specific extensions sql/item_func.cc: Put temporary files in binlog cache when using BEGIN/COMMIT sql/log.cc: Put temporary files in binlog cache when using BEGIN/COMMIT More debug information sql/log_event.cc: Put temporary files in binlog cache when using BEGIN/COMMIT sql/log_event.h: Put temporary files in binlog cache when using BEGIN/COMMIT sql/set_var.cc: Add system variables @@rand_seed1 and @@rand_seed2 sql/set_var.h: Add system variables @@rand_seed1 and @@rand_seed2 sql/slave.cc: Put temporary files in binlog cache when using BEGIN/COMMIT sql/sql_acl.cc: Put temporary files in binlog cache when using BEGIN/COMMIT sql/sql_base.cc: Store DROP of temporary tables in binlog cache sql/sql_class.h: Put temporary files in binlog cache when using BEGIN/COMMIT sql/sql_db.cc: Put temporary files in binlog cache when using BEGIN/COMMIT sql/sql_delete.cc: Put temporary files in binlog cache when using BEGIN/COMMIT sql/sql_insert.cc: Put temporary files in binlog cache when using BEGIN/COMMIT sql/sql_lex.h: DROP TEMPORARY TABLE sql/sql_load.cc: Put temporary files in binlog cache when using BEGIN/COMMIT sql/sql_parse.cc: Put temporary files in binlog cache when using BEGIN/COMMIT sql/sql_rename.cc: Put temporary files in binlog cache when using BEGIN/COMMIT sql/sql_repl.cc: Put temporary files in binlog cache when using BEGIN/COMMIT sql/sql_repl.h: Put temporary files in binlog cache when using BEGIN/COMMIT sql/sql_table.cc: Put temporary files in binlog cache when using BEGIN/COMMIT sql/sql_update.cc: Put temporary files in binlog cache when using BEGIN/COMMIT sql/sql_yacc.yy: DROP TEMPORARY sql/table.cc: Let MySQL 4.0 read 4.1 .frm files without 4.1 specific extensions sql/unireg.cc: Let MySQL 4.0 read 4.1 .frm files without 4.1 specific extensions
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc11
-rw-r--r--sql/field.h6
-rw-r--r--sql/item_func.cc2
-rw-r--r--sql/log.cc18
-rw-r--r--sql/log_event.cc100
-rw-r--r--sql/log_event.h50
-rw-r--r--sql/set_var.cc17
-rw-r--r--sql/set_var.h17
-rw-r--r--sql/slave.cc4
-rw-r--r--sql/sql_acl.cc2
-rw-r--r--sql/sql_base.cc28
-rw-r--r--sql/sql_class.h4
-rw-r--r--sql/sql_db.cc4
-rw-r--r--sql/sql_delete.cc57
-rw-r--r--sql/sql_insert.cc18
-rw-r--r--sql/sql_lex.h2
-rw-r--r--sql/sql_load.cc31
-rw-r--r--sql/sql_parse.cc6
-rw-r--r--sql/sql_rename.cc2
-rw-r--r--sql/sql_repl.cc5
-rw-r--r--sql/sql_repl.h4
-rw-r--r--sql/sql_table.cc55
-rw-r--r--sql/sql_update.cc19
-rw-r--r--sql/sql_yacc.yy13
-rw-r--r--sql/table.cc76
-rw-r--r--sql/unireg.cc1
26 files changed, 333 insertions, 219 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 42ddcc3b9d2..eed165f0ed1 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -4864,6 +4864,7 @@ uint pack_length_to_packflag(uint type)
Field *make_field(char *ptr, uint32 field_length,
uchar *null_pos, uchar null_bit,
uint pack_flag,
+ enum_field_types field_type,
Field::utype unireg_check,
TYPELIB *interval,
const char *field_name,
@@ -4889,6 +4890,9 @@ Field *make_field(char *ptr, uint32 field_length,
return new Field_blob(ptr,null_pos,null_bit,
unireg_check, field_name, table,
pack_length,f_is_binary(pack_flag) != 0);
+ if (f_is_geom(pack_flag))
+ return 0;
+
if (interval)
{
if (f_is_enum(pack_flag))
@@ -4902,7 +4906,7 @@ Field *make_field(char *ptr, uint32 field_length,
}
}
- switch ((enum enum_field_types) f_packtype(pack_flag)) {
+ switch (field_type) {
case FIELD_TYPE_DECIMAL:
return new Field_decimal(ptr,field_length,null_pos,null_bit,
unireg_check, field_name, table,
@@ -4965,10 +4969,11 @@ Field *make_field(char *ptr, uint32 field_length,
return new Field_datetime(ptr,null_pos,null_bit,
unireg_check, field_name, table);
case FIELD_TYPE_NULL:
- default: // Impossible (Wrong version)
return new Field_null(ptr,field_length,unireg_check,field_name,table);
+ default: // Impossible (Wrong version)
+ break;
}
- return 0; // Impossible (Wrong version)
+ return 0; // Impossible
}
diff --git a/sql/field.h b/sql/field.h
index 4290f99ea3e..ba28a6a872e 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1050,7 +1050,9 @@ public:
Field *make_field(char *ptr, uint32 field_length,
uchar *null_pos, uchar null_bit,
- uint pack_flag, Field::utype unireg_check,
+ uint pack_flag,
+ enum_field_types field_type,
+ Field::utype unireg_check,
TYPELIB *interval, const char *field_name,
struct st_table *table);
uint pack_length_to_packflag(uint type);
@@ -1073,6 +1075,7 @@ bool test_if_int(const char *str,int length);
#define FIELDFLAG_INTERVAL 256
#define FIELDFLAG_BITFIELD 512 // mangled with dec!
#define FIELDFLAG_BLOB 1024 // mangled with dec!
+#define FIELDFLAG_GEOM 2048
#define FIELDFLAG_LEFT_FULLSCREEN 8192
#define FIELDFLAG_RIGHT_FULLSCREEN 16384
#define FIELDFLAG_FORMAT_NUMBER 16384 // predit: ###,,## in output
@@ -1099,6 +1102,7 @@ bool test_if_int(const char *str,int length);
#define f_is_enum(x) ((x) & FIELDFLAG_INTERVAL)
#define f_is_bitfield(x) ((x) & FIELDFLAG_BITFIELD)
#define f_is_blob(x) (((x) & (FIELDFLAG_BLOB | FIELDFLAG_NUMBER)) == FIELDFLAG_BLOB)
+#define f_is_geom(x) ((x) & FIELDFLAG_GEOM)
#define f_is_equ(x) ((x) & (1+2+FIELDFLAG_PACK+31*256))
#define f_settype(x) (((int) x) << FIELDFLAG_PACK_SHIFT)
#define f_maybe_null(x) (x & FIELDFLAG_MAYBE_NULL)
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 7da5435276d..fec0e448630 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -1516,7 +1516,7 @@ void item_user_lock_release(ULL *ull)
tmp.append("DO RELEASE_LOCK(\"");
tmp.append(ull->key,ull->key_length);
tmp.append("\")");
- Query_log_event qev(current_thd,tmp.ptr(), tmp.length());
+ Query_log_event qev(current_thd, tmp.ptr(), tmp.length(),1);
qev.error_code=0; // this query is always safe to run on slave
mysql_bin_log.write(&qev);
}
diff --git a/sql/log.cc b/sql/log.cc
index 32c0f4417f1..5dc1a677f76 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -1017,9 +1017,13 @@ bool MYSQL_LOG::write(THD *thd,enum enum_server_command command,
bool MYSQL_LOG::write(Log_event* event_info)
{
bool error=0;
+ DBUG_ENTER("MYSQL_LOG::write(event)");
if (!inited) // Can't use mutex if not init
- return 0;
+ {
+ DBUG_PRINT("error",("not initied"));
+ DBUG_RETURN(0);
+ }
pthread_mutex_lock(&LOCK_log);
/* In most cases this is only called if 'is_open()' is true */
@@ -1040,7 +1044,8 @@ bool MYSQL_LOG::write(Log_event* event_info)
(db && !db_ok(db, binlog_do_db, binlog_ignore_db)))
{
VOID(pthread_mutex_unlock(&LOCK_log));
- return 0;
+ DBUG_PRINT("error",("!db_ok"));
+ DBUG_RETURN(0);
}
error=1;
@@ -1078,7 +1083,7 @@ bool MYSQL_LOG::write(Log_event* event_info)
char buf[1024] = "SET CHARACTER SET ";
char* p = strend(buf);
p = strmov(p, thd->variables.convert_set->name);
- Query_log_event e(thd, buf, (ulong)(p - buf));
+ Query_log_event e(thd, buf, (ulong)(p - buf), 0);
e.set_log_pos(this);
if (e.write(file))
goto err;
@@ -1126,7 +1131,7 @@ err:
}
pthread_mutex_unlock(&LOCK_log);
- return error;
+ DBUG_RETURN(error);
}
@@ -1156,6 +1161,7 @@ uint MYSQL_LOG::next_file_id()
bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache)
{
VOID(pthread_mutex_lock(&LOCK_log));
+ DBUG_ENTER("MYSQL_LOG::write(cache");
if (is_open()) // Should always be true
{
@@ -1214,7 +1220,7 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache)
signal_update();
}
VOID(pthread_mutex_unlock(&LOCK_log));
- return 0;
+ DBUG_RETURN(0);
err:
if (!write_error)
@@ -1223,7 +1229,7 @@ err:
sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
}
VOID(pthread_mutex_unlock(&LOCK_log));
- return 1;
+ DBUG_RETURN(1);
}
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 871f72acbae..12f97d825a6 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -131,22 +131,25 @@ const char* Log_event::get_type_str()
}
#ifndef MYSQL_CLIENT
-Log_event::Log_event(THD* thd_arg, uint16 flags_arg)
- :exec_time(0), flags(flags_arg), cached_event_len(0),
- temp_buf(0), thd(thd_arg)
+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)
{
- if (thd)
- {
- server_id = thd->server_id;
- when = thd->start_time;
- log_pos = thd->log_pos;
- }
- else
- {
- server_id = ::server_id;
- when = time(NULL);
- log_pos=0;
- }
+ 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)));
+}
+
+
+Log_event::Log_event()
+ :temp_buf(0), exec_time(0), cached_event_len(0), flags(0), cache_stmt(0),
+ thd(0)
+{
+ server_id = ::server_id;
+ when = time(NULL);
+ log_pos=0;
}
/*
@@ -179,7 +182,7 @@ static void cleanup_load_tmpdir()
#endif
Log_event::Log_event(const char* buf, bool old_format)
- :cached_event_len(0), temp_buf(0)
+ :temp_buf(0), cached_event_len(0), cache_stmt(0)
{
when = uint4korr(buf);
server_id = uint4korr(buf + SERVER_ID_OFFSET);
@@ -350,14 +353,12 @@ void Intvar_log_event::pack_info(String* packet)
void Rand_log_event::pack_info(String* packet)
{
- char buf1[256], buf[22];
- String tmp(buf1, sizeof(buf1));
- tmp.length(0);
- tmp.append("randseed1=");
- tmp.append(llstr(seed1, buf));
- tmp.append(",randseed2=");
- tmp.append(llstr(seed2, buf));
- net_store_data(packet, tmp.ptr(), tmp.length());
+ char buf1[256], *pos;
+ pos=strmov(buf1,"rand_seed1=");
+ pos=int10_to_str((long) seed1, pos, 10);
+ pos=strmov(pos, ",rand_seed2=");
+ pos=int10_to_str((long) seed2, pos, 10);
+ net_store_data(packet, buf1, (uint) (pos-buf1));
}
void Slave_log_event::pack_info(String* packet)
@@ -783,12 +784,10 @@ int Rotate_log_event::write_data(IO_CACHE* file)
#ifndef MYSQL_CLIENT
Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
ulong query_length, bool using_trans)
- :Log_event(thd_arg), data_buf(0), query(query_arg), db(thd_arg->db),
- q_len((uint32) query_length),
+ :Log_event(thd_arg, 0, using_trans), data_buf(0), query(query_arg),
+ db(thd_arg->db), q_len((uint32) query_length),
error_code(thd_arg->killed ? ER_SERVER_SHUTDOWN: thd_arg->net.last_errno),
- thread_id(thd_arg->thread_id),
- cache_stmt(using_trans &&
- (thd_arg->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
+ thread_id(thd_arg->thread_id)
{
time_t end_time;
time(&end_time);
@@ -963,8 +962,8 @@ void Rand_log_event::print(FILE* file, bool short_form, char* last_db)
print_header(file);
fprintf(file, "\tRand\n");
}
- fprintf(file, "SET RAND SEED1=%s;\n", llstr(seed1, llbuff));
- fprintf(file, "SET RAND SEED2=%s;\n", llstr(seed2, llbuff));
+ fprintf(file, "SET @@RAND_SEED1=%s, @@RAND_SEED2=%s;\n",
+ llstr(seed1, llbuff),llstr(seed2, llbuff));
fflush(file);
}
#endif
@@ -1093,8 +1092,10 @@ char* sql_ex_info::init(char* buf,char* buf_end,bool use_new_format)
Load_log_event::Load_log_event(THD* thd, sql_exchange* ex,
const char* db_arg, const char* table_name_arg,
List<Item>& fields_arg,
- enum enum_duplicates handle_dup)
- :Log_event(thd),thread_id(thd->thread_id), num_fields(0),fields(0),
+ enum enum_duplicates handle_dup,
+ bool using_trans)
+ :Log_event(thd, 0, using_trans),thread_id(thd->thread_id),
+ num_fields(0),fields(0),
field_lens(0),field_block_len(0),
table_name(table_name_arg ? table_name_arg : ""),
db(db_arg), fname(ex->file_name)
@@ -1332,7 +1333,7 @@ void Load_log_event::set_fields(List<Item> &fields)
Slave_log_event::Slave_log_event(THD* thd_arg,
struct st_relay_log_info* rli):
- Log_event(thd_arg),mem_pool(0),master_host(0)
+ Log_event(thd_arg,0,0),mem_pool(0),master_host(0)
{
DBUG_ENTER("Slave_log_event");
if (!rli->inited) // QQ When can this happen ?
@@ -1432,11 +1433,13 @@ Slave_log_event::Slave_log_event(const char* buf, int event_len)
}
#ifndef MYSQL_CLIENT
-Create_file_log_event::Create_file_log_event(THD* thd_arg, sql_exchange* ex,
- const char* db_arg, const char* table_name_arg,
- List<Item>& fields_arg, enum enum_duplicates handle_dup,
- char* block_arg, uint block_len_arg)
- :Load_log_event(thd_arg,ex,db_arg,table_name_arg,fields_arg,handle_dup),
+Create_file_log_event::
+Create_file_log_event(THD* thd_arg, sql_exchange* ex,
+ const char* db_arg, const char* table_name_arg,
+ List<Item>& fields_arg, enum enum_duplicates handle_dup,
+ char* block_arg, uint block_len_arg, bool using_trans)
+ :Load_log_event(thd_arg,ex,db_arg,table_name_arg,fields_arg,handle_dup,
+ using_trans),
fake_base(0),block(block_arg),block_len(block_len_arg),
file_id(thd_arg->file_id = mysql_bin_log.next_file_id())
{
@@ -1532,9 +1535,10 @@ void Create_file_log_event::pack_info(String* packet)
#ifndef MYSQL_CLIENT
Append_block_log_event::Append_block_log_event(THD* thd_arg, char* block_arg,
- uint block_len_arg)
- :Log_event(thd_arg), block(block_arg),block_len(block_len_arg),
- file_id(thd_arg->file_id)
+ 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)
{
}
#endif
@@ -1578,8 +1582,8 @@ 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)
- :Log_event(thd_arg),file_id(thd_arg->file_id)
+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)
{
}
#endif
@@ -1624,14 +1628,14 @@ void Delete_file_log_event::pack_info(String* packet)
#ifndef MYSQL_CLIENT
-Execute_load_log_event::Execute_load_log_event(THD* thd_arg)
- :Log_event(thd_arg),file_id(thd_arg->file_id)
+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)
{
}
#endif
-Execute_load_log_event::Execute_load_log_event(const char* buf,int len)
- :Log_event(buf, 0),file_id(0)
+Execute_load_log_event::Execute_load_log_event(const char* buf, int len)
+ :Log_event(buf, 0), file_id(0)
{
if ((uint)len < EXEC_LOAD_EVENT_OVERHEAD)
return;
diff --git a/sql/log_event.h b/sql/log_event.h
index 2a133becbad..69a70d535ec 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -224,18 +224,19 @@ struct st_relay_log_info;
class Log_event
{
public:
+ my_off_t log_pos;
+ char *temp_buf;
time_t when;
ulong exec_time;
uint32 server_id;
- my_off_t log_pos;
+ uint cached_event_len;
uint16 flags;
- int cached_event_len;
- char* temp_buf;
-
+ bool cache_stmt;
#ifndef MYSQL_CLIENT
THD* thd;
- Log_event(THD* thd_arg, uint16 flags_arg = 0);
+ Log_event(THD* thd_arg, uint16 flags_arg, bool cache_stmt);
+ Log_event();
// if mutex is 0, the read will proceed without mutex
static Log_event* read_log_event(IO_CACHE* file,
pthread_mutex_t* log_lock,
@@ -278,7 +279,7 @@ public:
{ return 0; }
virtual Log_event_type get_type_code() = 0;
virtual bool is_valid() = 0;
- virtual bool get_cache_stmt() { return 0; }
+ inline bool get_cache_stmt() { return cache_stmt; }
Log_event(const char* buf, bool old_format);
virtual ~Log_event() { free_temp_buf();}
void register_temp_buf(char* buf) { temp_buf = buf; }
@@ -320,14 +321,12 @@ public:
uint16 error_code;
ulong thread_id;
#ifndef MYSQL_CLIENT
- bool cache_stmt;
Query_log_event(THD* thd_arg, const char* query_arg, ulong query_length,
- bool using_trans=0);
+ bool using_trans);
const char* get_db() { return db; }
void pack_info(String* packet);
int exec_event(struct st_relay_log_info* rli);
- bool get_cache_stmt() { return cache_stmt; }
#else
void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif
@@ -404,14 +403,15 @@ public:
const char* fname;
uint32 skip_lines;
sql_ex_info sql_ex;
-
+
#ifndef MYSQL_CLIENT
String field_lens_buf;
String fields_buf;
Load_log_event(THD* thd, sql_exchange* ex, const char* db_arg,
const char* table_name_arg,
- List<Item>& fields_arg, enum enum_duplicates handle_dup);
+ List<Item>& fields_arg, enum enum_duplicates handle_dup,
+ bool using_trans);
void set_fields(List<Item> &fields_arg);
void pack_info(String* packet);
const char* get_db() { return db; }
@@ -427,8 +427,10 @@ public:
Load_log_event(const char* buf, int event_len, bool old_format);
~Load_log_event()
{}
- Log_event_type get_type_code() { return sql_ex.new_format() ?
- NEW_LOAD_EVENT: LOAD_EVENT; }
+ Log_event_type get_type_code()
+ {
+ return sql_ex.new_format() ? NEW_LOAD_EVENT: LOAD_EVENT;
+ }
int write_data_header(IO_CACHE* file);
int write_data_body(IO_CACHE* file);
bool is_valid() { return table_name != 0; }
@@ -454,7 +456,7 @@ public:
char server_version[ST_SERVER_VER_LEN];
#ifndef MYSQL_CLIENT
- Start_log_event() :Log_event((THD*)0),binlog_version(BINLOG_VERSION)
+ Start_log_event() :Log_event(), binlog_version(BINLOG_VERSION)
{
created = (uint32) when;
memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
@@ -485,7 +487,7 @@ public:
#ifndef MYSQL_CLIENT
Intvar_log_event(THD* thd_arg,uchar type_arg, ulonglong val_arg)
- :Log_event(thd_arg),val(val_arg),type(type_arg)
+ :Log_event(),val(val_arg),type(type_arg)
{}
void pack_info(String* packet);
int exec_event(struct st_relay_log_info* rli);
@@ -515,7 +517,7 @@ class Rand_log_event: public Log_event
#ifndef MYSQL_CLIENT
Rand_log_event(THD* thd_arg, ulonglong seed1_arg, ulonglong seed2_arg)
- :Log_event(thd_arg),seed1(seed1_arg),seed2(seed2_arg)
+ :Log_event(thd_arg,0,0),seed1(seed1_arg),seed2(seed2_arg)
{}
void pack_info(String* packet);
int exec_event(struct st_relay_log_info* rli);
@@ -536,7 +538,7 @@ class Stop_log_event: public Log_event
{
public:
#ifndef MYSQL_CLIENT
- Stop_log_event() :Log_event((THD*)0)
+ Stop_log_event() :Log_event()
{}
int exec_event(struct st_relay_log_info* rli);
#else
@@ -561,8 +563,9 @@ public:
bool alloced;
#ifndef MYSQL_CLIENT
Rotate_log_event(THD* thd_arg, const char* new_log_ident_arg,
- uint ident_len_arg = 0,ulonglong pos_arg = 4)
- : Log_event(thd_arg), new_log_ident(new_log_ident_arg),
+ uint ident_len_arg = 0,
+ ulonglong pos_arg = LOG_EVENT_OFFSET)
+ :Log_event(thd_arg,0,0), new_log_ident(new_log_ident_arg),
pos(pos_arg),ident_len(ident_len_arg ? ident_len_arg :
(uint) strlen(new_log_ident_arg)), alloced(0)
{}
@@ -606,7 +609,8 @@ public:
const char* table_name_arg,
List<Item>& fields_arg,
enum enum_duplicates handle_dup,
- char* block_arg, uint block_len_arg);
+ char* block_arg, uint block_len_arg,
+ bool using_trans);
void pack_info(String* packet);
int exec_event(struct st_relay_log_info* rli);
#else
@@ -651,7 +655,7 @@ public:
#ifndef MYSQL_CLIENT
Append_block_log_event(THD* thd, char* block_arg,
- uint block_len_arg);
+ uint block_len_arg, bool using_trans);
int exec_event(struct st_relay_log_info* rli);
void pack_info(String* packet);
#else
@@ -673,7 +677,7 @@ public:
uint file_id;
#ifndef MYSQL_CLIENT
- Delete_file_log_event(THD* thd);
+ Delete_file_log_event(THD* thd, bool using_trans);
void pack_info(String* packet);
int exec_event(struct st_relay_log_info* rli);
#else
@@ -694,7 +698,7 @@ public:
uint file_id;
#ifndef MYSQL_CLIENT
- Execute_load_log_event(THD* thd);
+ Execute_load_log_event(THD* thd, bool using_trans);
void pack_info(String* packet);
int exec_event(struct st_relay_log_info* rli);
#else
diff --git a/sql/set_var.cc b/sql/set_var.cc
index a992ddf6044..ce85a81594c 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -283,6 +283,8 @@ static sys_var_last_insert_id sys_identity("identity");
static sys_var_insert_id sys_insert_id("insert_id");
/* alias for last_insert_id() to be compatible with Sybase */
static sys_var_slave_skip_counter sys_slave_skip_counter("sql_slave_skip_counter");
+static sys_var_rand_seed1 sys_rand_seed1("rand_seed1");
+static sys_var_rand_seed2 sys_rand_seed2("rand_seed2");
/*
@@ -351,6 +353,8 @@ sys_var *sys_variables[]=
&sys_query_cache_type,
#endif /* HAVE_QUERY_CACHE */
&sys_quote_show_create,
+ &sys_rand_seed1,
+ &sys_rand_seed2,
&sys_read_buff_size,
&sys_read_rnd_buff_size,
&sys_rpl_recovery_rank,
@@ -1043,6 +1047,19 @@ bool sys_var_slave_skip_counter::update(THD *thd, set_var *var)
}
+bool sys_var_rand_seed1::update(THD *thd, set_var *var)
+{
+ thd->rand.seed1=var->value->val_int();
+ return 0;
+}
+
+bool sys_var_rand_seed2::update(THD *thd, set_var *var)
+{
+ thd->rand.seed2=var->value->val_int();
+ return 0;
+}
+
+
/*
Functions to update thd->options bits
*/
diff --git a/sql/set_var.h b/sql/set_var.h
index c43cdbfd63e..a171c4f5e76 100644
--- a/sql/set_var.h
+++ b/sql/set_var.h
@@ -332,6 +332,23 @@ public:
};
+class sys_var_rand_seed1 :public sys_var
+{
+public:
+ sys_var_rand_seed1(const char *name_arg) :sys_var(name_arg) {}
+ bool update(THD *thd, set_var *var);
+ bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
+};
+
+class sys_var_rand_seed2 :public sys_var
+{
+public:
+ sys_var_rand_seed2(const char *name_arg) :sys_var(name_arg) {}
+ bool update(THD *thd, set_var *var);
+ bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
+};
+
+
class sys_var_thd_conv_charset :public sys_var_thd
{
public:
diff --git a/sql/slave.cc b/sql/slave.cc
index 620523dd47f..5d82f34bfab 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -2252,7 +2252,7 @@ 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);
+ Append_block_log_event aev(thd,0,0,0);
for (;;)
{
@@ -2265,7 +2265,7 @@ static int process_io_create_file(MASTER_INFO* mi, Create_file_log_event* cev)
if (unlikely(!num_bytes)) /* eof */
{
send_ok(net); /* 3.23 master wants it */
- Execute_load_log_event xev(thd);
+ Execute_load_log_event xev(thd,0);
xev.log_pos = mi->master_log_pos;
if (unlikely(mi->rli.relay_log.append(&xev)))
{
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 1694e662b52..dc59f3f3137 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -1091,7 +1091,7 @@ bool change_password(THD *thd, const char *host, const char *user,
acl_user->host.hostname ? acl_user->host.hostname : "",
new_password));
mysql_update_log.write(thd, buff, query_length);
- Query_log_event qinfo(thd, buff, query_length);
+ Query_log_event qinfo(thd, buff, query_length, 0);
mysql_bin_log.write(&qinfo);
DBUG_RETURN(0);
}
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 3b46c53f75c..838cf70f08d 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -539,26 +539,20 @@ void close_temporary_tables(THD *thd)
{
TABLE *table,*next;
char *query, *end;
- const uint init_query_buf_size = 11; // "drop table "
uint query_buf_size;
bool found_user_tables = 0;
+ if (!thd->temporary_tables)
+ return;
+
LINT_INIT(end);
- query_buf_size = init_query_buf_size;
+ query_buf_size= 50; // Enough for DROP ... TABLE
for (table=thd->temporary_tables ; table ; table=table->next)
- {
query_buf_size += table->key_length;
- }
-
- if (query_buf_size == init_query_buf_size)
- return; // no tables to close
if ((query = alloc_root(&thd->mem_root, query_buf_size)))
- {
- memcpy(query, "drop table ", init_query_buf_size);
- end = query + init_query_buf_size;
- }
+ end=strmov(query, "DROP /*!40005 TEMPORARY */ TABLE ");
for (table=thd->temporary_tables ; table ; table=next)
{
@@ -567,12 +561,14 @@ void close_temporary_tables(THD *thd)
// skip temporary tables not created directly by the user
if (table->real_name[0] != '#')
{
- end = strxmov(end,table->table_cache_key,".",
- table->real_name,",", NullS);
- // here we assume table_cache_key always starts
- // with \0 terminated db name
+ /*
+ Here we assume table_cache_key always starts
+ with \0 terminated db name
+ */
found_user_tables = 1;
}
+ end = strxmov(end,table->table_cache_key,".",
+ table->real_name,",", NullS);
}
next=table->next;
close_temporary(table);
@@ -580,7 +576,7 @@ void close_temporary_tables(THD *thd)
if (query && found_user_tables && mysql_bin_log.is_open())
{
/* The -1 is to remove last ',' */
- Query_log_event qinfo(thd, query, (ulong)(end-query)-1);
+ Query_log_event qinfo(thd, query, (ulong)(end-query)-1, 0);
qinfo.error_code=0;
mysql_bin_log.write(&qinfo);
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index b8921964804..0f010b9de28 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -419,6 +419,7 @@ public:
table_map used_tables;
USER_CONN *user_connect;
ulong query_id,version, options,thread_id, col_access;
+ ulong rand_saved_seed1, rand_saved_seed2;
long dbug_thread_id;
pthread_t real_id;
uint current_tablenr,tmp_table,cond_count;
@@ -433,7 +434,6 @@ public:
bool set_query_id,locked,count_cuted_fields,some_tables_deleted;
bool no_errors, allow_sum_func, password, fatal_error;
bool query_start_used,last_insert_id_used,insert_id_used,rand_used;
- ulonglong rand_saved_seed1, rand_saved_seed2;
bool system_thread,in_lock_tables,global_read_lock;
bool query_error, bootstrap, cleanup_done;
bool safe_to_cache_query;
@@ -805,7 +805,7 @@ public:
uint num_of_tables;
int error;
thr_lock_type lock_option;
- bool do_delete, not_trans_safe;
+ bool do_delete, transactional_tables, log_delayed, normal_tables;
public:
multi_delete(THD *thd, TABLE_LIST *dt, thr_lock_type lock_option_arg,
uint num_of_tables);
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index be193ee0b55..cde0c6cc31f 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -86,7 +86,7 @@ int mysql_create_db(THD *thd, char *db, uint create_options, bool silent)
mysql_update_log.write(thd,thd->query, thd->query_length);
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query, thd->query_length);
+ Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
mysql_bin_log.write(&qinfo);
}
}
@@ -174,7 +174,7 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
mysql_update_log.write(thd, thd->query, thd->query_length);
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query, thd->query_length);
+ Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
mysql_bin_log.write(&qinfo);
}
if (thd->query == path)
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index b40e0b7b093..1faa6e3250e 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -35,7 +35,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order,
SQL_SELECT *select=0;
READ_RECORD info;
bool using_limit=limit != HA_POS_ERROR;
- bool using_transactions;
+ bool transactional_table, log_delayed;
ha_rows deleted;
DBUG_ENTER("mysql_delete");
@@ -161,21 +161,22 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order,
(void) table->file->extra(HA_EXTRA_NORMAL);
cleanup:
- using_transactions=table->file->has_transactions();
- if (deleted && (error <= 0 || !using_transactions))
+ transactional_table= table->file->has_transactions();
+ log_delayed= (transactional_table || table->tmp_table);
+ if (deleted && (error <= 0 || !transactional_table))
{
mysql_update_log.write(thd,thd->query, thd->query_length);
if (mysql_bin_log.is_open())
{
Query_log_event qinfo(thd, thd->query, thd->query_length,
- using_transactions);
- if (mysql_bin_log.write(&qinfo) && using_transactions)
+ log_delayed);
+ if (mysql_bin_log.write(&qinfo) && transactional_table)
error=1;
}
- if (!using_transactions)
+ if (!log_delayed)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
}
- if (using_transactions && ha_autocommit_or_rollback(thd,error >= 0))
+ if (transactional_table && ha_autocommit_or_rollback(thd,error >= 0))
error=1;
if (deleted)
{
@@ -214,9 +215,8 @@ multi_delete::multi_delete(THD *thd_arg, TABLE_LIST *dt,
uint num_of_tables_arg)
: delete_tables (dt), thd(thd_arg), deleted(0),
num_of_tables(num_of_tables_arg), error(0), lock_option(lock_option_arg),
- do_delete(false)
+ do_delete(0), transactional_tables(0), log_delayed(0), normal_tables(0)
{
- not_trans_safe=false;
tempfiles = (Unique **) sql_calloc(sizeof(Unique *) * (num_of_tables-1));
}
@@ -266,8 +266,12 @@ multi_delete::initialize_tables(JOIN *join)
/* Don't use KEYREAD optimization on this table */
tbl->no_keyread=1;
walk=walk->next;
- if (!not_trans_safe && !tbl->file->has_transactions())
- not_trans_safe=true;
+ if (tbl->file->has_transactions())
+ log_delayed= transactional_tables= 1;
+ else if (tbl->tmp_table != NO_TMP_TABLE)
+ log_delayed= 1;
+ else
+ normal_tables= 1;
}
}
walk= delete_tables;
@@ -373,7 +377,7 @@ void multi_delete::send_error(uint errcode,const char *err)
In all other cases do attempt deletes ...
*/
if ((table_being_deleted->table->file->has_transactions() &&
- table_being_deleted == delete_tables) || !not_trans_safe)
+ table_being_deleted == delete_tables) || !normal_tables)
ha_rollback_stmt(thd);
else if (do_delete)
{
@@ -419,8 +423,7 @@ int multi_delete::do_deletes(bool from_send_error)
READ_RECORD info;
init_read_record(&info,thd,table,NULL,0,0);
- while (!(error=info.read_record(&info)) &&
- (!thd->killed || from_send_error || not_trans_safe))
+ while (!(error=info.read_record(&info)) && !thd->killed)
{
if ((error=table->file->delete_row(table->record[0])))
{
@@ -453,11 +456,6 @@ bool multi_delete::send_eof()
/* reset used flags */
thd->proc_info="end";
- if (error)
- {
- ::send_error(&thd->net);
- return 1;
- }
/*
Write the SQL statement to the binlog if we deleted
@@ -465,24 +463,25 @@ bool multi_delete::send_eof()
was a non-transaction-safe table involved, since
modifications in it cannot be rolled back.
*/
- if (deleted || not_trans_safe)
+ if (deleted)
{
mysql_update_log.write(thd,thd->query,thd->query_length);
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query, thd->query_length);
- if (mysql_bin_log.write(&qinfo) &&
- !not_trans_safe)
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ log_delayed);
+ if (mysql_bin_log.write(&qinfo) && !normal_tables)
error=1; // Log write failed: roll back the SQL statement
}
/* Commit or rollback the current SQL statement */
VOID(ha_autocommit_or_rollback(thd,error > 0));
- }
- if (deleted)
- {
+
query_cache_invalidate3(thd, delete_tables, 1);
}
- ::send_ok(&thd->net,deleted);
+ if (error)
+ ::send_error(&thd->net);
+ else
+ ::send_ok(&thd->net,deleted);
return 0;
}
@@ -565,6 +564,7 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
*fn_ext(path)=0; // Remove the .frm extension
error= ha_create_table(path,&create_info,1) ? -1 : 0;
query_cache_invalidate3(thd, table_list, 0);
+
end:
if (!dont_send_ok)
{
@@ -573,7 +573,8 @@ end:
mysql_update_log.write(thd,thd->query,thd->query_length);
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query, thd->query_length);
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ thd->tmp_table);
mysql_bin_log.write(&qinfo);
}
send_ok(&thd->net); // This should return record count
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index bd379bf688d..81178809f8f 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -104,7 +104,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
int error;
bool log_on= ((thd->options & OPTION_UPDATE_LOG) ||
!(thd->master_access & SUPER_ACL));
- bool using_transactions, bulk_insert=0;
+ bool transactional_table, log_delayed, bulk_insert=0;
uint value_count;
uint save_time_stamp;
ulong counter = 1;
@@ -297,21 +297,23 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
thd->insert_id(id); // For update log
else if (table->next_number_field)
id=table->next_number_field->val_int(); // Return auto_increment value
- using_transactions=table->file->has_transactions();
- if ((info.copied || info.deleted) && (error <= 0 || !using_transactions))
+
+ transactional_table= table->file->has_transactions();
+ log_delayed= (transactional_table || table->tmp_table);
+ if ((info.copied || info.deleted) && (error <= 0 || !transactional_table))
{
mysql_update_log.write(thd, thd->query, thd->query_length);
if (mysql_bin_log.is_open())
{
Query_log_event qinfo(thd, thd->query, thd->query_length,
- using_transactions);
- if (mysql_bin_log.write(&qinfo) && using_transactions)
+ log_delayed);
+ if (mysql_bin_log.write(&qinfo) && transactional_table)
error=1;
}
- if (!using_transactions)
+ if (!log_delayed)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
}
- if (using_transactions)
+ if (transactional_table)
error=ha_autocommit_or_rollback(thd,error);
if (info.copied || info.deleted)
{
@@ -1197,7 +1199,7 @@ bool delayed_insert::handle_inserts(void)
mysql_update_log.write(&thd,row->query, row->query_length);
if (using_bin_log)
{
- Query_log_event qinfo(&thd, row->query, row->query_length);
+ Query_log_event qinfo(&thd, row->query, row->query_length,0);
mysql_bin_log.write(&qinfo);
}
}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 16ef7e750cd..54e72fafdd5 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -176,7 +176,7 @@ typedef struct st_lex
enum enum_var_type option_type;
uint grant,grant_tot_col,which_columns, union_option;
thr_lock_type lock_option;
- bool drop_primary,drop_if_exists,local_file, olap;
+ bool drop_primary, drop_if_exists, drop_temporary, local_file, olap;
bool in_comment,ignore_space,verbose,simple_alter;
uint slave_thd_opt;
} LEX;
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 8881c79eba4..cfb12b8a5bf 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -90,7 +90,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
bool is_fifo=0;
LOAD_FILE_INFO lf_info;
char * db = table_list->db ? table_list->db : thd->db;
- bool using_transactions;
+ bool transactional_table, log_delayed;
DBUG_ENTER("mysql_load");
#ifdef EMBEDDED_LIBRARY
@@ -105,6 +105,9 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
}
if (!(table = open_ltable(thd,table_list,lock_type)))
DBUG_RETURN(-1);
+ transactional_table= table->file->has_transactions();
+ log_delayed= (transactional_table || table->tmp_table);
+
if (!fields.elements)
{
Field **field;
@@ -224,6 +227,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
lf_info.handle_dup = handle_duplicates;
lf_info.wrote_create_file = 0;
lf_info.last_pos_in_file = HA_POS_ERROR;
+ lf_info.log_delayed= log_delayed;
read_info.set_io_cache_arg((void*) &lf_info);
}
restore_record(table,2);
@@ -275,16 +279,16 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
free_blobs(table); /* if pack_blob was used */
table->copy_blobs=0;
thd->count_cuted_fields=0; /* Don`t calc cuted fields */
- using_transactions = table->file->has_transactions();
+
if (error)
{
- if (using_transactions)
+ if (transactional_table)
ha_autocommit_or_rollback(thd,error);
if (!opt_old_rpl_compat && mysql_bin_log.is_open())
{
if (lf_info.wrote_create_file)
{
- Delete_file_log_event d(thd);
+ Delete_file_log_event d(thd, log_delayed);
mysql_bin_log.write(&d);
}
}
@@ -297,27 +301,30 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
if (!thd->slave_thread)
mysql_update_log.write(thd,thd->query,thd->query_length);
- if (!using_transactions)
+ if (!log_delayed)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
if (mysql_bin_log.is_open())
{
- if (opt_old_rpl_compat && !read_file_from_client)
+ if (opt_old_rpl_compat)
{
- Load_log_event qinfo(thd, ex, db, table->table_name, fields,
- handle_duplicates);
- mysql_bin_log.write(&qinfo);
+ if (!read_file_from_client)
+ {
+ Load_log_event qinfo(thd, ex, db, table->table_name, fields,
+ handle_duplicates, log_delayed);
+ mysql_bin_log.write(&qinfo);
+ }
}
- if (!opt_old_rpl_compat)
+ else
{
read_info.end_io_cache(); // make sure last block gets logged
if (lf_info.wrote_create_file)
{
- Execute_load_log_event e(thd);
+ Execute_load_log_event e(thd, log_delayed);
mysql_bin_log.write(&e);
}
}
}
- if (using_transactions)
+ if (transactional_table)
error=ha_autocommit_or_rollback(thd,error);
DBUG_RETURN(error);
}
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 7416506fd02..232f255da35 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2341,7 +2341,7 @@ mysql_execute_command(void)
mysql_update_log.write(thd, thd->query, thd->query_length);
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query, thd->query_length);
+ Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
mysql_bin_log.write(&qinfo);
}
}
@@ -2361,7 +2361,7 @@ mysql_execute_command(void)
mysql_update_log.write(thd, thd->query, thd->query_length);
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query, thd->query_length);
+ Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
mysql_bin_log.write(&qinfo);
}
if (mqh_used && lex->sql_command == SQLCOM_GRANT)
@@ -2723,8 +2723,8 @@ mysql_init_query(THD *thd)
thd->lex.select->olap= UNSPECIFIED_OLAP_TYPE;
thd->fatal_error=0; // Safety
thd->last_insert_id_used=thd->query_start_used=thd->insert_id_used=0;
- thd->sent_row_count=thd->examined_row_count=0;
thd->rand_used=0;
+ thd->sent_row_count=thd->examined_row_count=0;
thd->safe_to_cache_query=1;
DBUG_VOID_RETURN;
}
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc
index 049690eb318..3eddd2646d5 100644
--- a/sql/sql_rename.cc
+++ b/sql/sql_rename.cc
@@ -94,7 +94,7 @@ end:
mysql_update_log.write(thd,thd->query,thd->query_length);
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query, thd->query_length);
+ Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
mysql_bin_log.write(&qinfo);
}
send_ok(&thd->net);
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 47b258d9ed2..003bb290b41 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -1132,7 +1132,8 @@ 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, buffer, block_len,
+ lf_info->log_delayed);
mysql_bin_log.write(&a);
}
else
@@ -1140,7 +1141,7 @@ int log_loaded_block(IO_CACHE* file)
Create_file_log_event c(lf_info->thd,lf_info->ex,lf_info->db,
lf_info->table_name, *lf_info->fields,
lf_info->handle_dup, buffer,
- block_len);
+ block_len, lf_info->log_delayed);
mysql_bin_log.write(&c);
lf_info->wrote_create_file = 1;
DBUG_SYNC_POINT("debug_lock.created_file_event",10);
diff --git a/sql/sql_repl.h b/sql/sql_repl.h
index 197fd03ec7c..15435382b08 100644
--- a/sql/sql_repl.h
+++ b/sql/sql_repl.h
@@ -43,13 +43,13 @@ int check_binlog_magic(IO_CACHE* log, const char** errmsg);
typedef struct st_load_file_info
{
THD* thd;
+ my_off_t last_pos_in_file;
sql_exchange* ex;
List <Item> *fields;
enum enum_duplicates handle_dup;
char* db;
char* table_name;
- bool wrote_create_file;
- my_off_t last_pos_in_file;
+ bool wrote_create_file, log_delayed;
} LOAD_FILE_INFO;
int log_loaded_block(IO_CACHE* file);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 865b30cdb39..36aa31e7553 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -110,6 +110,17 @@ int mysql_rm_table_part2_with_lock(THD *thd,
return error;
}
+/*
+ TODO:
+ When logging to the binary log, we should log
+ tmp_tables and transactional tables as separate statements if we
+ are in a transaction; This is needed to get these tables into the
+ cached binary log that is only written on COMMIT.
+
+ The current code only writes DROP statements that only uses temporary
+ tables to the cache binary log. This should be ok on most cases, but
+ not all.
+*/
int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
bool dont_log_query)
@@ -119,7 +130,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
String wrong_tables;
db_type table_type;
int error;
- bool some_tables_deleted=0;
+ bool some_tables_deleted=0, tmp_table_deleted=0;
DBUG_ENTER("mysql_rm_table_part2");
for (table=tables ; table ; table=table->next)
@@ -127,7 +138,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
char *db=table->db ? table->db : thd->db;
if (!close_temporary_table(thd, db, table->real_name))
{
- some_tables_deleted=1; // Log query
+ tmp_table_deleted=1;
continue; // removed temporary table
}
@@ -143,8 +154,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
DBUG_RETURN(-1);
/* remove form file and isam files */
- (void) sprintf(path,"%s/%s/%s%s",mysql_data_home,db,table->real_name,
- reg_ext);
+ strxmov(path, mysql_data_home, "/", db, "/", table->real_name, reg_ext,
+ NullS);
(void) unpack_filename(path,path);
error=0;
@@ -177,7 +188,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
wrong_tables.append(String(table->real_name));
}
}
- if (some_tables_deleted)
+ if (some_tables_deleted || tmp_table_deleted)
{
query_cache_invalidate3(thd, tables, 0);
if (!dont_log_query)
@@ -185,7 +196,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
mysql_update_log.write(thd, thd->query,thd->query_length);
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query, thd->query_length);
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ tmp_table_deleted && !some_tables_deleted);
mysql_bin_log.write(&qinfo);
}
}
@@ -272,7 +284,8 @@ static int sort_keys(KEY *a, KEY *b)
create_info Create information (like MAX_ROWS)
fields List of fields to create
keys List of keys to create
- tmp_table Set to 1 if this is a temporary table
+ tmp_table Set to 1 if this is an internal temporary table
+ (From ALTER TABLE)
no_log Don't log the query to binary log.
DESCRIPTION
@@ -690,16 +703,6 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
/* my_error(ER_CANT_CREATE_TABLE,MYF(0),table_name,my_errno); */
goto end;
}
- if (!tmp_table && !no_log)
- {
- // Must be written before unlock
- mysql_update_log.write(thd,thd->query, thd->query_length);
- if (mysql_bin_log.is_open())
- {
- Query_log_event qinfo(thd, thd->query, thd->query_length);
- mysql_bin_log.write(&qinfo);
- }
- }
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
{
/* Open table and put in temporary table list */
@@ -709,6 +712,18 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
goto end;
}
}
+ if (!tmp_table && !no_log)
+ {
+ // Must be written before unlock
+ mysql_update_log.write(thd,thd->query, thd->query_length);
+ if (mysql_bin_log.is_open())
+ {
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ test(create_info->options &
+ HA_LEX_CREATE_TMP_TABLE));
+ mysql_bin_log.write(&qinfo);
+ }
+ }
error=0;
end:
VOID(pthread_mutex_unlock(&LOCK_open));
@@ -1408,7 +1423,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
mysql_update_log.write(thd, thd->query, thd->query_length);
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query, thd->query_length);
+ Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
mysql_bin_log.write(&qinfo);
}
send_ok(&thd->net);
@@ -1773,7 +1788,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
mysql_update_log.write(thd, thd->query,thd->query_length);
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query, thd->query_length);
+ Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
mysql_bin_log.write(&qinfo);
}
goto end_temporary;
@@ -1902,7 +1917,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
mysql_update_log.write(thd, thd->query,thd->query_length);
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query, thd->query_length);
+ Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
mysql_bin_log.write(&qinfo);
}
VOID(pthread_cond_broadcast(&COND_refresh));
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 92decc63b6b..c1f02b5a30e 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -54,7 +54,7 @@ int mysql_update(THD *thd,
thr_lock_type lock_type)
{
bool using_limit=limit != HA_POS_ERROR;
- bool used_key_is_modified, using_transactions;
+ bool used_key_is_modified, transactional_table, log_delayed;
int error=0;
uint save_time_stamp, used_index, want_privilege;
ulong query_id=thd->query_id, timestamp_query_id;
@@ -301,21 +301,22 @@ int mysql_update(THD *thd,
thd->proc_info="end";
VOID(table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY));
table->time_stamp=save_time_stamp; // Restore auto timestamp pointer
- using_transactions=table->file->has_transactions();
- if (updated && (error <= 0 || !using_transactions))
+ transactional_table= table->file->has_transactions();
+ log_delayed= (transactional_table || table->tmp_table);
+ if (updated && (error <= 0 || !transactional_table))
{
mysql_update_log.write(thd,thd->query,thd->query_length);
if (mysql_bin_log.is_open())
{
Query_log_event qinfo(thd, thd->query, thd->query_length,
- using_transactions);
- if (mysql_bin_log.write(&qinfo) && using_transactions)
- error=1;
+ log_delayed);
+ if (mysql_bin_log.write(&qinfo) && transactional_table)
+ error=1; // Rollback update
}
- if (!using_transactions)
+ if (!log_delayed)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
}
- if (using_transactions && ha_autocommit_or_rollback(thd, error >= 0))
+ if (transactional_table && ha_autocommit_or_rollback(thd, error >= 0))
error=1;
if (updated)
{
@@ -790,7 +791,7 @@ bool multi_update::send_eof()
if (updated || not_trans_safe)
{
mysql_update_log.write(thd,thd->query,thd->query_length);
- Query_log_event qinfo(thd, thd->query, thd->query_length);
+ Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
/*
mysql_bin_log is not open if binlogging or replication
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index b4d1fa802bb..911fc12d9c4 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -513,6 +513,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
type int_type real_type order_dir opt_field_spec lock_option
udf_type if_exists opt_local opt_table_options table_options
table_option opt_if_not_exists opt_var_type opt_var_ident_type
+ opt_temporary
%type <ulong_num>
ULONG_NUM raid_types merge_insert_types
@@ -2383,11 +2384,12 @@ do: DO_SYM
*/
drop:
- DROP TABLE_SYM if_exists table_list opt_restrict
+ DROP opt_temporary TABLE_SYM if_exists table_list opt_restrict
{
LEX *lex=Lex;
lex->sql_command = SQLCOM_DROP_TABLE;
- lex->drop_if_exists = $3;
+ lex->drop_temporary= $2;
+ lex->drop_if_exists= $4;
}
| DROP INDEX ident ON table_ident {}
{
@@ -2424,8 +2426,13 @@ table_name:
if_exists:
/* empty */ { $$=0; }
- | IF EXISTS { $$= 1; };
+ | IF EXISTS { $$= 1; }
+ ;
+opt_temporary:
+ /* empty */ { $$= 0; }
+ | TEMPORARY { $$= 1; }
+ ;
/*
** Insert : add new data to table
*/
diff --git a/sql/table.cc b/sql/table.cc
index d3b719c553d..b68edac5fc2 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -47,19 +47,19 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
int j,error;
uint rec_buff_length,n_length,int_length,records,key_parts,keys,
interval_count,interval_parts,read_length,db_create_options;
- uint key_info_length;
+ uint key_info_length, com_length;
ulong pos;
- char index_file[FN_REFLEN], *names,*keynames;
+ char index_file[FN_REFLEN], *names, *keynames;
uchar head[288],*disk_buff,new_field_pack_flag;
my_string record;
const char **int_array;
- bool new_frm_ver,use_hash, null_field_first;
+ bool use_hash, null_field_first;
File file;
Field **field_ptr,*reg_field;
KEY *keyinfo;
KEY_PART_INFO *key_part;
uchar *null_pos;
- uint null_bit;
+ uint null_bit, new_frm_ver, field_pack_length;
SQL_CRYPT *crypted=0;
DBUG_ENTER("openfrm");
DBUG_PRINT("enter",("name: '%s' form: %lx",name,outparam));
@@ -95,14 +95,15 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
if (my_read(file,(byte*) head,64,MYF(MY_NABP))) goto err_not_open;
if (head[0] != (uchar) 254 || head[1] != 1 ||
- (head[2] != FRM_VER && head[2] != FRM_VER+1))
- goto err_not_open; /* purecov: inspected */
+ (head[2] != FRM_VER && head[2] > FRM_VER+2))
+ goto err_not_open; /* purecov: inspected */
new_field_pack_flag=head[27];
- new_frm_ver= (head[2] == FRM_VER+1);
+ new_frm_ver= (head[2] - FRM_VER);
+ field_pack_length= new_frm_ver < 2 ? 11 : 15;
error=3;
if (!(pos=get_form_pos(file,head,(TYPELIB*) 0)))
- goto err_not_open; /* purecov: inspected */
+ goto err_not_open; /* purecov: inspected */
*fn_ext(index_file)='\0'; // Remove .frm extension
outparam->db_type=ha_checktype((enum db_type) (uint) *(head+3));
@@ -153,9 +154,23 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
for (i=0 ; i < keys ; i++, keyinfo++)
{
- keyinfo->flags= ((uint) strpos[0]) ^ HA_NOSAME;
- keyinfo->key_length= (uint) uint2korr(strpos+1);
- keyinfo->key_parts= (uint) strpos[3]; strpos+=4;
+ if (new_frm_ver == 2)
+ {
+ keyinfo->flags= (uint) uint2korr(strpos) ^ HA_NOSAME;
+ keyinfo->key_length= (uint) uint2korr(strpos+2);
+ keyinfo->key_parts= (uint) strpos[4];
+ keyinfo->algorithm= (enum ha_key_alg) strpos[5];
+ strpos+=8;
+ }
+ else
+ {
+ keyinfo->flags= ((uint) strpos[0]) ^ HA_NOSAME;
+ keyinfo->key_length= (uint) uint2korr(strpos+1);
+ keyinfo->key_parts= (uint) strpos[3];
+ keyinfo->algorithm= HA_KEY_ALG_UNDEF;
+ strpos+=4;
+ }
+
keyinfo->key_part= key_part;
keyinfo->rec_per_key= rec_per_key;
for (j=keyinfo->key_parts ; j-- ; key_part++)
@@ -165,7 +180,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
key_part->offset= (uint) uint2korr(strpos+2)-1;
key_part->key_type= (uint) uint2korr(strpos+5);
// key_part->field= (Field*) 0; // Will be fixed later
- if (new_frm_ver)
+ if (new_frm_ver >= 1)
{
key_part->key_part_flag= *(strpos+4);
key_part->length= (uint) uint2korr(strpos+7);
@@ -191,14 +206,6 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
}
keynames=(char*) key_part;
strpos+= (strmov(keynames, (char *) strpos) - keynames)+1;
- /* Test if new 4.0 format */
- if ((uint) (strpos - disk_buff) < key_info_length)
- {
- /* Read key types */
- keyinfo=outparam->key_info;
- for (i=0 ; i < keys ; i++, keyinfo++)
- keyinfo->algorithm= (enum ha_key_alg) *(strpos++);
- }
outparam->reclength = uint2korr((head+16));
if (*(head+26) == 1)
@@ -267,6 +274,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
interval_parts=uint2korr(head+272);
int_length=uint2korr(head+274);
outparam->null_fields=uint2korr(head+282);
+ com_length=uint2korr(head+284);
outparam->comment=strdup_root(&outparam->mem_root,
(char*) head+47);
@@ -278,12 +286,12 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
interval_count*sizeof(TYPELIB)+
(outparam->fields+interval_parts+
keys+3)*sizeof(my_string)+
- (n_length+int_length)))))
+ (n_length+int_length+com_length)))))
goto err_not_open; /* purecov: inspected */
outparam->field=field_ptr;
- read_length=((uint) (outparam->fields*11)+pos+
- (uint) (n_length+int_length));
+ read_length=(uint) (outparam->fields * field_pack_length +
+ pos+ (uint) (n_length+int_length+com_length));
if (read_string(file,(gptr*) &disk_buff,read_length))
goto err_not_open; /* purecov: inspected */
if (crypted)
@@ -299,7 +307,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
names= (char*) (int_array+outparam->fields+interval_parts+keys+3);
if (!interval_count)
outparam->intervals=0; // For better debugging
- memcpy((char*) names, strpos+(outparam->fields*11),
+ memcpy((char*) names, strpos+(outparam->fields*field_pack_length),
(uint) (n_length+int_length));
fix_type_pointers(&int_array,&outparam->fieldnames,1,&names);
@@ -332,22 +340,40 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
(hash_get_key) get_field_name,0,
HASH_CASE_INSENSITIVE);
- for (i=0 ; i < outparam->fields; i++, strpos+= 11, field_ptr++)
+ for (i=0 ; i < outparam->fields; i++, strpos+=field_pack_length, field_ptr++)
{
uint pack_flag= uint2korr(strpos+6);
uint interval_nr= (uint) strpos[10];
+ enum_field_types field_type;
+
+ if (new_frm_ver == 2)
+ {
+ /* new frm file in 4.1 */
+ field_type=(enum_field_types) (uint) strpos[11];
+ }
+ else
+ {
+ /* old frm file */
+ field_type= (enum_field_types) f_packtype(pack_flag);
+ }
*field_ptr=reg_field=
make_field(record+uint2korr(strpos+4),
(uint32) strpos[3], // field_length
null_pos,null_bit,
pack_flag,
+ field_type,
(Field::utype) MTYP_TYPENR((uint) strpos[8]),
(interval_nr ?
outparam->intervals+interval_nr-1 :
(TYPELIB*) 0),
outparam->fieldnames.type_names[i],
outparam);
+ if (!*field_ptr) // Field in 4.1
+ {
+ error= 4;
+ goto err_not_open; /* purecov: inspected */
+ }
if (!(reg_field->flags & NOT_NULL_FLAG))
{
if ((null_bit<<=1) == 256)
diff --git a/sql/unireg.cc b/sql/unireg.cc
index 7d0201f75ae..cc8440da1e4 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -557,6 +557,7 @@ static bool make_empty_rec(File file,enum db_type table_type,
null_pos+null_count/8,
1 << (null_count & 7),
field->pack_flag,
+ field->sql_type,
field->unireg_check,
field->interval,
field->field_name,