summaryrefslogtreecommitdiff
path: root/innobase
diff options
context:
space:
mode:
authorunknown <tsmith@siva.hindu.god>2007-03-22 14:40:52 -0600
committerunknown <tsmith@siva.hindu.god>2007-03-22 14:40:52 -0600
commit805c2d52cd4a6cca64605ead2ddc0e43a65b819c (patch)
tree155a0829cce062b1d6e6cea2e24ab82536187f32 /innobase
parentbdb9b4483e270fc9d095109ad47615b6b4be62f3 (diff)
downloadmariadb-git-805c2d52cd4a6cca64605ead2ddc0e43a65b819c.tar.gz
NULL MERGE this to 5.1
Apply the following InnoDB snapshots: innodb-5.0-ss1319 innodb-5.0-ss1331 innodb-5.0-ss1333 innodb-5.0-ss1341 Fixes: - Bug #21409: Incorrect result returned when in READ-COMMITTED with query_cache ON At low transaction isolation levels we let each consistent read set its own snapshot. - Bug #23666: strange Innodb_row_lock_time_% values in show status; also millisecs wrong On Windows ut_usectime returns secs and usecs relative to the UNIX epoch (which is Jan, 1 1970). - Bug #25494: LATEST DEADLOCK INFORMATION is not always cleared lock_deadlock_recursive(): When the search depth or length is exceeded, rewind lock_latest_err_file and display the two transactions at the point of aborting the search. - Bug #25927: Foreign key with ON DELETE SET NULL on NOT NULL can crash server Prevent ALTER TABLE ... MODIFY ... NOT NULL on columns for which there is a foreign key constraint ON ... SET NULL. - Bug #26835: Repeatable corruption of utf8-enabled tables inside InnoDB The bug could be reproduced as follows: Define a table so that the first column of the clustered index is a VARCHAR or a UTF-8 CHAR in a collation where sequences of bytes of differing length are considered equivalent. Insert and delete a record. Before the delete-marked record is purged, insert another record whose first column is of different length but equivalent to the first record. Under certain conditions, the insertion can be incorrectly performed as update-in-place. Likewise, an operation that could be done as update-in-place can unnecessarily be performed as delete and insert, but that would not cause corruption but merely degraded performance. innobase/dict/dict0dict.c: NULL MERGE this to 5.1 Apply the following InnoDB snapshots: innodb-5.0-ss1319 innodb-5.0-ss1331 innodb-5.0-ss1333 innodb-5.0-ss1341 Revision r1317: branches/5.0: Port r1316 from trunk: Prevent ALTER TABLE ... MODIFY ... NOT NULL on columns for which there is a foreign key constraint ON ... SET NULL. (Bug #25927) dict_foreign_find_index(): Add paramettter check_null. dict_foreign_add_to_cache(): Do not allow ON DELETE SET NULL or ON UPDATE SET NULL if any of the referencing columns are declared NOT NULL. innobase/include/rem0rec.ic: NULL MERGE this to 5.1 Apply the following InnoDB snapshots: innodb-5.0-ss1319 innodb-5.0-ss1331 innodb-5.0-ss1333 innodb-5.0-ss1341 Revision r1339: branches/5.0: Merge r1338 from trunk: rec_offs_nth_size(): Treat n==0 as a special case. (Bug #26835) innobase/include/sync0sync.ic: NULL MERGE this to 5.1 Apply the following InnoDB snapshots: innodb-5.0-ss1319 innodb-5.0-ss1331 innodb-5.0-ss1333 innodb-5.0-ss1341 Revision r1293: branches/5.0: Fixed inline asm code, it didn't work with GCC > ver 3.x. innobase/lock/lock0lock.c: NULL MERGE this to 5.1 Apply the following InnoDB snapshots: innodb-5.0-ss1319 innodb-5.0-ss1331 innodb-5.0-ss1333 innodb-5.0-ss1341 Revision r1331: branches/5.0: Merge r1330 from trunk: lock_deadlock_recursive(): When the search depth or length is exceeded, rewind lock_latest_err_file and display the two transactions at the point of aborting the search. (Bug #25494) Revision r1333: branches/5.0: Merge r1332 from trunk: lock_deadlock_recursive(): When aborting the search, display a note regardless of start->undo_no. Otherwise, aborted searches may show up as genuine deadlocks. This mistake was made in r1330. innobase/srv/srv0srv.c: NULL MERGE this to 5.1 Apply the following InnoDB snapshots: innodb-5.0-ss1319 innodb-5.0-ss1331 innodb-5.0-ss1333 innodb-5.0-ss1341 Revision r1261: branches/5.0: Fix for Bug# 23666. On Windows ut_usectime returns secs and usecs relative to the UNIX epoch (which is Jan, 1 1970). innobase/ut/ut0ut.c: NULL MERGE this to 5.1 Apply the following InnoDB snapshots: innodb-5.0-ss1319 innodb-5.0-ss1331 innodb-5.0-ss1333 innodb-5.0-ss1341 Revision r1261: branches/5.0: Fix for Bug# 23666. On Windows ut_usectime returns secs and usecs relative to the UNIX epoch (which is Jan, 1 1970). mysql-test/r/innodb.result: NULL MERGE this to 5.1 Apply the following InnoDB snapshots: innodb-5.0-ss1319 innodb-5.0-ss1331 innodb-5.0-ss1333 innodb-5.0-ss1341 Revision r1319: branches/5.0: Port r1318 from trunk: Add a test case for r1316 (Bug #25927). Revision r1328: branches/5.0: mysql-test: Merge changes from MySQL AB. Revision r1341: branches/5.0: Merge r1340 from trunk: innodb.test, innodb.result: Add test case for Bug #26835. The bug could be reproduced as follows: Define a table so that the first column of the clustered index is a VARCHAR or a UTF-8 CHAR in a collation where sequences of bytes of differing length are considered equivalent. Insert and delete a record. Before the delete-marked record is purged, insert another record whose first column is of different length but equivalent to the first record. Under certain conditions, the insertion can be incorrectly performed as update-in-place. Likewise, an operation that could be done as update-in-place can unnecessarily be performed as delete and insert, but that would not cause corruption but merely degraded performance. Revision r1284: Merge changes from MySQL AB: ChangeSet 2007/01/24 14:49:36+04:00 holyfoot@mysql.com bug #22682 Test fails --without-geometry geometry dependent parts moved to proper .test files mysql-test/r/innodb.result 2007/01/24 14:49:34+04:00 holyfoot@mysql.com +0 -2 result fixed mysql-test/r/innodb_gis.result 2007/01/24 14:49:34+04:00 holyfoot@mysql.com +2 -0 result fixed mysql-test/t/innodb.test 2007/01/24 14:49:34+04:00 holyfoot@mysql.com +0 -6 HAVE_GEOMETRY dependent part moved to innodb_gis.test mysql-test/t/innodb_gis.test 2007/01/24 14:49:35+04:00 holyfoot@mysql.com +6 -0 HAVE_GEOMETRY dependent part moved here from innodb.test Revision r1186: dict_load_foreign(): Use a local variable instead of the 10-bit field foreign->n_fields in order to preserve ON UPDATE CASCADE and ON DELETE CASCADE flags. For some reason, gcc does not warn about shifting a 10-bit field to right by 24 bits. (Bug #24741) This bug was introduced while reducing the memory footprint of the InnoDB data dictionary (Bug #20877). innodb.test, innodb.result: Add a test case. Revision r1318: Add a test case for r1316 (Bug #25927). Revision r1340: innodb.test, innodb.result: Add test case for Bug #26835. The bug could be reproduced as follows: Define a table so that the first column of the clustered index is a VARCHAR or a UTF-8 CHAR in a collation where sequences of bytes of differing length are considered equivalent. Insert and delete a record. Before the delete-marked record is purged, insert another record whose first column is of different length but equivalent to the first record. Under certain conditions, the insertion can be incorrectly performed as update-in-place. Likewise, an operation that could be done as update-in-place can unnecessarily be performed as delete and insert, but that would not cause corruption but merely degraded performance. mysql-test/t/innodb.test: NULL MERGE this to 5.1 Apply the following InnoDB snapshots: innodb-5.0-ss1319 innodb-5.0-ss1331 innodb-5.0-ss1333 innodb-5.0-ss1341 Revision r1279: branches/5.0: Merge changes from MySQL AB: ChangeSet 2006/11/20 22:42:06+02:00 monty@mysql.com Remove compiler warnings (Mostly in DBUG_PRINT() and unused arguments) Fixed bug in query cache when used with traceing (--with-debug) Fixed memory leak in mysqldump Removed warnings from mysqltest scripts (replaced -- with #) mysql-test/t/innodb.test 2006/11/20 22:41:41+02:00 monty@mysql.com +1 -1 Remove mysqltest warnings sql/ha_innodb.cc 2006/11/20 22:41:51+02:00 monty@mysql.com +2 -2 Fixed compiler warning Revision r1319: branches/5.0: Port r1318 from trunk: Add a test case for r1316 (Bug #25927). Revision r1328: branches/5.0: mysql-test: Merge changes from MySQL AB. Revision r1341: branches/5.0: Merge r1340 from trunk: innodb.test, innodb.result: Add test case for Bug #26835. The bug could be reproduced as follows: Define a table so that the first column of the clustered index is a VARCHAR or a UTF-8 CHAR in a collation where sequences of bytes of differing length are considered equivalent. Insert and delete a record. Before the delete-marked record is purged, insert another record whose first column is of different length but equivalent to the first record. Under certain conditions, the insertion can be incorrectly performed as update-in-place. Likewise, an operation that could be done as update-in-place can unnecessarily be performed as delete and insert, but that would not cause corruption but merely degraded performance. Revision r1284: Merge changes from MySQL AB: ChangeSet 2007/01/24 14:49:36+04:00 holyfoot@mysql.com bug #22682 Test fails --without-geometry geometry dependent parts moved to proper .test files mysql-test/r/innodb.result 2007/01/24 14:49:34+04:00 holyfoot@mysql.com +0 -2 result fixed mysql-test/r/innodb_gis.result 2007/01/24 14:49:34+04:00 holyfoot@mysql.com +2 -0 result fixed mysql-test/t/innodb.test 2007/01/24 14:49:34+04:00 holyfoot@mysql.com +0 -6 HAVE_GEOMETRY dependent part moved to innodb_gis.test mysql-test/t/innodb_gis.test 2007/01/24 14:49:35+04:00 holyfoot@mysql.com +6 -0 HAVE_GEOMETRY dependent part moved here from innodb.test Revision r1283: Merge changes from MySQL AB: ChangeSet 2007/01/22 18:42:52+02:00 monty@mysql.com Give warnings for unused objects Changed error message to be compatible with old error file Added new error message for new DUP_ENTRY syntax mysql-test/t/innodb.test 2007/01/22 18:42:49+02:00 monty@mysql.com +14 -14 Changed to use new error message Revision r1186: dict_load_foreign(): Use a local variable instead of the 10-bit field foreign->n_fields in order to preserve ON UPDATE CASCADE and ON DELETE CASCADE flags. For some reason, gcc does not warn about shifting a 10-bit field to right by 24 bits. (Bug #24741) This bug was introduced while reducing the memory footprint of the InnoDB data dictionary (Bug #20877). innodb.test, innodb.result: Add a test case. Revision r1318: Add a test case for r1316 (Bug #25927). Revision r1329: Merge changes from MySQL AB to mysql-test directives. The results are not affected. Revision r1340: innodb.test, innodb.result: Add test case for Bug #26835. The bug could be reproduced as follows: Define a table so that the first column of the clustered index is a VARCHAR or a UTF-8 CHAR in a collation where sequences of bytes of differing length are considered equivalent. Insert and delete a record. Before the delete-marked record is purged, insert another record whose first column is of different length but equivalent to the first record. Under certain conditions, the insertion can be incorrectly performed as update-in-place. Likewise, an operation that could be done as update-in-place can unnecessarily be performed as delete and insert, but that would not cause corruption but merely degraded performance. sql/ha_innodb.cc: NULL MERGE this to 5.1 Apply the following InnoDB snapshots: innodb-5.0-ss1319 innodb-5.0-ss1331 innodb-5.0-ss1333 innodb-5.0-ss1341 Revision r1279: branches/5.0: Merge changes from MySQL AB: ChangeSet 2006/11/20 22:42:06+02:00 monty@mysql.com Remove compiler warnings (Mostly in DBUG_PRINT() and unused arguments) Fixed bug in query cache when used with traceing (--with-debug) Fixed memory leak in mysqldump Removed warnings from mysqltest scripts (replaced -- with #) mysql-test/t/innodb.test 2006/11/20 22:41:41+02:00 monty@mysql.com +1 -1 Remove mysqltest warnings sql/ha_innodb.cc 2006/11/20 22:41:51+02:00 monty@mysql.com +2 -2 Fixed compiler warning Revision r1280: branches/5.0: Merge a change from MySQL AB: ChangeSet 2006/11/30 18:25:05+02:00 monty@mysql.com Fixed portability issue in my_thr_init.c (was added in my last push) Fixed compiler warnings (detected by VC++): - Removed not used variables - Added casts - Fixed wrong assignments to bool - Fixed wrong calls with bool arguments - Added missing argument to store(longlong), which caused wrong store method to be called. sql/ha_innodb.cc 2006/11/30 18:24:53+02:00 monty@mysql.com +0 -1 Removed not used variable Revision r1260: branches/5.0: Fix for Bug# 21409. At low transaction isolation levels we let each consistent read set its own snapshot. Revision r1326: branches/5.0: Merge code from MySQL AB: ChangeSet@1.2417.3.1 2007-02-22 16:59:57+02:00 monty@mysql.fi Fixed compiler warnings (for linux and win32 and win64)
Diffstat (limited to 'innobase')
-rw-r--r--innobase/dict/dict0dict.c36
-rw-r--r--innobase/include/rem0rec.ic3
-rw-r--r--innobase/include/sync0sync.ic37
-rw-r--r--innobase/lock/lock0lock.c30
-rw-r--r--innobase/srv/srv0srv.c6
-rw-r--r--innobase/ut/ut0ut.c59
6 files changed, 117 insertions, 54 deletions
diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c
index df48a8a4b5a..33aebb25071 100644
--- a/innobase/dict/dict0dict.c
+++ b/innobase/dict/dict0dict.c
@@ -2139,9 +2139,12 @@ dict_foreign_find_index(
ulint n_cols, /* in: number of columns */
dict_index_t* types_idx, /* in: NULL or an index to whose types the
column types must match */
- ibool check_charsets) /* in: whether to check charsets.
+ ibool check_charsets, /* in: whether to check charsets.
only has an effect if types_idx !=
NULL. */
+ ulint check_null)
+ /* in: nonzero if none of the columns must
+ be declared NOT NULL */
{
#ifndef UNIV_HOTBACKUP
dict_index_t* index;
@@ -2154,10 +2157,11 @@ dict_foreign_find_index(
if (dict_index_get_n_fields(index) >= n_cols) {
for (i = 0; i < n_cols; i++) {
- col_name = dict_index_get_nth_field(index, i)
- ->col->name;
- if (dict_index_get_nth_field(index, i)
- ->prefix_len != 0) {
+ dict_field_t* field
+ = dict_index_get_nth_field(index, i);
+
+ col_name = field->col->name;
+ if (field->prefix_len != 0) {
/* We do not accept column prefix
indexes here */
@@ -2169,6 +2173,13 @@ dict_foreign_find_index(
break;
}
+ if (check_null
+ && (field->col->type.prtype
+ & DATA_NOT_NULL)) {
+
+ return(NULL);
+ }
+
if (types_idx && !cmp_types_are_equal(
dict_index_get_nth_type(index, i),
dict_index_get_nth_type(types_idx, i),
@@ -2290,7 +2301,7 @@ dict_foreign_add_to_cache(
index = dict_foreign_find_index(ref_table,
(const char**) for_in_cache->referenced_col_names,
for_in_cache->n_fields,
- for_in_cache->foreign_index, check_charsets);
+ for_in_cache->foreign_index, check_charsets, FALSE);
if (index == NULL) {
dict_foreign_error_report(ef, for_in_cache,
@@ -2317,13 +2328,17 @@ dict_foreign_add_to_cache(
index = dict_foreign_find_index(for_table,
(const char**) for_in_cache->foreign_col_names,
for_in_cache->n_fields,
- for_in_cache->referenced_index, check_charsets);
+ for_in_cache->referenced_index, check_charsets,
+ for_in_cache->type
+ & (DICT_FOREIGN_ON_DELETE_SET_NULL
+ | DICT_FOREIGN_ON_UPDATE_SET_NULL));
if (index == NULL) {
dict_foreign_error_report(ef, for_in_cache,
"there is no index in the table which would contain\n"
"the columns as the first columns, or the data types in the\n"
-"table do not match to the ones in the referenced table.");
+"table do not match to the ones in the referenced table\n"
+"or one of the ON ... SET NULL columns is declared NOT NULL.");
if (for_in_cache == foreign) {
if (added_to_referenced_list) {
@@ -3125,7 +3140,8 @@ col_loop1:
/* Try to find an index which contains the columns
as the first fields and in the right order */
- index = dict_foreign_find_index(table, column_names, i, NULL, TRUE);
+ index = dict_foreign_find_index(table, column_names, i,
+ NULL, TRUE, FALSE);
if (!index) {
mutex_enter(&dict_foreign_err_mutex);
@@ -3390,7 +3406,7 @@ try_find_index:
if (referenced_table) {
index = dict_foreign_find_index(referenced_table,
- column_names, i, foreign->foreign_index, TRUE);
+ column_names, i, foreign->foreign_index, TRUE, FALSE);
if (!index) {
dict_foreign_free(foreign);
mutex_enter(&dict_foreign_err_mutex);
diff --git a/innobase/include/rem0rec.ic b/innobase/include/rem0rec.ic
index 9c24f385f4f..1abbb503bab 100644
--- a/innobase/include/rem0rec.ic
+++ b/innobase/include/rem0rec.ic
@@ -982,6 +982,9 @@ rec_offs_nth_size(
{
ut_ad(rec_offs_validate(NULL, NULL, offsets));
ut_ad(n < rec_offs_n_fields(offsets));
+ if (!n) {
+ return(rec_offs_base(offsets)[1 + n] & REC_OFFS_MASK);
+ }
return((rec_offs_base(offsets)[1 + n] - rec_offs_base(offsets)[n])
& REC_OFFS_MASK);
}
diff --git a/innobase/include/sync0sync.ic b/innobase/include/sync0sync.ic
index a32a82d6e8b..e5c6f56d8ba 100644
--- a/innobase/include/sync0sync.ic
+++ b/innobase/include/sync0sync.ic
@@ -6,6 +6,16 @@ Mutex, the basic synchronization primitive
Created 9/5/1995 Heikki Tuuri
*******************************************************/
+#if defined(not_defined) && defined(__GNUC__) && defined(UNIV_INTEL_X86)
+/* %z0: Use the size of operand %0 which in our case is *m to determine
+instruction size, it should end up as xchgl. "1" in the input constraint,
+says that "in" has to go in the same place as "out".*/
+#define TAS(m, in, out) \
+ asm volatile ("xchg%z0 %2, %0" \
+ : "=g" (*(m)), "=r" (out) \
+ : "1" (in)) /* Note: "1" here refers to "=r" (out) */
+#endif
+
/**********************************************************************
Sets the waiters field in a mutex. */
@@ -85,20 +95,10 @@ mutex_test_and_set(
return(res);
#elif defined(not_defined) && defined(__GNUC__) && defined(UNIV_INTEL_X86)
- ulint* lw;
ulint res;
- lw = &(mutex->lock_word);
-
- /* In assembly we use the so-called AT & T syntax where
- the order of operands is inverted compared to the ordinary Intel
- syntax. The 'l' after the mnemonics denotes a 32-bit operation.
- The line after the code tells which values come out of the asm
- code, and the second line tells the input to the asm code. */
+ TAS(&mutex->lock_word, 1, res);
- asm volatile("movl $1, %%eax; xchgl (%%ecx), %%eax" :
- "=eax" (res), "=m" (*lw) :
- "ecx" (lw));
return(res);
#else
ibool ret;
@@ -137,20 +137,9 @@ mutex_reset_lock_word(
__asm MOV ECX, lw
__asm XCHG EDX, DWORD PTR [ECX]
#elif defined(not_defined) && defined(__GNUC__) && defined(UNIV_INTEL_X86)
- ulint* lw;
-
- lw = &(mutex->lock_word);
-
- /* In assembly we use the so-called AT & T syntax where
- the order of operands is inverted compared to the ordinary Intel
- syntax. The 'l' after the mnemonics denotes a 32-bit operation. */
+ ulint res;
- asm volatile("movl $0, %%eax; xchgl (%%ecx), %%eax" :
- "=m" (*lw) :
- "ecx" (lw) :
- "eax"); /* gcc does not seem to understand
- that our asm code resets eax: tell it
- explicitly that after the third ':' */
+ TAS(&mutex->lock_word, 0, res);
#else
mutex->lock_word = 0;
diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c
index 06475c8ef7e..77dfca5fdf4 100644
--- a/innobase/lock/lock0lock.c
+++ b/innobase/lock/lock0lock.c
@@ -3259,12 +3259,6 @@ lock_deadlock_recursive(
*cost = *cost + 1;
- if ((depth > LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK)
- || (*cost > LOCK_MAX_N_STEPS_IN_DEADLOCK_CHECK)) {
-
- return(LOCK_VICTIM_IS_START);
- }
-
lock = wait_lock;
if (lock_get_type(wait_lock) == LOCK_REC) {
@@ -3296,11 +3290,18 @@ lock_deadlock_recursive(
if (lock_has_to_wait(wait_lock, lock)) {
+ ibool too_far
+ = depth > LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK
+ || *cost > LOCK_MAX_N_STEPS_IN_DEADLOCK_CHECK;
+
lock_trx = lock->trx;
- if (lock_trx == start) {
+ if (lock_trx == start || too_far) {
+
/* We came back to the recursion starting
- point: a deadlock detected */
+ point: a deadlock detected; or we have
+ searched the waits-for graph too long */
+
FILE* ef = lock_latest_err_file;
rewind(ef);
@@ -3342,9 +3343,20 @@ lock_deadlock_recursive(
}
#ifdef UNIV_DEBUG
if (lock_print_waits) {
- fputs("Deadlock detected\n", stderr);
+ fputs("Deadlock detected"
+ " or too long search\n",
+ stderr);
}
#endif /* UNIV_DEBUG */
+ if (too_far) {
+
+ fputs("TOO DEEP OR LONG SEARCH"
+ " IN THE LOCK TABLE"
+ " WAITS-FOR GRAPH\n", ef);
+
+ return(LOCK_VICTIM_IS_START);
+ }
+
if (ut_dulint_cmp(wait_lock->trx->undo_no,
start->undo_no) >= 0) {
/* Our recursion starting point
diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c
index fe9e08d65be..96c0f05111b 100644
--- a/innobase/srv/srv0srv.c
+++ b/innobase/srv/srv0srv.c
@@ -1822,14 +1822,14 @@ srv_export_innodb_status(void)
export_vars.innodb_pages_written= buf_pool->n_pages_written;
export_vars.innodb_row_lock_waits= srv_n_lock_wait_count;
export_vars.innodb_row_lock_current_waits= srv_n_lock_wait_current_count;
- export_vars.innodb_row_lock_time= srv_n_lock_wait_time / 10000;
+ export_vars.innodb_row_lock_time= srv_n_lock_wait_time / 1000;
if (srv_n_lock_wait_count > 0) {
export_vars.innodb_row_lock_time_avg = (ulint)
- (srv_n_lock_wait_time / 10000 / srv_n_lock_wait_count);
+ (srv_n_lock_wait_time / 1000 / srv_n_lock_wait_count);
} else {
export_vars.innodb_row_lock_time_avg = 0;
}
- export_vars.innodb_row_lock_time_max= srv_n_lock_max_wait_time / 10000;
+ export_vars.innodb_row_lock_time_max= srv_n_lock_max_wait_time / 1000;
export_vars.innodb_rows_read= srv_n_rows_read;
export_vars.innodb_rows_inserted= srv_n_rows_inserted;
export_vars.innodb_rows_updated= srv_n_rows_updated;
diff --git a/innobase/ut/ut0ut.c b/innobase/ut/ut0ut.c
index 1be5939303a..feb03269d91 100644
--- a/innobase/ut/ut0ut.c
+++ b/innobase/ut/ut0ut.c
@@ -20,6 +20,55 @@ Created 5/11/1994 Heikki Tuuri
ibool ut_always_false = FALSE;
+#ifdef __WIN__
+/*********************************************************************
+NOTE: The Windows epoch starts from 1601/01/01 whereas the Unix
+epoch starts from 1970/1/1. For selection of constant see:
+http://support.microsoft.com/kb/167296/ */
+#define WIN_TO_UNIX_DELTA_USEC ((ib_longlong) 11644473600000000ULL)
+
+
+/*********************************************************************
+This is the Windows version of gettimeofday(2).*/
+static
+int
+ut_gettimeofday(
+/*============*/
+ /* out: 0 if all OK else -1 */
+ struct timeval* tv, /* out: Values are relative to Unix epoch */
+ void* tz) /* in: not used */
+{
+ FILETIME ft;
+ ib_longlong tm;
+
+ if (!tv) {
+ errno = EINVAL;
+ return(-1);
+ }
+
+ GetSystemTimeAsFileTime(&ft);
+
+ tm = (ib_longlong) ft.dwHighDateTime << 32;
+ tm |= ft.dwLowDateTime;
+
+ ut_a(tm >= 0); /* If tm wraps over to negative, the quotient / 10
+ does not work */
+
+ tm /= 10; /* Convert from 100 nsec periods to usec */
+
+ /* If we don't convert to the Unix epoch the value for
+ struct timeval::tv_sec will overflow.*/
+ tm -= WIN_TO_UNIX_DELTA_USEC;
+
+ tv->tv_sec = (long) (tm / 1000000L);
+ tv->tv_usec = (long) (tm % 1000000L);
+
+ return(0);
+}
+#else
+#define ut_gettimeofday gettimeofday
+#endif
+
/*********************************************************************
Get the quote character to be used in SQL identifiers.
This definition must match the one in sql/ha_innodb.cc! */
@@ -82,17 +131,11 @@ ut_usectime(
ulint* sec, /* out: seconds since the Epoch */
ulint* ms) /* out: microseconds since the Epoch+*sec */
{
-#ifdef __WIN__
- SYSTEMTIME st;
- GetLocalTime(&st);
- *sec = (ulint) st.wSecond;
- *ms = (ulint) st.wMilliseconds;
-#else
struct timeval tv;
- gettimeofday(&tv,NULL);
+
+ ut_gettimeofday(&tv, NULL);
*sec = (ulint) tv.tv_sec;
*ms = (ulint) tv.tv_usec;
-#endif
}
/**************************************************************