diff options
author | unknown <monty@hundin.mysql.fi> | 2002-11-07 04:02:37 +0200 |
---|---|---|
committer | unknown <monty@hundin.mysql.fi> | 2002-11-07 04:02:37 +0200 |
commit | 72413e7f81cb87327d8bb2094a43d66578cd1632 (patch) | |
tree | e27391c030124332f69b62384e7e47e39f8e1818 /sql | |
parent | 23f4865b163293006bbedbc2b69bc55ba1081baa (diff) | |
download | mariadb-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.cc | 11 | ||||
-rw-r--r-- | sql/field.h | 6 | ||||
-rw-r--r-- | sql/item_func.cc | 2 | ||||
-rw-r--r-- | sql/log.cc | 18 | ||||
-rw-r--r-- | sql/log_event.cc | 100 | ||||
-rw-r--r-- | sql/log_event.h | 50 | ||||
-rw-r--r-- | sql/set_var.cc | 17 | ||||
-rw-r--r-- | sql/set_var.h | 17 | ||||
-rw-r--r-- | sql/slave.cc | 4 | ||||
-rw-r--r-- | sql/sql_acl.cc | 2 | ||||
-rw-r--r-- | sql/sql_base.cc | 28 | ||||
-rw-r--r-- | sql/sql_class.h | 4 | ||||
-rw-r--r-- | sql/sql_db.cc | 4 | ||||
-rw-r--r-- | sql/sql_delete.cc | 57 | ||||
-rw-r--r-- | sql/sql_insert.cc | 18 | ||||
-rw-r--r-- | sql/sql_lex.h | 2 | ||||
-rw-r--r-- | sql/sql_load.cc | 31 | ||||
-rw-r--r-- | sql/sql_parse.cc | 6 | ||||
-rw-r--r-- | sql/sql_rename.cc | 2 | ||||
-rw-r--r-- | sql/sql_repl.cc | 5 | ||||
-rw-r--r-- | sql/sql_repl.h | 4 | ||||
-rw-r--r-- | sql/sql_table.cc | 55 | ||||
-rw-r--r-- | sql/sql_update.cc | 19 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 13 | ||||
-rw-r--r-- | sql/table.cc | 76 | ||||
-rw-r--r-- | sql/unireg.cc | 1 |
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, |