Below is the list of changes that have just been committed into a local
5.1 repository of cmiller. When cmiller does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2006-10-17 11:23:07-04:00, cmiller@stripped +51 -0
Merge bk-internal.mysql.com:/home/bk/mysql-5.1
into zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.1-maint
MERGE: 1.2273.97.51
BitKeeper/etc/collapsed@stripped, 2006-10-17 11:22:52-04:00, cmiller@stripped +0
-0
auto-union
MERGE: 1.8.3.1
BitKeeper/etc/ignore@stripped, 2006-10-17 11:22:52-04:00, cmiller@stripped +0 -0
auto-union
MERGE: 1.259.1.1
Makefile.am@stripped, 2006-10-17 11:22:58-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.98.1.1
client/mysql.cc@stripped, 2006-10-17 11:22:58-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.234.2.1
client/mysqldump.c@stripped, 2006-10-17 11:22:58-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.250.1.3
client/mysqltest.c@stripped, 2006-10-17 11:22:58-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.228.1.1
configure.in@stripped, 2006-10-17 11:22:58-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.385.1.2
include/m_ctype.h@stripped, 2006-10-17 11:22:58-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.126.1.1
include/my_global.h@stripped, 2006-10-17 11:22:58-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.146.1.1
mysql-test/lib/mtr_process.pl@stripped, 2006-10-17 11:22:58-04:00,
cmiller@stripped +0 -0
Auto merged
MERGE: 1.52.2.1
mysql-test/mysql-test-run.pl@stripped, 2006-10-17 11:22:58-04:00,
cmiller@stripped +0 -0
Auto merged
MERGE: 1.183.4.1
mysql-test/r/binlog_row_mix_innodb_myisam.result@stripped, 2006-10-17 11:22:58-04:00,
cmiller@stripped +0 -0
Auto merged
MERGE: 1.12.1.1
mysql-test/r/csv.result@stripped, 2006-10-17 11:22:59-04:00, cmiller@stripped +0
-0
Auto merged
MERGE: 1.10.1.4
mysql-test/r/ctype_utf8.result@stripped, 2006-10-17 11:22:59-04:00,
cmiller@stripped +0 -0
Auto merged
MERGE: 1.98.1.10
mysql-test/r/func_time.result@stripped, 2006-10-17 11:22:59-04:00,
cmiller@stripped +0 -0
Auto merged
MERGE: 1.80.1.2
mysql-test/r/mysql.result@stripped, 2006-10-17 11:22:59-04:00, cmiller@stripped +0
-0
Auto merged
MERGE: 1.17.1.1
mysql-test/r/partition.result@stripped, 2006-10-17 11:22:59-04:00,
cmiller@stripped +0 -0
Auto merged
MERGE: 1.49.9.3
mysql-test/r/ps.result@stripped, 2006-10-17 11:22:59-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.77.1.1
mysql-test/r/strict.result@stripped, 2006-10-17 11:22:59-04:00, cmiller@stripped
+0 -0
Auto merged
MERGE: 1.38.1.1
mysql-test/r/trigger.result@stripped, 2006-10-17 11:22:59-04:00, cmiller@stripped
+0 -0
Auto merged
MERGE: 1.49.1.1
mysql-test/r/warnings.result@stripped, 2006-10-17 11:22:59-04:00, cmiller@stripped
+0 -0
Auto merged
MERGE: 1.51.1.1
mysql-test/t/csv.test@stripped, 2006-10-17 11:22:59-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.12.1.5
mysql-test/t/ctype_utf8.test@stripped, 2006-10-17 11:22:59-04:00, cmiller@stripped
+0 -0
Auto merged
MERGE: 1.89.1.10
mysql-test/t/func_time.test@stripped, 2006-10-17 11:22:59-04:00, cmiller@stripped
+0 -0
Auto merged
MERGE: 1.65.1.1
mysql-test/t/mysql.test@stripped, 2006-10-17 11:22:59-04:00, cmiller@stripped +0
-0
Auto merged
MERGE: 1.20.2.1
mysql-test/t/partition.test@stripped, 2006-10-17 11:22:59-04:00, cmiller@stripped
+0 -0
Auto merged
MERGE: 1.44.6.3
mysql-test/t/ps.test@stripped, 2006-10-17 11:22:59-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.74.2.1
mysql-test/t/trigger.test@stripped, 2006-10-17 11:22:59-04:00, cmiller@stripped +0
-0
Auto merged
MERGE: 1.53.1.1
sql/field.cc@stripped, 2006-10-17 11:22:59-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.345.1.1
sql/filesort.cc@stripped, 2006-10-17 11:23:00-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.113.1.1
sql/item.cc@stripped, 2006-10-17 11:23:00-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.214.1.1
sql/item_func.cc@stripped, 2006-10-17 11:23:00-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.320.1.1
sql/item_func.h@stripped, 2006-10-17 11:23:00-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.140.1.17
sql/item_timefunc.cc@stripped, 2006-10-17 11:23:00-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.136.1.2
sql/item_timefunc.h@stripped, 2006-10-17 11:23:00-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.72.1.1
sql/log.cc@stripped, 2006-10-17 11:23:00-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.237.1.2
sql/mysql_priv.h@stripped, 2006-10-17 11:23:00-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.448.1.1
sql/opt_range.cc@stripped, 2006-10-17 11:23:00-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.239.1.1
sql/opt_range.h@stripped, 2006-10-17 11:23:00-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.65.1.1
sql/set_var.cc@stripped, 2006-10-17 11:23:01-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.192.2.1
sql/sql_acl.cc@stripped, 2006-10-17 11:23:01-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.218.1.2
sql/sql_class.h@stripped, 2006-10-17 11:23:01-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.320.1.2
sql/sql_insert.cc@stripped, 2006-10-17 11:23:01-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.230.1.2
sql/sql_lex.h@stripped, 2006-10-17 11:23:01-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.244.1.1
sql/sql_select.cc@stripped, 2006-10-17 11:23:01-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.452.1.1
sql/sql_show.cc@stripped, 2006-10-17 11:23:02-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.366.1.1
sql/sql_table.cc@stripped, 2006-10-17 11:23:02-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.359.1.14
sql/sql_update.cc@stripped, 2006-10-17 11:23:02-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.208.1.2
sql/sql_view.cc@stripped, 2006-10-17 11:23:02-04:00, cmiller@stripped +0 -1
Auto merged
MERGE: 1.101.4.7
sql/sql_yacc.yy@stripped, 2006-10-17 11:23:02-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.507.1.1
vio/viosocket.c@stripped, 2006-10-17 11:23:02-04:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.44.1.1
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: cmiller
# Host: zippy.cornsilk.net
# Root: /home/cmiller/work/mysql/mysql-5.1-maint/RESYNC
--- 1.253/client/mysqldump.c 2006-10-17 11:23:18 -04:00
+++ 1.254/client/mysqldump.c 2006-10-17 11:23:18 -04:00
@@ -3405,7 +3405,7 @@ static int do_reset_master(MYSQL *mysql_
}
-static int start_transaction(MYSQL *mysql_con, my_bool consistent_read_now)
+static int start_transaction(MYSQL *mysql_con)
{
/*
We use BEGIN for old servers. --single-transaction --master-data will fail
@@ -3420,10 +3420,8 @@ static int start_transaction(MYSQL *mysq
"SET SESSION TRANSACTION ISOLATION "
"LEVEL REPEATABLE READ") ||
mysql_query_with_error_report(mysql_con, 0,
- consistent_read_now ?
"START TRANSACTION "
- "WITH CONSISTENT SNAPSHOT" :
- "BEGIN"));
+ "/*!40100 WITH CONSISTENT SNAPSHOT */"));
}
@@ -3913,7 +3911,7 @@ int main(int argc, char **argv)
if ((opt_lock_all_tables || opt_master_data) &&
do_flush_tables_read_lock(mysql))
goto err;
- if (opt_single_transaction && start_transaction(mysql, test(opt_master_data)))
+ if (opt_single_transaction && start_transaction(mysql))
goto err;
if (opt_delete_master_logs && do_reset_master(mysql))
goto err;
--- 1.386/configure.in 2006-10-17 11:23:19 -04:00
+++ 1.387/configure.in 2006-10-17 11:23:19 -04:00
@@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line!
# remember to also change ndb version below and update version.c in ndb
-AM_INIT_AUTOMAKE(mysql, 5.1.12-beta)
+AM_INIT_AUTOMAKE(mysql, 5.1.13-beta)
AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10
--- 1.137/sql/item_timefunc.cc 2006-10-17 11:23:19 -04:00
+++ 1.138/sql/item_timefunc.cc 2006-10-17 11:23:19 -04:00
@@ -96,6 +96,125 @@ static bool make_datetime(date_time_form
/*
+ Wrapper over make_datetime() with validation of the input TIME value
+
+ NOTE
+ see make_datetime() for more information
+
+ RETURN
+ 1 if there was an error during converion
+ 0 otherwise
+*/
+
+static bool make_datetime_with_warn(date_time_format_types format, TIME *ltime,
+ String *str)
+{
+ int warning= 0;
+ bool rc;
+
+ if (make_datetime(format, ltime, str))
+ return 1;
+ if (check_time_range(ltime, &warning))
+ return 1;
+ if (!warning)
+ return 0;
+
+ make_truncated_value_warning(current_thd, str->ptr(), str->length(),
+ MYSQL_TIMESTAMP_TIME, NullS);
+ return make_datetime(format, ltime, str);
+}
+
+
+/*
+ Wrapper over make_time() with validation of the input TIME value
+
+ NOTE
+ see make_time() for more info
+
+ RETURN
+ 1 if there was an error during conversion
+ 0 otherwise
+*/
+
+static bool make_time_with_warn(const DATE_TIME_FORMAT *format,
+ TIME *l_time, String *str)
+{
+ int warning= 0;
+ make_time(format, l_time, str);
+ if (check_time_range(l_time, &warning))
+ return 1;
+ if (warning)
+ {
+ make_truncated_value_warning(current_thd, str->ptr(), str->length(),
+ MYSQL_TIMESTAMP_TIME, NullS);
+ make_time(format, l_time, str);
+ }
+
+ return 0;
+}
+
+
+/*
+ Convert seconds to TIME value with overflow checking
+
+ SYNOPSIS:
+ sec_to_time()
+ seconds number of seconds
+ unsigned_flag 1, if 'seconds' is unsigned, 0, otherwise
+ ltime output TIME value
+
+ DESCRIPTION
+ If the 'seconds' argument is inside TIME data range, convert it to a
+ corresponding value.
+ Otherwise, truncate the resulting value to the nearest endpoint, and
+ produce a warning message.
+
+ RETURN
+ 1 if the value was truncated during conversion
+ 0 otherwise
+*/
+
+static bool sec_to_time(longlong seconds, bool unsigned_flag, TIME *ltime)
+{
+ uint sec;
+
+ bzero((char *)ltime, sizeof(*ltime));
+
+ if (seconds < 0)
+ {
+ if (unsigned_flag)
+ goto overflow;
+ ltime->neg= 1;
+ if (seconds < -3020399)
+ goto overflow;
+ seconds= -seconds;
+ }
+ else if (seconds > 3020399)
+ goto overflow;
+
+ sec= (uint) ((ulonglong) seconds % 3600);
+ ltime->hour= (uint) (seconds/3600);
+ ltime->minute= sec/60;
+ ltime->second= sec % 60;
+
+ return 0;
+
+overflow:
+ ltime->hour= TIME_MAX_HOUR;
+ ltime->minute= TIME_MAX_MINUTE;
+ ltime->second= TIME_MAX_SECOND;
+
+ char buf[22];
+ int len= (int)(longlong10_to_str(seconds, buf, unsigned_flag ? 10 : -10)
+ - buf);
+ make_truncated_value_warning(current_thd, buf, len, MYSQL_TIMESTAMP_TIME,
+ NullS);
+
+ return 1;
+}
+
+
+/*
Date formats corresponding to compound %r and %T conversion specifiers
Note: We should init at least first element of "positions" array
@@ -1546,8 +1665,6 @@ int Item_func_sysdate_local::save_in_fie
String *Item_func_sec_to_time::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
- longlong seconds=(longlong) args[0]->val_int();
- uint sec;
TIME ltime;
if ((null_value=args[0]->null_value) || str->alloc(19))
@@ -1556,18 +1673,7 @@ String *Item_func_sec_to_time::val_str(S
return (String*) 0;
}
- ltime.neg= 0;
- if (seconds < 0)
- {
- seconds= -seconds;
- ltime.neg= 1;
- }
-
- sec= (uint) ((ulonglong) seconds % 3600);
- ltime.day= 0;
- ltime.hour= (uint) (seconds/3600);
- ltime.minute= sec/60;
- ltime.second= sec % 60;
+ sec_to_time(args[0]->val_int(), args[0]->unsigned_flag, <ime);
make_time((DATE_TIME_FORMAT *) 0, <ime, str);
return str;
@@ -1577,16 +1683,15 @@ String *Item_func_sec_to_time::val_str(S
longlong Item_func_sec_to_time::val_int()
{
DBUG_ASSERT(fixed == 1);
- longlong seconds=args[0]->val_int();
- longlong sign=1;
+ TIME ltime;
+
if ((null_value=args[0]->null_value))
return 0;
- if (seconds < 0)
- {
- seconds= -seconds;
- sign= -1;
- }
- return sign*((seconds / 3600)*10000+((seconds/60) % 60)*100+ (seconds % 60));
+
+ sec_to_time(args[0]->val_int(), args[0]->unsigned_flag, <ime);
+
+ return (ltime.neg ? -1 : 1) *
+ ((ltime.hour)*10000 + ltime.minute*100 + ltime.second);
}
@@ -2030,11 +2135,15 @@ bool Item_date_add_interval::eq(const It
(date_sub_interval == other->date_sub_interval));
}
+/*
+ 'interval_names' reflects the order of the enumeration interval_type.
+ See item_timefunc.h
+ */
static const char *interval_names[]=
{
- "year", "quarter", "month", "day", "hour",
- "minute", "week", "second", "microsecond",
+ "year", "quarter", "month", "week", "day",
+ "hour", "minute", "second", "microsecond",
"year_month", "day_hour", "day_minute",
"day_second", "hour_minute", "hour_second",
"minute_second", "day_microsecond",
@@ -2572,6 +2681,8 @@ String *Item_func_add_time::val_str(Stri
if (l_time1.neg != l_time2.neg)
l_sign= -l_sign;
+ bzero((char *)&l_time3, sizeof(l_time3));
+
l_time3.neg= calc_time_diff(&l_time1, &l_time2, -l_sign,
&seconds, µseconds);
@@ -2600,7 +2711,7 @@ String *Item_func_add_time::val_str(Stri
}
l_time3.hour+= days*24;
- if (!make_datetime(l_time1.second_part || l_time2.second_part ?
+ if (!make_datetime_with_warn(l_time1.second_part || l_time2.second_part ?
TIME_MICROSECOND : TIME_ONLY,
&l_time3, str))
return str;
@@ -2657,6 +2768,8 @@ String *Item_func_timediff::val_str(Stri
if (l_time1.neg != l_time2.neg)
l_sign= -l_sign;
+ bzero((char *)&l_time3, sizeof(l_time3));
+
l_time3.neg= calc_time_diff(&l_time1, &l_time2, l_sign,
&seconds, µseconds);
@@ -2670,7 +2783,7 @@ String *Item_func_timediff::val_str(Stri
calc_time_from_sec(&l_time3, (long) seconds, microseconds);
- if (!make_datetime(l_time1.second_part || l_time2.second_part ?
+ if (!make_datetime_with_warn(l_time1.second_part || l_time2.second_part ?
TIME_MICROSECOND : TIME_ONLY,
&l_time3, str))
return str;
@@ -2690,29 +2803,58 @@ String *Item_func_maketime::val_str(Stri
{
DBUG_ASSERT(fixed == 1);
TIME ltime;
+ bool overflow= 0;
- long hour= (long) args[0]->val_int();
- long minute= (long) args[1]->val_int();
- long second= (long) args[2]->val_int();
+ longlong hour= args[0]->val_int();
+ longlong minute= args[1]->val_int();
+ longlong second= args[2]->val_int();
if ((null_value=(args[0]->null_value ||
args[1]->null_value ||
args[2]->null_value ||
- minute > 59 || minute < 0 ||
- second > 59 || second < 0 ||
+ minute < 0 || minute > 59 ||
+ second < 0 || second > 59 ||
str->alloc(19))))
return 0;
+ bzero((char *)<ime, sizeof(ltime));
ltime.neg= 0;
+
+ /* Check for integer overflows */
if (hour < 0)
{
+ if (args[0]->unsigned_flag)
+ overflow= 1;
+ else
ltime.neg= 1;
- hour= -hour;
}
- ltime.hour= (ulong) hour;
- ltime.minute= (ulong) minute;
- ltime.second= (ulong) second;
- make_time((DATE_TIME_FORMAT *) 0, <ime, str);
+ if (-hour > UINT_MAX || hour > UINT_MAX)
+ overflow= 1;
+
+ if (!overflow)
+ {
+ ltime.hour= (uint) ((hour < 0 ? -hour : hour));
+ ltime.minute= (uint) minute;
+ ltime.second= (uint) second;
+ }
+ else
+ {
+ ltime.hour= TIME_MAX_HOUR;
+ ltime.minute= TIME_MAX_MINUTE;
+ ltime.second= TIME_MAX_SECOND;
+ char buf[28];
+ char *ptr= longlong10_to_str(hour, buf, args[0]->unsigned_flag ? 10 : -10);
+ int len = (int)(ptr - buf) +
+ my_sprintf(ptr, (ptr, ":%02u:%02u", (uint)minute, (uint)second));
+ make_truncated_value_warning(current_thd, buf, len, MYSQL_TIMESTAMP_TIME,
+ NullS);
+ }
+
+ if (make_time_with_warn((DATE_TIME_FORMAT *) 0, <ime, str))
+ {
+ null_value= 1;
+ return 0;
+ }
return str;
}
@@ -3056,7 +3198,7 @@ bool Item_func_str_to_date::get_date(TIM
goto null_date;
null_value= 0;
- bzero((char*) ltime, sizeof(ltime));
+ bzero((char*) ltime, sizeof(*ltime));
date_time_format.format.str= (char*) format->ptr();
date_time_format.format.length= format->length();
if (extract_date_time(&date_time_format, val->ptr(), val->length(),
--- 1.238/sql/log.cc 2006-10-17 11:23:19 -04:00
+++ 1.239/sql/log.cc 2006-10-17 11:23:19 -04:00
@@ -32,10 +32,22 @@
#include <mysql/plugin.h>
+/*
+ Define placement versions of operator new and operator delete since
+ we cannot be sure that the <new> include exists.
+ */
+inline void *operator new(size_t, void *ptr) { return ptr; }
+inline void *operator new[](size_t, void *ptr) { return ptr; }
+inline void operator delete(void*, void*) { /* Do nothing */ }
+inline void operator delete[](void*, void*) { /* Do nothing */ }
+
/* max size of the log message */
#define MAX_LOG_BUFFER_SIZE 1024
#define MAX_USER_HOST_SIZE 512
#define MAX_TIME_SIZE 32
+#define MY_OFF_T_UNDEF (~(my_off_t)0UL)
+
+#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
LOGGER logger;
@@ -70,23 +82,92 @@ char *make_default_log_name(char *buff,c
}
/*
- This is a POD. Please keep it that way!
-
- Don't add constructors, destructors, or virtual functions.
+ Helper class to store binary log transaction data.
*/
-struct binlog_trx_data {
+class binlog_trx_data {
+public:
+ binlog_trx_data()
+#ifdef HAVE_ROW_BASED_REPLICATION
+ : m_pending(0), before_stmt_pos(MY_OFF_T_UNDEF)
+#endif
+ {
+ trans_log.end_of_file= max_binlog_cache_size;
+ }
+
+ ~binlog_trx_data()
+ {
+#ifdef HAVE_ROW_BASED_REPLICATION
+ DBUG_ASSERT(pending() == NULL);
+#endif
+ close_cached_file(&trans_log);
+ }
+
+ my_off_t position() const {
+ return my_b_tell(&trans_log);
+ }
+
bool empty() const
{
#ifdef HAVE_ROW_BASED_REPLICATION
- return pending == NULL && my_b_tell(&trans_log) == 0;
+ return pending() == NULL && my_b_tell(&trans_log) == 0;
#else
return my_b_tell(&trans_log) == 0;
#endif
}
- binlog_trx_data() {}
+
+ /*
+ Truncate the transaction cache to a certain position. This
+ includes deleting the pending event.
+ */
+ void truncate(my_off_t pos)
+ {
+#ifdef HAVE_ROW_BASED_REPLICATION
+ delete pending();
+ set_pending(0);
+#endif
+ reinit_io_cache(&trans_log, WRITE_CACHE, pos, 0, 0);
+ }
+
+ /*
+ Reset the entire contents of the transaction cache, emptying it
+ completely.
+ */
+ void reset() {
+ if (!empty())
+ truncate(0);
+#ifdef HAVE_ROW_BASED_REPLICATION
+ before_stmt_pos= MY_OFF_T_UNDEF;
+#endif
+ trans_log.end_of_file= max_binlog_cache_size;
+ }
+
+#ifdef HAVE_ROW_BASED_REPLICATION
+ Rows_log_event *pending() const
+ {
+ return m_pending;
+ }
+
+ void set_pending(Rows_log_event *const pending)
+ {
+ m_pending= pending;
+ }
+#endif
+
IO_CACHE trans_log; // The transaction cache
+
+private:
#ifdef HAVE_ROW_BASED_REPLICATION
- Rows_log_event *pending; // The pending binrows event
+ /*
+ Pending binrows event. This event is the event where the rows are
+ currently written.
+ */
+ Rows_log_event *m_pending;
+
+public:
+ /*
+ Binlog position before the start of the current statement.
+ */
+ my_off_t before_stmt_pos;
#endif
};
@@ -1150,6 +1231,69 @@ void Log_to_csv_event_handler::
/*
+ Save position of binary log transaction cache.
+
+ SYNPOSIS
+ binlog_trans_log_savepos()
+
+ thd The thread to take the binlog data from
+ pos Pointer to variable where the position will be stored
+
+ DESCRIPTION
+
+ Save the current position in the binary log transaction cache into
+ the variable pointed to by 'pos'
+ */
+
+static void
+binlog_trans_log_savepos(THD *thd, my_off_t *pos)
+{
+ DBUG_ENTER("binlog_trans_log_savepos");
+ DBUG_ASSERT(pos != NULL);
+ if (thd->ha_data[binlog_hton->slot] == NULL)
+ thd->binlog_setup_trx_data();
+ binlog_trx_data *const trx_data=
+ (binlog_trx_data*) thd->ha_data[binlog_hton->slot];
+ DBUG_ASSERT(mysql_bin_log.is_open());
+ *pos= trx_data->position();
+ DBUG_PRINT("return", ("*pos=%u", *pos));
+ DBUG_VOID_RETURN;
+}
+
+
+/*
+ Truncate the binary log transaction cache.
+
+ SYNPOSIS
+ binlog_trans_log_truncate()
+
+ thd The thread to take the binlog data from
+ pos Position to truncate to
+
+ DESCRIPTION
+
+ Truncate the binary log to the given position. Will not change
+ anything else.
+
+ */
+static void
+binlog_trans_log_truncate(THD *thd, my_off_t pos)
+{
+ DBUG_ENTER("binlog_trans_log_truncate");
+ DBUG_PRINT("enter", ("pos=%u", pos));
+
+ DBUG_ASSERT(thd->ha_data[binlog_hton->slot] != NULL);
+ /* Only true if binlog_trans_log_savepos() wasn't called before */
+ DBUG_ASSERT(pos != ~(my_off_t) 0);
+
+ binlog_trx_data *const trx_data=
+ (binlog_trx_data*) thd->ha_data[binlog_hton->slot];
+ trx_data->truncate(pos);
+ DBUG_VOID_RETURN;
+}
+
+
+/*
this function is mostly a placeholder.
conceptually, binlog initialization (now mostly done in MYSQL_BIN_LOG::open)
should be moved here.
@@ -1175,27 +1319,62 @@ static int binlog_close_connection(handl
{
binlog_trx_data *const trx_data=
(binlog_trx_data*) thd->ha_data[binlog_hton->slot];
- IO_CACHE *trans_log= &trx_data->trans_log;
DBUG_ASSERT(mysql_bin_log.is_open() && trx_data->empty());
- close_cached_file(trans_log);
thd->ha_data[binlog_hton->slot]= 0;
+ trx_data->~binlog_trx_data();
my_free((gptr)trx_data, MYF(0));
return 0;
}
+/*
+ End a transaction.
+
+ SYNOPSIS
+ binlog_end_trans()
+
+ thd The thread whose transaction should be ended
+ trx_data Pointer to the transaction data to use
+ end_ev The end event to use, or NULL
+ all True if the entire transaction should be ended, false if
+ only the statement transaction should be ended.
+
+ DESCRIPTION
+
+ End the currently open transaction. The transaction can be either
+ a real transaction (if 'all' is true) or a statement transaction
+ (if 'all' is false).
+
+ If 'end_ev' is NULL, the transaction is a rollback of only
+ transactional tables, so the transaction cache will be truncated
+ to either just before the last opened statement transaction (if
+ 'all' is false), or reset completely (if 'all' is true).
+ */
static int
binlog_end_trans(THD *thd, binlog_trx_data *trx_data,
- Log_event *end_ev)
+ Log_event *end_ev, bool all)
{
DBUG_ENTER("binlog_end_trans");
int error=0;
IO_CACHE *trans_log= &trx_data->trans_log;
+ DBUG_PRINT("enter", ("transaction: %s, end_ev=%p",
+ all ? "all" : "stmt", end_ev));
+ DBUG_PRINT("info", ("thd->options={ %s%s}",
+ FLAGSTR(thd->options, OPTION_NOT_AUTOCOMMIT),
+ FLAGSTR(thd->options, OPTION_BEGIN)));
-
- /* NULL denotes ROLLBACK with nothing to replicate */
+ /*
+ NULL denotes ROLLBACK with nothing to replicate: i.e., rollback of
+ only transactional tables. If the transaction contain changes to
+ any non-transactiona tables, we need write the transaction and log
+ a ROLLBACK last.
+ */
if (end_ev != NULL)
{
/*
+ Doing a commit or a rollback including non-transactional tables,
+ i.e., ending a transaction where we might write the transaction
+ cache to the binary log.
+
We can always end the statement when ending a transaction since
transactions are not allowed inside stored functions. If they
were, we would have to ensure that we're not ending a statement
@@ -1204,38 +1383,55 @@ binlog_end_trans(THD *thd, binlog_trx_da
#ifdef HAVE_ROW_BASED_REPLICATION
thd->binlog_flush_pending_rows_event(TRUE);
#endif
- error= mysql_bin_log.write(thd, trans_log, end_ev);
- }
-#ifdef HAVE_ROW_BASED_REPLICATION
- else
+ /*
+ We write the transaction cache to the binary log if either we're
+ committing the entire transaction, or if we are doing an
+ autocommit outside a transaction.
+ */
+ if (all || !(thd->options & (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT)))
{
+ error= mysql_bin_log.write(thd, &trx_data->trans_log, end_ev);
+ trx_data->reset();
#ifdef HAVE_ROW_BASED_REPLICATION
- thd->binlog_delete_pending_rows_event();
-#endif
- }
-
/*
- We need to step the table map version both after writing the
- entire transaction to the log file and after rolling back the
- transaction.
-
We need to step the table map version after writing the
- transaction cache to disk. In addition, we need to step the table
- map version on a rollback to ensure that a new table map event is
- generated instead of the one that was written to the thrown-away
- transaction cache.
+ transaction cache to disk.
*/
mysql_bin_log.update_table_map_version();
#endif
-
statistic_increment(binlog_cache_use, &LOCK_status);
if (trans_log->disk_writes != 0)
{
statistic_increment(binlog_cache_disk_use, &LOCK_status);
trans_log->disk_writes= 0;
}
- reinit_io_cache(trans_log, WRITE_CACHE, (my_off_t) 0, 0, 1); // cannot fail
- trans_log->end_of_file= max_binlog_cache_size;
+ }
+ }
+#ifdef HAVE_ROW_BASED_REPLICATION
+ else
+ {
+ /*
+ If rolling back an entire transaction or a single statement not
+ inside a transaction, we reset the transaction cache.
+
+ If rolling back a statement in a transaction, we truncate the
+ transaction cache to remove the statement.
+
+ */
+ if (all || !(thd->options & (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT)))
+ trx_data->reset();
+ else
+ trx_data->truncate(trx_data->before_stmt_pos); // ...statement
+
+ /*
+ We need to step the table map version on a rollback to ensure
+ that a new table map event is generated instead of the one that
+ was written to the thrown-away transaction cache.
+ */
+ mysql_bin_log.update_table_map_version();
+ }
+#endif
+
DBUG_RETURN(error);
}
@@ -1252,26 +1448,31 @@ static int binlog_prepare(handlerton *ht
static int binlog_commit(handlerton *hton, THD *thd, bool all)
{
+ int error= 0;
DBUG_ENTER("binlog_commit");
binlog_trx_data *const trx_data=
(binlog_trx_data*) thd->ha_data[binlog_hton->slot];
IO_CACHE *trans_log= &trx_data->trans_log;
- DBUG_ASSERT(mysql_bin_log.is_open() &&
- (all || !(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))));
+ DBUG_ASSERT(mysql_bin_log.is_open());
- if (trx_data->empty())
+ if (all && trx_data->empty())
{
// we're here because trans_log was flushed in MYSQL_BIN_LOG::log()
+ trx_data->reset();
DBUG_RETURN(0);
}
if (all)
{
Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, FALSE);
qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE)
- DBUG_RETURN(binlog_end_trans(thd, trx_data, &qev));
+ int error= binlog_end_trans(thd, trx_data, &qev, all);
+ DBUG_RETURN(error);
}
else
- DBUG_RETURN(binlog_end_trans(thd, trx_data, &invisible_commit));
+ {
+ int error= binlog_end_trans(thd, trx_data, &invisible_commit, all);
+ DBUG_RETURN(error);
+ }
}
static int binlog_rollback(handlerton *hton, THD *thd, bool all)
@@ -1281,13 +1482,13 @@ static int binlog_rollback(handlerton *h
binlog_trx_data *const trx_data=
(binlog_trx_data*) thd->ha_data[binlog_hton->slot];
IO_CACHE *trans_log= &trx_data->trans_log;
- /*
- First assert is guaranteed - see trans_register_ha() call below.
- The second must be true. If it is not, we're registering
- unnecessary, doing extra work. The cause should be found and eliminated
- */
- DBUG_ASSERT(all || !(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)));
- DBUG_ASSERT(mysql_bin_log.is_open() && !trx_data->empty());
+ DBUG_ASSERT(mysql_bin_log.is_open());
+
+ if (trx_data->empty()) {
+ trx_data->reset();
+ DBUG_RETURN(0);
+ }
+
/*
Update the binary log with a BEGIN/ROLLBACK block if we have
cached some queries and we updated some non-transactional
@@ -1299,10 +1500,10 @@ static int binlog_rollback(handlerton *h
{
Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, FALSE);
qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE)
- error= binlog_end_trans(thd, trx_data, &qev);
+ error= binlog_end_trans(thd, trx_data, &qev, all);
}
else
- error= binlog_end_trans(thd, trx_data, 0);
+ error= binlog_end_trans(thd, trx_data, 0, all);
DBUG_RETURN(error);
}
@@ -1330,11 +1531,8 @@ static int binlog_rollback(handlerton *h
static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv)
{
DBUG_ENTER("binlog_savepoint_set");
- binlog_trx_data *const trx_data=
- (binlog_trx_data*) thd->ha_data[binlog_hton->slot];
- DBUG_ASSERT(mysql_bin_log.is_open() && my_b_tell(&trx_data->trans_log));
- *(my_off_t *)sv= my_b_tell(&trx_data->trans_log);
+ binlog_trans_log_savepos(thd, (my_off_t*) sv);
/* Write it to the binary log */
int const error=
@@ -1349,7 +1547,7 @@ static int binlog_savepoint_rollback(han
binlog_trx_data *const trx_data=
(binlog_trx_data*) thd->ha_data[binlog_hton->slot];
IO_CACHE *trans_log= &trx_data->trans_log;
- DBUG_ASSERT(mysql_bin_log.is_open() && my_b_tell(trans_log));
+ DBUG_ASSERT(mysql_bin_log.is_open());
/*
Write ROLLBACK TO SAVEPOINT to the binlog cache if we have updated some
@@ -1364,7 +1562,7 @@ static int binlog_savepoint_rollback(han
thd->query, thd->query_length, TRUE, FALSE);
DBUG_RETURN(error);
}
- reinit_io_cache(trans_log, WRITE_CACHE, *(my_off_t *)sv, 0, 0);
+ binlog_trans_log_truncate(thd, *(my_off_t*)sv);
DBUG_RETURN(0);
}
@@ -2495,7 +2693,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
thread. If the transaction involved MyISAM tables, it should go
into binlog even on rollback.
*/
- (void) pthread_mutex_lock(&LOCK_thread_count);
+ VOID(pthread_mutex_lock(&LOCK_thread_count));
/* Save variables so that we can reopen the log */
save_name=name;
@@ -2527,7 +2725,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
my_free((gptr) save_name, MYF(0));
err:
- (void) pthread_mutex_unlock(&LOCK_thread_count);
+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
pthread_mutex_unlock(&LOCK_index);
pthread_mutex_unlock(&LOCK_log);
DBUG_RETURN(error);
@@ -3093,18 +3291,76 @@ int THD::binlog_setup_trx_data()
ha_data[binlog_hton->slot]= 0;
DBUG_RETURN(1); // Didn't manage to set it up
}
- trx_data->trans_log.end_of_file= max_binlog_cache_size;
+
+ trx_data= new (ha_data[binlog_hton->slot]) binlog_trx_data;
+
DBUG_RETURN(0);
}
+#ifdef HAVE_ROW_BASED_REPLICATION
/*
- Write a table map to the binary log.
+ Function to start a statement and optionally a transaction for the
+ binary log.
+
+ SYNOPSIS
+ binlog_start_trans_and_stmt()
+
+ DESCRIPTION
+
+ This function does three things:
+ - Start a transaction if not in autocommit mode or if a BEGIN
+ statement has been seen.
+
+ - Start a statement transaction to allow us to truncate the binary
+ log.
- This function is called from ha_external_lock() after the storage
- engine has registered for the transaction.
+ - Save the currrent binlog position so that we can roll back the
+ statement by truncating the transaction log.
+
+ We only update the saved position if the old one was undefined,
+ the reason is that there are some cases (e.g., for CREATE-SELECT)
+ where the position is saved twice (e.g., both in
+ select_create::prepare() and THD::binlog_write_table_map()) , but
+ we should use the first. This means that calls to this function
+ can be used to start the statement before the first table map
+ event, to include some extra events.
+ */
+
+void
+THD::binlog_start_trans_and_stmt()
+{
+ DBUG_ENTER("binlog_start_trans_and_stmt");
+ binlog_trx_data *trx_data= (binlog_trx_data*) ha_data[binlog_hton->slot];
+ DBUG_PRINT("enter", ("trx_data=0x%lu", trx_data));
+ if (trx_data)
+ DBUG_PRINT("enter", ("trx_data->before_stmt_pos=%u",
+ trx_data->before_stmt_pos));
+ if (trx_data == NULL ||
+ trx_data->before_stmt_pos == MY_OFF_T_UNDEF)
+ {
+ /*
+ The call to binlog_trans_log_savepos() might create the trx_data
+ structure, if it didn't exist before, so we save the position
+ into an auto variable and then write it into the transaction
+ data for the binary log (i.e., trx_data).
+ */
+ my_off_t pos= 0;
+ binlog_trans_log_savepos(this, &pos);
+ trx_data= (binlog_trx_data*) ha_data[binlog_hton->slot];
+
+ trx_data->before_stmt_pos= pos;
+
+ if (options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
+ trans_register_ha(this, TRUE, binlog_hton);
+ trans_register_ha(this, FALSE, binlog_hton);
+ }
+ DBUG_VOID_RETURN;
+}
+
+/*
+ Write a table map to the binary log.
*/
-#ifdef HAVE_ROW_BASED_REPLICATION
int THD::binlog_write_table_map(TABLE *table, bool is_trans)
{
int error;
@@ -3123,10 +3379,8 @@ int THD::binlog_write_table_map(TABLE *t
Table_map_log_event
the_event(this, table, table->s->table_map_id, is_trans, flags);
- if (is_trans)
- trans_register_ha(this,
- (options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) != 0,
- binlog_hton);
+ if (is_trans && binlog_table_maps == 0)
+ binlog_start_trans_and_stmt();
if ((error= mysql_bin_log.write(&the_event)))
DBUG_RETURN(error);
@@ -3147,7 +3401,7 @@ THD::binlog_get_pending_rows_event() con
(since the trx_data is set up there). In that case, we just return
NULL.
*/
- return trx_data ? trx_data->pending : NULL;
+ return trx_data ? trx_data->pending() : NULL;
}
void
@@ -3160,7 +3414,7 @@ THD::binlog_set_pending_rows_event(Rows_
(binlog_trx_data*) ha_data[binlog_hton->slot];
DBUG_ASSERT(trx_data);
- trx_data->pending= ev;
+ trx_data->set_pending(ev);
}
@@ -3169,8 +3423,9 @@ THD::binlog_set_pending_rows_event(Rows_
(either cached binlog if transaction, or disk binlog). Sets a new pending
event.
*/
-int MYSQL_BIN_LOG::
- flush_and_set_pending_rows_event(THD *thd, Rows_log_event* event)
+int
+MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd,
+ Rows_log_event* event)
{
DBUG_ENTER("MYSQL_BIN_LOG::flush_and_set_pending_rows_event(event)");
DBUG_ASSERT(mysql_bin_log.is_open());
@@ -3183,9 +3438,9 @@ int MYSQL_BIN_LOG::
DBUG_ASSERT(trx_data);
- DBUG_PRINT("info", ("trx_data->pending=%p", trx_data->pending));
+ DBUG_PRINT("info", ("trx_data->pending()=%p", trx_data->pending()));
- if (Rows_log_event* pending= trx_data->pending)
+ if (Rows_log_event* pending= trx_data->pending())
{
IO_CACHE *file= &log_file;
@@ -3335,15 +3590,14 @@ bool MYSQL_BIN_LOG::write(Log_event *eve
binlog_trx_data *const trx_data=
(binlog_trx_data*) thd->ha_data[binlog_hton->slot];
IO_CACHE *trans_log= &trx_data->trans_log;
- bool trans_log_in_use= my_b_tell(trans_log) != 0;
- if (event_info->get_cache_stmt() && !trans_log_in_use)
- trans_register_ha(thd,
- (thd->options &
- (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) != 0,
- binlog_hton);
- if (event_info->get_cache_stmt() || trans_log_in_use)
+ my_off_t trans_log_pos= my_b_tell(trans_log);
+ if (event_info->get_cache_stmt() || trans_log_pos != 0)
{
- DBUG_PRINT("info", ("Using trans_log"));
+ DBUG_PRINT("info", ("Using trans_log: cache=%d, trans_log_pos=%u",
+ event_info->get_cache_stmt(),
+ trans_log_pos));
+ if (trans_log_pos == 0)
+ thd->binlog_start_trans_and_stmt();
file= trans_log;
}
/*
@@ -3547,6 +3801,12 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_C
uint length;
/*
+ We only bother to write to the binary log if there is anything
+ to write.
+ */
+ if (my_b_tell(cache) > 0)
+ {
+ /*
Log "BEGIN" at the beginning of the transaction.
which may contain more than 1 SQL statement.
*/
@@ -3587,7 +3847,7 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_C
DBUG_EXECUTE_IF("half_binlogged_transaction", goto DBUG_skip_commit;);
} while ((length=my_b_fill(cache)));
- if (commit_event->write(&log_file))
+ if (commit_event && commit_event->write(&log_file))
goto err;
#ifndef DBUG_OFF
DBUG_skip_commit:
@@ -3602,6 +3862,8 @@ DBUG_skip_commit:
goto err;
}
signal_update();
+ }
+
/*
if commit_event is Xid_log_event, increase the number of
prepared_xids (it's decreasd in ::unlog()). Binlog cannot be rotated
@@ -3610,7 +3872,7 @@ DBUG_skip_commit:
If the commit_event is not Xid_log_event (then it's a Query_log_event)
rotate binlog, if necessary.
*/
- if (commit_event->get_type_code() == XID_EVENT)
+ if (commit_event && commit_event->get_type_code() == XID_EVENT)
{
pthread_mutex_lock(&LOCK_prep_xids);
prepared_xids++;
@@ -4620,12 +4882,17 @@ int TC_LOG_BINLOG::log(THD *thd, my_xid
Xid_log_event xle(thd, xid);
binlog_trx_data *trx_data=
(binlog_trx_data*) thd->ha_data[binlog_hton->slot];
- DBUG_RETURN(!binlog_end_trans(thd, trx_data, &xle)); // invert return value
+ /*
+ We always commit the entire transaction when writing an XID. Also
+ note that the return value is inverted.
+ */
+ DBUG_RETURN(!binlog_end_trans(thd, trx_data, &xle, TRUE));
}
void TC_LOG_BINLOG::unlog(ulong cookie, my_xid xid)
{
pthread_mutex_lock(&LOCK_prep_xids);
+ DBUG_ASSERT(prepared_xids > 0);
if (--prepared_xids == 0)
pthread_cond_signal(&COND_prep_xids);
pthread_mutex_unlock(&LOCK_prep_xids);
--- 1.321/sql/sql_class.h 2006-10-17 11:23:19 -04:00
+++ 1.322/sql/sql_class.h 2006-10-17 11:23:19 -04:00
@@ -930,6 +930,7 @@ public:
/*
Public interface to write RBR events to the binlog
*/
+ void binlog_start_trans_and_stmt();
int binlog_write_table_map(TABLE *table, bool is_transactional);
int binlog_write_row(TABLE* table, bool is_transactional,
MY_BITMAP const* cols, my_size_t colcnt,
--- 1.231/sql/sql_insert.cc 2006-10-17 11:23:19 -04:00
+++ 1.232/sql/sql_insert.cc 2006-10-17 11:23:19 -04:00
@@ -2033,6 +2033,10 @@ err:
rolled back. We only need to roll back a potential statement
transaction, since real transactions are rolled back in
close_thread_tables().
+
+ TODO: This is not true any more, table maps are generated on the
+ first call to ha_*_row() instead. Remove code that are used to
+ cover for the case outlined above.
*/
ha_rollback_stmt(thd);
@@ -2402,6 +2406,7 @@ select_insert::prepare(List<Item> &value
DBUG_ENTER("select_insert::prepare");
unit= u;
+
/*
Since table in which we are going to insert is added to the first
select, LEX::current_select should point to the first select while
@@ -2631,20 +2636,26 @@ void select_insert::send_error(uint errc
if (errcode != ER_UNKNOWN_ERROR && !thd->net.report_error)
my_message(errcode, err, MYF(0));
- if (!table)
+ /*
+ If the creation of the table failed (due to a syntax error, for
+ example), no table will have been opened and therefore 'table'
+ will be NULL. In that case, we still need to execute the rollback
+ and the end of the function to truncate the binary log, but we can
+ skip all the intermediate steps.
+ */
+ if (table)
{
/*
- This can only happen when using CREATE ... SELECT and the table was not
- created becasue of an syntax error
+ If we are not in prelocked mode, we end the bulk insert started
+ before.
*/
- DBUG_VOID_RETURN;
- }
if (!thd->prelocked_mode)
table->file->ha_end_bulk_insert();
+
/*
- If at least one row has been inserted/modified and will stay in the table
- (the table doesn't have transactions) we must write to the binlog (and
- the error code will make the slave stop).
+ If at least one row has been inserted/modified and will stay in
+ the table (the table doesn't have transactions) we must write to
+ the binlog (and the error code will make the slave stop).
For many errors (example: we got a duplicate key error while
inserting into a MyISAM table), no row will be added to the table,
@@ -2652,22 +2663,12 @@ void select_insert::send_error(uint errc
be an error code mismatch (the inserts will succeed on the slave
with no error).
- If we are using row-based replication we have two cases where this
- code is executed: replication of CREATE-SELECT and replication of
- INSERT-SELECT.
-
- When replicating a CREATE-SELECT statement, we shall not write the
- events to the binary log and should thus not set
- OPTION_STATUS_NO_TRANS_UPDATE.
-
- When replicating INSERT-SELECT, we shall not write the events to
- the binary log for transactional table, but shall write all events
- if there is one or more writes to non-transactional tables. In
- this case, the OPTION_STATUS_NO_TRANS_UPDATE is set if there is a
- write to a non-transactional table, otherwise it is cleared.
+ If table creation failed, the number of rows modified will also be
+ zero, so no check for that is made.
*/
if (info.copied || info.deleted || info.updated)
{
+ DBUG_ASSERT(table != NULL);
if (!table->file->has_transactions())
{
if (mysql_bin_log.is_open())
@@ -2681,8 +2682,10 @@ void select_insert::send_error(uint errc
query_cache_invalidate3(thd, table, 1);
}
}
- ha_rollback_stmt(thd);
table->file->ha_release_auto_increment();
+ }
+
+ ha_rollback_stmt(thd);
DBUG_VOID_RETURN;
}
@@ -2690,8 +2693,11 @@ void select_insert::send_error(uint errc
bool select_insert::send_eof()
{
int error,error2;
+ bool const trans_table= table->file->has_transactions();
ulonglong id;
DBUG_ENTER("select_insert::send_eof");
+ DBUG_PRINT("enter", ("trans_table=%d, table_type='%s'",
+ trans_table, table->file->table_type()));
error= (!thd->prelocked_mode) ? table->file->ha_end_bulk_insert():0;
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
@@ -2711,9 +2717,8 @@ bool select_insert::send_eof()
are not logged in RBR)
- We are using statement based replication
*/
- if (!table->file->has_transactions() &&
- (!table->s->tmp_table ||
- !thd->current_stmt_binlog_row_based))
+ if (!trans_table &&
+ (!table->s->tmp_table || !thd->current_stmt_binlog_row_based))
thd->options|= OPTION_STATUS_NO_TRANS_UPDATE;
}
@@ -2729,11 +2734,22 @@ bool select_insert::send_eof()
thd->clear_error();
thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query, thd->query_length,
- table->file->has_transactions(), FALSE);
+ trans_table, FALSE);
}
- if ((error2=ha_autocommit_or_rollback(thd,error)) && ! error)
+ /*
+ We will call ha_autocommit_or_rollback() also for
+ non-transactional tables under row-based replication: there might
+ be events in the binary logs transaction, and we need to write
+ them to the binary log.
+ */
+ if (trans_table || thd->current_stmt_binlog_row_based)
+ {
+ int const error2= ha_autocommit_or_rollback(thd, error);
+ if (error2 && !error)
error=error2;
+ }
table->file->ha_release_auto_increment();
+
if (error)
{
table->file->print_error(error,MYF(0));
@@ -2930,14 +2946,19 @@ select_create::prepare(List<Item> &value
class MY_HOOKS : public TABLEOP_HOOKS {
public:
MY_HOOKS(select_create *x) : ptr(x) { }
+
+ private:
virtual void do_prelock(TABLE **tables, uint count)
{
+ TABLE const *const table = *tables;
if (ptr->get_thd()->current_stmt_binlog_row_based &&
- !(ptr->get_create_info()->options & HA_LEX_CREATE_TMP_TABLE))
+ table->s->tmp_table == NO_TMP_TABLE &&
+ !ptr->get_create_info()->table_existed)
+ {
ptr->binlog_show_create_table(tables, count);
}
+ }
- private:
select_create *ptr;
};
@@ -2946,6 +2967,20 @@ select_create::prepare(List<Item> &value
#endif
unit= u;
+
+#ifdef HAVE_ROW_BASED_REPLICATION
+ /*
+ Start a statement transaction before the create if we are creating
+ a non-temporary table and are using row-based replication for the
+ statement.
+ */
+ if ((thd->lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) == 0 &&
+ thd->current_stmt_binlog_row_based)
+ {
+ thd->binlog_start_trans_and_stmt();
+ }
+#endif
+
if (!(table= create_table_from_items(thd, create_info, create_table,
extra_fields, keys, &values,
&thd->extra_lock, hook_ptr)))
@@ -3093,8 +3128,17 @@ void select_create::abort()
table->s->version= 0;
hash_delete(&open_cache,(byte*) table);
if (!create_info->table_existed)
+ {
quick_rm_table(table_type, create_table->db,
create_table->table_name, 0);
+ /*
+ We roll back the statement, including truncating the
+ transaction cache of the binary log, if the statement
+ failed.
+ */
+ if (thd->current_stmt_binlog_row_based)
+ ha_rollback_stmt(thd);
+ }
/* Tell threads waiting for refresh that something has happened */
if (version != refresh_version)
broadcast_refresh();
--- 1.366/sql/sql_table.cc 2006-10-17 11:23:19 -04:00
+++ 1.367/sql/sql_table.cc 2006-10-17 11:23:19 -04:00
@@ -5232,6 +5232,7 @@ bool mysql_alter_table(THD *thd,char *ne
/* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
if (alter_info->tablespace_op != NO_TABLESPACE_OP)
+ /* Conditionally writes to binlog. */
DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list,
alter_info->tablespace_op));
if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
@@ -5341,10 +5342,10 @@ bool mysql_alter_table(THD *thd,char *ne
!table->s->tmp_table) // no need to touch frm
{
error=0;
+ VOID(pthread_mutex_lock(&LOCK_open));
if (new_name != table_name || new_db != db)
{
thd->proc_info="rename";
- VOID(pthread_mutex_lock(&LOCK_open));
/* Then do a 'simple' rename of the table */
error=0;
if (!access(new_name_buff,F_OK))
@@ -5367,7 +5368,6 @@ bool mysql_alter_table(THD *thd,char *ne
error= -1;
}
}
- VOID(pthread_mutex_unlock(&LOCK_open));
}
if (!error)
@@ -5376,16 +5376,12 @@ bool mysql_alter_table(THD *thd,char *ne
case LEAVE_AS_IS:
break;
case ENABLE:
- VOID(pthread_mutex_lock(&LOCK_open));
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
- VOID(pthread_mutex_unlock(&LOCK_open));
error= table->file->enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
/* COND_refresh will be signaled in close_thread_tables() */
break;
case DISABLE:
- VOID(pthread_mutex_lock(&LOCK_open));
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
- VOID(pthread_mutex_unlock(&LOCK_open));
error=table->file->disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
/* COND_refresh will be signaled in close_thread_tables() */
break;
@@ -5410,6 +5406,7 @@ bool mysql_alter_table(THD *thd,char *ne
table->file->print_error(error, MYF(0));
error= -1;
}
+ VOID(pthread_mutex_unlock(&LOCK_open));
table_list->table=0; // For query cache
query_cache_invalidate3(thd, table_list, 0);
DBUG_RETURN(error);
--- 1.209/sql/sql_update.cc 2006-10-17 11:23:19 -04:00
+++ 1.210/sql/sql_update.cc 2006-10-17 11:23:19 -04:00
@@ -1217,6 +1217,8 @@ multi_update::initialize_tables(JOIN *jo
TMP_TABLE_PARAM *tmp_param;
table->mark_columns_needed_for_update();
+ if (ignore)
+ table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
if (table == main_table) // First table in join
{
if (safe_update_on_fly(join->join_tab))
@@ -1331,7 +1333,11 @@ multi_update::~multi_update()
{
TABLE_LIST *table;
for (table= update_tables ; table; table= table->next_local)
+ {
table->table->no_keyread= table->table->no_cache= 0;
+ if (ignore)
+ table->table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
+ }
if (tmp_tables)
{
--- 1.110/sql/sql_view.cc 2006-10-17 11:23:20 -04:00
+++ 1.111/sql/sql_view.cc 2006-10-17 11:23:20 -04:00
@@ -212,6 +212,7 @@ fill_defined_view_parts (THD *thd, TABLE
SYNOPSIS
mysql_create_view()
thd - thread handler
+ views - views to create
mode - VIEW_CREATE_NEW, VIEW_ALTER, VIEW_CREATE_OR_REPLACE
RETURN VALUE
@@ -219,7 +220,7 @@ fill_defined_view_parts (THD *thd, TABLE
TRUE Error
*/
-bool mysql_create_view(THD *thd,
+bool mysql_create_view(THD *thd, TABLE_LIST *views,
enum_view_create_mode mode)
{
LEX *lex= thd->lex;
@@ -548,6 +549,49 @@ bool mysql_create_view(THD *thd,
}
VOID(pthread_mutex_lock(&LOCK_open));
res= mysql_register_view(thd, view, mode);
+
+ if (mysql_bin_log.is_open())
+ {
+ String buff;
+ const LEX_STRING command[3]=
+ {{ C_STRING_WITH_LEN("CREATE ") },
+ { C_STRING_WITH_LEN("ALTER ") },
+ { C_STRING_WITH_LEN("CREATE OR REPLACE ") }};
+
+ buff.append(command[thd->lex->create_view_mode].str,
+ command[thd->lex->create_view_mode].length);
+ view_store_options(thd, views, &buff);
+ buff.append(STRING_WITH_LEN("VIEW "));
+ /* Test if user supplied a db (ie: we did not use thd->db) */
+ if (views->db && views->db[0] &&
+ (thd->db == NULL || strcmp(views->db, thd->db)))
+ {
+ append_identifier(thd, &buff, views->db,
+ views->db_length);
+ buff.append('.');
+ }
+ append_identifier(thd, &buff, views->table_name,
+ views->table_name_length);
+ if (lex->view_list.elements)
+ {
+ List_iterator_fast<LEX_STRING> names(lex->view_list);
+ LEX_STRING *name;
+ int i;
+
+ for (i= 0; name= names++; i++)
+ {
+ buff.append(i ? ", " : "(");
+ append_identifier(thd, &buff, name->str, name->length);
+ }
+ buff.append(')');
+ }
+ buff.append(STRING_WITH_LEN(" AS "));
+ buff.append(views->source.str, views->source.length);
+
+ thd->binlog_query(THD::STMT_QUERY_TYPE,
+ buff.ptr(), buff.length(), FALSE, FALSE);
+ }
+
VOID(pthread_mutex_unlock(&LOCK_open));
if (view->revision != 1)
query_cache_invalidate3(thd, view, 0);
@@ -1318,13 +1362,13 @@ bool mysql_drop_view(THD *thd, TABLE_LIS
enum legacy_db_type not_used;
DBUG_ENTER("mysql_drop_view");
+ VOID(pthread_mutex_lock(&LOCK_open));
for (view= views; view; view= view->next_local)
{
TABLE_SHARE *share;
frm_type_enum type= FRMTYPE_ERROR;
build_table_filename(path, sizeof(path),
view->db, view->table_name, reg_ext, 0);
- VOID(pthread_mutex_lock(&LOCK_open));
if (access(path, F_OK) ||
FRMTYPE_VIEW != (type= mysql_frm_type(thd, path, ¬_used)))
@@ -1336,7 +1380,6 @@ bool mysql_drop_view(THD *thd, TABLE_LIS
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
name);
- VOID(pthread_mutex_unlock(&LOCK_open));
continue;
}
if (type == FRMTYPE_TABLE)
@@ -1353,7 +1396,6 @@ bool mysql_drop_view(THD *thd, TABLE_LIS
non_existant_views.append(',');
non_existant_views.append(String(view->table_name,system_charset_info));
}
- VOID(pthread_mutex_unlock(&LOCK_open));
continue;
}
if (my_delete(path, MYF(MY_WME)))
@@ -1374,8 +1416,16 @@ bool mysql_drop_view(THD *thd, TABLE_LIS
}
query_cache_invalidate3(thd, view, 0);
sp_cache_invalidate();
- VOID(pthread_mutex_unlock(&LOCK_open));
}
+
+ if (mysql_bin_log.is_open())
+ {
+ thd->clear_error();
+ thd->binlog_query(THD::MYSQL_QUERY_TYPE,
+ thd->query, thd->query_length, FALSE, FALSE);
+ }
+
+ VOID(pthread_mutex_unlock(&LOCK_open));
if (error)
{
DBUG_RETURN(TRUE);
--- 1.13/mysql-test/r/csv.result 2006-10-17 11:23:20 -04:00
+++ 1.14/mysql-test/r/csv.result 2006-10-17 11:23:20 -04:00
@@ -5204,3 +5204,22 @@ select * from bug15205;
val
drop table bug15205;
drop table bug15205_2;
+create table bug22080_1 (id int,string varchar(64)) Engine=CSV;
+create table bug22080_2 (id int,string varchar(64)) Engine=CSV;
+create table bug22080_3 (id int,string varchar(64)) Engine=CSV;
+insert into bug22080_1 values(1,'string');
+insert into bug22080_1 values(2,'string');
+insert into bug22080_1 values(3,'string');
+"1","string"
+2","string"
+"3","string"
+check table bug22080_2;
+Table Op Msg_type Msg_text
+test.bug22080_2 check error Corrupt
+"1","string"
+"2",string"
+"3","string"
+check table bug22080_3;
+Table Op Msg_type Msg_text
+test.bug22080_3 check error Corrupt
+drop tables bug22080_1,bug22080_2,bug22080_3;
--- 1.15/mysql-test/t/csv.test 2006-10-17 11:23:20 -04:00
+++ 1.16/mysql-test/t/csv.test 2006-10-17 11:23:20 -04:00
@@ -1582,3 +1582,26 @@ select * from bug15205_2;
select * from bug15205;
drop table bug15205;
drop table bug15205_2;
+
+#
+# Bug#22080 "CHECK fails to identify some corruption"
+#
+
+create table bug22080_1 (id int,string varchar(64)) Engine=CSV;
+create table bug22080_2 (id int,string varchar(64)) Engine=CSV;
+create table bug22080_3 (id int,string varchar(64)) Engine=CSV;
+insert into bug22080_1 values(1,'string');
+insert into bug22080_1 values(2,'string');
+insert into bug22080_1 values(3,'string');
+
+# Currupt the file as described in the bug report
+--exec sed -e 's/"2"/2"/' $MYSQLTEST_VARDIR/master-data/test/bug22080_1.CSV >
$MYSQLTEST_VARDIR/master-data/test/bug22080_2.CSV
+--exec sed -e 's/2","/2",/' $MYSQLTEST_VARDIR/master-data/test/bug22080_1.CSV >
$MYSQLTEST_VARDIR/master-data/test/bug22080_3.CSV
+
+--exec cat $MYSQLTEST_VARDIR/master-data/test/bug22080_2.CSV
+check table bug22080_2;
+
+--exec cat $MYSQLTEST_VARDIR/master-data/test/bug22080_3.CSV
+check table bug22080_3;
+
+drop tables bug22080_1,bug22080_2,bug22080_3;
--- 1.81/mysql-test/r/func_time.result 2006-10-17 11:23:20 -04:00
+++ 1.82/mysql-test/r/func_time.result 2006-10-17 11:23:20 -04:00
@@ -339,7 +339,9 @@ extract(DAY_MINUTE FROM "02 10:11:12")
21011
select extract(DAY_SECOND FROM "225 10:11:12");
extract(DAY_SECOND FROM "225 10:11:12")
-225101112
+8385959
+Warnings:
+Warning 1292 Truncated incorrect time value: '225 10:11:12'
select extract(HOUR FROM "1999-01-02 10:11:12");
extract(HOUR FROM "1999-01-02 10:11:12")
10
@@ -612,7 +614,7 @@ date_add(date,INTERVAL "1 1:1:1" DAY_SEC
2003-01-03 01:01:01
select date_add(date,INTERVAL "1" WEEK) from t1;
date_add(date,INTERVAL "1" WEEK)
-2003-01-09 00:00:00
+2003-01-09
select date_add(date,INTERVAL "1" QUARTER) from t1;
date_add(date,INTERVAL "1" QUARTER)
2003-04-02
@@ -621,7 +623,7 @@ timestampadd(MINUTE, 1, date)
2003-01-02 00:01:00
select timestampadd(WEEK, 1, date) from t1;
timestampadd(WEEK, 1, date)
-2003-01-09 00:00:00
+2003-01-09
select timestampadd(SQL_TSI_SECOND, 1, date) from t1;
timestampadd(SQL_TSI_SECOND, 1, date)
2003-01-02 00:00:01
@@ -902,6 +904,93 @@ fmtddate field2
Sep-4 12:00AM abcd
DROP TABLE testBug8868;
SET NAMES DEFAULT;
+SELECT SEC_TO_TIME(3300000);
+SEC_TO_TIME(3300000)
+838:59:59
+Warnings:
+Warning 1292 Truncated incorrect time value: '3300000'
+SELECT SEC_TO_TIME(3300000)+0;
+SEC_TO_TIME(3300000)+0
+8385959.000000
+Warnings:
+Warning 1292 Truncated incorrect time value: '3300000'
+SELECT SEC_TO_TIME(3600 * 4294967296);
+SEC_TO_TIME(3600 * 4294967296)
+838:59:59
+Warnings:
+Warning 1292 Truncated incorrect time value: '15461882265600'
+SELECT TIME_TO_SEC('916:40:00');
+TIME_TO_SEC('916:40:00')
+3020399
+Warnings:
+Warning 1292 Truncated incorrect time value: '916:40:00'
+SELECT ADDTIME('500:00:00', '416:40:00');
+ADDTIME('500:00:00', '416:40:00')
+838:59:59
+Warnings:
+Warning 1292 Truncated incorrect time value: '916:40:00'
+SELECT ADDTIME('916:40:00', '416:40:00');
+ADDTIME('916:40:00', '416:40:00')
+838:59:59
+Warnings:
+Warning 1292 Truncated incorrect time value: '916:40:00'
+Warning 1292 Truncated incorrect time value: '1255:39:59'
+SELECT SUBTIME('916:40:00', '416:40:00');
+SUBTIME('916:40:00', '416:40:00')
+422:19:59
+Warnings:
+Warning 1292 Truncated incorrect time value: '916:40:00'
+SELECT SUBTIME('-916:40:00', '416:40:00');
+SUBTIME('-916:40:00', '416:40:00')
+-838:59:59
+Warnings:
+Warning 1292 Truncated incorrect time value: '-916:40:00'
+Warning 1292 Truncated incorrect time value: '-1255:39:59'
+SELECT MAKETIME(916,0,0);
+MAKETIME(916,0,0)
+838:59:59
+Warnings:
+Warning 1292 Truncated incorrect time value: '916:00:00'
+SELECT MAKETIME(4294967296, 0, 0);
+MAKETIME(4294967296, 0, 0)
+838:59:59
+Warnings:
+Warning 1292 Truncated incorrect time value: '4294967296:00:00'
+SELECT MAKETIME(-4294967296, 0, 0);
+MAKETIME(-4294967296, 0, 0)
+-838:59:59
+Warnings:
+Warning 1292 Truncated incorrect time value: '-4294967296:00:00'
+SELECT MAKETIME(0, 4294967296, 0);
+MAKETIME(0, 4294967296, 0)
+NULL
+SELECT MAKETIME(0, 0, 4294967296);
+MAKETIME(0, 0, 4294967296)
+NULL
+SELECT MAKETIME(CAST(-1 AS UNSIGNED), 0, 0);
+MAKETIME(CAST(-1 AS UNSIGNED), 0, 0)
+838:59:59
+Warnings:
+Warning 1292 Truncated incorrect time value: '18446744073709551615:00:00'
+SELECT EXTRACT(HOUR FROM '100000:02:03');
+EXTRACT(HOUR FROM '100000:02:03')
+838
+Warnings:
+Warning 1292 Truncated incorrect time value: '100000:02:03'
+CREATE TABLE t1(f1 TIME);
+INSERT INTO t1 VALUES('916:00:00 a');
+Warnings:
+Warning 1265 Data truncated for column 'f1' at row 1
+Warning 1264 Out of range value adjusted for column 'f1' at row 1
+SELECT * FROM t1;
+f1
+838:59:59
+DROP TABLE t1;
+SELECT SEC_TO_TIME(CAST(-1 AS UNSIGNED));
+SEC_TO_TIME(CAST(-1 AS UNSIGNED))
+838:59:59
+Warnings:
+Warning 1292 Truncated incorrect time value: '18446744073709551615'
(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 DAY)),'%H') As H)
union
(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 DAY)),'%H') As H);
--- 1.66/mysql-test/t/func_time.test 2006-10-17 11:23:20 -04:00
+++ 1.67/mysql-test/t/func_time.test 2006-10-17 11:23:20 -04:00
@@ -466,6 +466,47 @@ SET NAMES DEFAULT;
#
+# Bug #11655: Wrong time is returning from nested selects - maximum time exists
+#
+# check if SEC_TO_TIME() handles out-of-range values correctly
+SELECT SEC_TO_TIME(3300000);
+SELECT SEC_TO_TIME(3300000)+0;
+SELECT SEC_TO_TIME(3600 * 4294967296);
+
+# check if TIME_TO_SEC() handles out-of-range values correctly
+SELECT TIME_TO_SEC('916:40:00');
+
+# check if ADDTIME() handles out-of-range values correctly
+SELECT ADDTIME('500:00:00', '416:40:00');
+SELECT ADDTIME('916:40:00', '416:40:00');
+
+# check if SUBTIME() handles out-of-range values correctly
+SELECT SUBTIME('916:40:00', '416:40:00');
+SELECT SUBTIME('-916:40:00', '416:40:00');
+
+# check if MAKETIME() handles out-of-range values correctly
+SELECT MAKETIME(916,0,0);
+SELECT MAKETIME(4294967296, 0, 0);
+SELECT MAKETIME(-4294967296, 0, 0);
+SELECT MAKETIME(0, 4294967296, 0);
+SELECT MAKETIME(0, 0, 4294967296);
+SELECT MAKETIME(CAST(-1 AS UNSIGNED), 0, 0);
+
+# check if EXTRACT() handles out-of-range values correctly
+SELECT EXTRACT(HOUR FROM '100000:02:03');
+
+# check if we get proper warnings if both input string truncation
+# and out-of-range value occur
+CREATE TABLE t1(f1 TIME);
+INSERT INTO t1 VALUES('916:00:00 a');
+SELECT * FROM t1;
+DROP TABLE t1;
+
+#
+# Bug #20927: sec_to_time treats big unsigned as signed
+#
+# check if SEC_TO_TIME() handles BIGINT UNSIGNED values correctly
+SELECT SEC_TO_TIME(CAST(-1 AS UNSIGNED));
# Bug #19844 time_format in Union truncates values
#
--- 1.55/mysql-test/r/partition.result 2006-10-17 11:23:20 -04:00
+++ 1.56/mysql-test/r/partition.result 2006-10-17 11:23:20 -04:00
@@ -1090,41 +1090,15 @@ drop table t1;
create table t1 (a int) engine myisam
partition by range (a)
subpartition by hash (a)
-(partition p0 VALUES LESS THAN (1) DATA DIRECTORY = 'hello/master-data/tmpdata' INDEX
DIRECTORY = 'hello/master-data/tmpinx'
+(partition p0 VALUES LESS THAN (1) DATA DIRECTORY =
'MYSQLTEST_VARDIR/master-data/tmpdata' INDEX DIRECTORY =
'MYSQLTEST_VARDIR/master-data/tmpinx'
(SUBPARTITION subpart00, SUBPARTITION subpart01));
-hello/master-data/test/t1.frm
-hello/master-data/test/t1.par
-hello/master-data/test/t1#P#p0#SP#subpart00.MYD
-hello/master-data/test/t1#P#p0#SP#subpart00.MYI
-hello/master-data/test/t1#P#p0#SP#subpart01.MYD
-hello/master-data/test/t1#P#p0#SP#subpart01.MYI
-hello/master-data/tmpdata/t1#P#p0#SP#subpart00.MYD
-hello/master-data/tmpdata/t1#P#p0#SP#subpart01.MYD
-hello/master-data/tmpinx/t1#P#p0#SP#subpart00.MYI
-hello/master-data/tmpinx/t1#P#p0#SP#subpart01.MYI
+Checking if file exists before alter
ALTER TABLE t1 REORGANIZE PARTITION p0 INTO
-(partition p1 VALUES LESS THAN (1) DATA DIRECTORY = 'hello/master-data/tmpdata' INDEX
DIRECTORY = 'hello/master-data/tmpinx'
+(partition p1 VALUES LESS THAN (1) DATA DIRECTORY =
'MYSQLTEST_VARDIR/master-data/tmpdata' INDEX DIRECTORY =
'MYSQLTEST_VARDIR/master-data/tmpinx'
(SUBPARTITION subpart10, SUBPARTITION subpart11),
-partition p2 VALUES LESS THAN (2) DATA DIRECTORY = 'hello/master-data/tmpdata' INDEX
DIRECTORY = 'hello/master-data/tmpinx'
+partition p2 VALUES LESS THAN (2) DATA DIRECTORY = 'MYSQLTEST_VARDIR/master-data/tmpdata'
INDEX DIRECTORY = 'MYSQLTEST_VARDIR/master-data/tmpinx'
(SUBPARTITION subpart20, SUBPARTITION subpart21));
-hello/master-data/test/t1.frm
-hello/master-data/test/t1.par
-hello/master-data/test/t1#P#p1#SP#subpart10.MYD
-hello/master-data/test/t1#P#p1#SP#subpart10.MYI
-hello/master-data/test/t1#P#p1#SP#subpart11.MYD
-hello/master-data/test/t1#P#p1#SP#subpart11.MYI
-hello/master-data/test/t1#P#p2#SP#subpart20.MYD
-hello/master-data/test/t1#P#p2#SP#subpart20.MYI
-hello/master-data/test/t1#P#p2#SP#subpart21.MYD
-hello/master-data/test/t1#P#p2#SP#subpart21.MYI
-hello/master-data/tmpdata/t1#P#p1#SP#subpart10.MYD
-hello/master-data/tmpdata/t1#P#p1#SP#subpart11.MYD
-hello/master-data/tmpdata/t1#P#p2#SP#subpart20.MYD
-hello/master-data/tmpdata/t1#P#p2#SP#subpart21.MYD
-hello/master-data/tmpinx/t1#P#p1#SP#subpart10.MYI
-hello/master-data/tmpinx/t1#P#p1#SP#subpart11.MYI
-hello/master-data/tmpinx/t1#P#p2#SP#subpart20.MYI
-hello/master-data/tmpinx/t1#P#p2#SP#subpart21.MYI
+Checking if file exists after alter
drop table t1;
create table t1 (a bigint unsigned not null, primary key(a))
engine = myisam
--- 1.48/mysql-test/t/partition.test 2006-10-17 11:23:20 -04:00
+++ 1.49/mysql-test/t/partition.test 2006-10-17 11:23:20 -04:00
@@ -4,6 +4,7 @@
# Taken fromm the select test
#
-- source include/have_partition.inc
+-- source include/have_innodb.inc
#
# This test is disabled on Windows due to BUG#19107
#
@@ -1286,37 +1287,51 @@ eval SET @inx_dir = 'INDEX DIRECTORY = '
let $inx_directory = `select @inx_dir`;
--enable_query_log
---replace_result $MYSQLTEST_VARDIR "hello"
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval create table t1 (a int) engine myisam
partition by range (a)
subpartition by hash (a)
(partition p0 VALUES LESS THAN (1) $data_directory $inx_directory
(SUBPARTITION subpart00, SUBPARTITION subpart01));
---replace_result $MYSQLTEST_VARDIR "hello"
---exec ls $MYSQLTEST_VARDIR/master-data/test/t1.* || true
---replace_result $MYSQLTEST_VARDIR "hello"
---exec ls $MYSQLTEST_VARDIR/master-data/test/t1#* || true
---replace_result $MYSQLTEST_VARDIR "hello"
---exec ls $MYSQLTEST_VARDIR/master-data/tmpdata/t1#* || true
---replace_result $MYSQLTEST_VARDIR "hello"
---exec ls $MYSQLTEST_VARDIR/master-data/tmpinx/t1#* || true
---replace_result $MYSQLTEST_VARDIR "hello"
+--echo Checking if file exists before alter
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1.frm
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1.par
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p0#SP#subpart00.MYD
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p0#SP#subpart00.MYI
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p0#SP#subpart01.MYD
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p0#SP#subpart01.MYI
+--file_exists $MYSQLTEST_VARDIR/master-data/tmpdata/t1#P#p0#SP#subpart00.MYD
+--file_exists $MYSQLTEST_VARDIR/master-data/tmpdata/t1#P#p0#SP#subpart01.MYD
+--file_exists $MYSQLTEST_VARDIR/master-data/tmpinx/t1#P#p0#SP#subpart00.MYI
+--file_exists $MYSQLTEST_VARDIR/master-data/tmpinx/t1#P#p0#SP#subpart01.MYI
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval ALTER TABLE t1 REORGANIZE PARTITION p0 INTO
(partition p1 VALUES LESS THAN (1) $data_directory $inx_directory
(SUBPARTITION subpart10, SUBPARTITION subpart11),
partition p2 VALUES LESS THAN (2) $data_directory $inx_directory
(SUBPARTITION subpart20, SUBPARTITION subpart21));
---replace_result $MYSQLTEST_VARDIR "hello"
---exec ls $MYSQLTEST_VARDIR/master-data/test/t1.* || true
---replace_result $MYSQLTEST_VARDIR "hello"
---exec ls $MYSQLTEST_VARDIR/master-data/test/t1#* || true
---replace_result $MYSQLTEST_VARDIR "hello"
---exec ls $MYSQLTEST_VARDIR/master-data/tmpdata/t1#* || true
---replace_result $MYSQLTEST_VARDIR "hello"
---exec ls $MYSQLTEST_VARDIR/master-data/tmpinx/t1#* || true
+--echo Checking if file exists after alter
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1.frm
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1.par
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p1#SP#subpart10.MYD
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p1#SP#subpart10.MYI
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p1#SP#subpart11.MYD
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p1#SP#subpart11.MYI
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p2#SP#subpart20.MYD
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p2#SP#subpart20.MYI
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p2#SP#subpart21.MYD
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p2#SP#subpart21.MYI
+--file_exists $MYSQLTEST_VARDIR/master-data/tmpdata/t1#P#p1#SP#subpart10.MYD
+--file_exists $MYSQLTEST_VARDIR/master-data/tmpdata/t1#P#p1#SP#subpart11.MYD
+--file_exists $MYSQLTEST_VARDIR/master-data/tmpdata/t1#P#p2#SP#subpart20.MYD
+--file_exists $MYSQLTEST_VARDIR/master-data/tmpdata/t1#P#p2#SP#subpart21.MYD
+--file_exists $MYSQLTEST_VARDIR/master-data/tmpinx/t1#P#p1#SP#subpart10.MYI
+--file_exists $MYSQLTEST_VARDIR/master-data/tmpinx/t1#P#p1#SP#subpart11.MYI
+--file_exists $MYSQLTEST_VARDIR/master-data/tmpinx/t1#P#p2#SP#subpart20.MYI
+--file_exists $MYSQLTEST_VARDIR/master-data/tmpinx/t1#P#p2#SP#subpart21.MYI
drop table t1;
--exec rmdir $MYSQLTEST_VARDIR/master-data/tmpdata || true
| Thread |
|---|
| • bk commit into 5.1 tree (cmiller:1.2313) | Chad MILLER | 17 Oct |