Commit 72413e7f authored by unknown's avatar unknown

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
parent 23f4865b
......@@ -72,7 +72,7 @@ show binlog events in 'slave-bin.001' from 4;
Log_name Pos Event_type Server_id Orig_log_pos Info
slave-bin.001 4 Start 2 4 Server ver: VERSION, Binlog ver: 3
slave-bin.001 79 Query 1 79 use test; create table t1(n int not null auto_increment primary key)
slave-bin.001 172 Intvar 1 200 INSERT_ID=1
slave-bin.001 172 Intvar 1 172 INSERT_ID=1
slave-bin.001 200 Query 1 200 use test; insert into t1 values (NULL)
slave-bin.001 263 Query 1 263 use test; drop table t1
slave-bin.001 311 Query 1 311 use test; create table t1 (word char(20) not null)
......
......@@ -170,6 +170,10 @@ convert_character_set cp1251_koi8
select @@timestamp>0;
@@timestamp>0
1
set @@rand_seed1=10000000,@@rand_seed2=1000000;
select ROUND(RAND(),5);
ROUND(RAND(),5)
0.02887
set big_tables=OFFF;
Variable 'big_tables' can't be set to the value of 'OFFF'
set big_tables="OFFF";
......
......@@ -93,6 +93,10 @@ set global character set default, session character set default;
show variables like "convert_character_set";
select @@timestamp>0;
set @@rand_seed1=10000000,@@rand_seed2=1000000;
select ROUND(RAND(),5);
# The following should give errors
--error 1231
......
......@@ -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
}
......
......@@ -1050,7 +1050,9 @@ class Copy_field :public Sql_alloc {
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)
......@@ -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);
}
......
......@@ -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 @@ bool MYSQL_LOG::write(Log_event* event_info)
}
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 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache)
sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
}
VOID(pthread_mutex_unlock(&LOCK_log));
return 1;
DBUG_RETURN(1);
}
......
......@@ -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;
......
......@@ -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 @@ class Log_event
{ 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 @@ class Query_log_event: public Log_event
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 @@ class Load_log_event: public Log_event
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 @@ class Load_log_event: public Log_event
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 @@ class Start_log_event: public Log_event
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 @@ class Intvar_log_event: public Log_event
#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 @@ class Rotate_log_event: public Log_event
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 @@ class Create_file_log_event: public Load_log_event
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 @@ class Append_block_log_event: public Log_event
#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 @@ class Delete_file_log_event: public Log_event
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 @@ class Execute_load_log_event: public Log_event
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
......
......@@ -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
*/
......
......@@ -332,6 +332,23 @@ class sys_var_slave_skip_counter :public sys_var
};
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:
......
......@@ -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)))
{
......
......@@ -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);
}
......
......@@ -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);
}
......
......@@ -419,6 +419,7 @@ class THD :public ilink {
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 @@ class THD :public ilink {
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 @@ class Unique :public Sql_alloc
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);
......
......@@ -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)
......
......@@ -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 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
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
......
......@@ -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);
}
}
......
......@@ -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;
......
......@@ -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);
}
......
......@@ -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;
}
......
......@@ -94,7 +94,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list)
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);
......
......@@ -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);
......
......@@ -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);
......@@ -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));
......
......@@ -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
......
......@@ -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
*/
......
......@@ -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)
......
......@@ -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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment