List:Commits« Previous MessageNext Message »
From:Tatiana A. Nurnberg Date:July 10 2008 1:36pm
Subject:bzr push into mysql-6.0 branch (azundris:2705)
View as plain text  
 2705 Tatiana A. Nurnberg	2008-07-10 [merge]
      auto-merge
added:
  mysql-test/suite/bugs/combinations
  mysql-test/suite/bugs/r/rpl_bug37426.result
  mysql-test/suite/bugs/t/rpl_bug37426.test
modified:
  client/mysqltest.c
  mysql-test/extra/rpl_tests/rpl_row_basic.test
  mysql-test/r/mysqltest.result
  mysql-test/suite/binlog/r/binlog_base64_flag.result
  mysql-test/suite/binlog/t/binlog_base64_flag.test
  mysql-test/suite/funcs_2/charset/charset_master.test
  mysql-test/suite/funcs_2/t/innodb_charset.test
  mysql-test/suite/funcs_2/t/memory_charset.test
  mysql-test/suite/funcs_2/t/myisam_charset.test
  mysql-test/suite/funcs_2/t/ndb_charset.test
  mysql-test/suite/parts/inc/partition_check_drop.inc
  mysql-test/suite/parts/inc/partition_layout.inc
  mysql-test/suite/parts/inc/partition_layout_check1.inc
  mysql-test/suite/parts/inc/partition_layout_check2.inc
  mysql-test/suite/parts/r/partition_alter1_1_2_myisam.result
  mysql-test/suite/parts/r/partition_alter1_1_myisam.result
  mysql-test/suite/parts/r/partition_alter1_2_myisam.result
  mysql-test/suite/parts/r/partition_alter2_myisam.result
  mysql-test/suite/parts/r/partition_alter3_innodb.result
  mysql-test/suite/parts/r/partition_alter3_myisam.result
  mysql-test/suite/parts/r/partition_basic_innodb.result
  mysql-test/suite/parts/r/partition_basic_myisam.result
  mysql-test/suite/parts/r/partition_basic_symlink_myisam.result
  mysql-test/suite/parts/r/partition_engine_myisam.result
  mysql-test/suite/parts/r/partition_syntax_myisam.result
  mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result
  mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result
  mysql-test/t/mysqltest.test
  sql/field.cc
  sql/field.h
  sql/rpl_utility.cc
  sql/slave.cc
  sql/slave.h
  sql/sql_insert.cc

=== modified file 'mysql-test/r/func_misc.result'
--- a/mysql-test/r/func_misc.result	2008-06-03 12:10:33 +0000
+++ b/mysql-test/r/func_misc.result	2008-07-10 03:29:11 +0000
@@ -310,6 +310,20 @@ drop table t1;
 SELECT NAME_CONST('var', 'value') COLLATE latin1_general_cs;
 NAME_CONST('var', 'value') COLLATE latin1_general_cs
 value
+select @@session.time_zone into @save_tz;
+set @@session.time_zone='UTC';
+select uuid() into @my_uuid;
+select mid(@my_uuid,15,1);
+mid(@my_uuid,15,1)
+1
+select 24 * 60 * 60 * 1000 * 1000 * 10 into @my_uuid_one_day;
+select concat('0',mid(@my_uuid,16,3),mid(@my_uuid,10,4),left(@my_uuid,8)) into @my_uuidate;
+select floor(conv(@my_uuidate,16,10)/@my_uuid_one_day) into @my_uuid_date;
+select 141427 + datediff(curdate(),'1970-01-01') into @my_uuid_synthetic;
+select @my_uuid_date - @my_uuid_synthetic;
+@my_uuid_date - @my_uuid_synthetic
+0
+set @@session.time_zone=@save_tz;
 End of 5.0 tests
 select connection_id() > 0;
 connection_id() > 0

=== modified file 'mysql-test/t/func_misc.test'
--- a/mysql-test/t/func_misc.test	2008-06-03 12:10:33 +0000
+++ b/mysql-test/t/func_misc.test	2008-07-10 03:29:11 +0000
@@ -426,6 +426,25 @@ drop table t1;
 #
 SELECT NAME_CONST('var', 'value') COLLATE latin1_general_cs;
 
+#
+# Bug #35848: UUID() returns UUIDs with the wrong time
+#
+select @@session.time_zone into @save_tz;
+
+# make sure all times are UTC so the DayNr won't differ
+set @@session.time_zone='UTC';
+select uuid() into @my_uuid;
+# if version nibble isn't 1, the following calculations will be rubbish
+select mid(@my_uuid,15,1);
+select 24 * 60 * 60 * 1000 * 1000 * 10 into @my_uuid_one_day;
+select concat('0',mid(@my_uuid,16,3),mid(@my_uuid,10,4),left(@my_uuid,8)) into @my_uuidate;
+select floor(conv(@my_uuidate,16,10)/@my_uuid_one_day) into @my_uuid_date;
+select 141427 + datediff(curdate(),'1970-01-01') into @my_uuid_synthetic;
+# these should be identical; date part of UUID should be current date
+select @my_uuid_date - @my_uuid_synthetic;
+
+set @@session.time_zone=@save_tz;
+
 --echo End of 5.0 tests
 
 #

=== modified file 'sql/item_strfunc.cc'
--- a/sql/item_strfunc.cc	2008-05-16 09:50:26 +0000
+++ b/sql/item_strfunc.cc	2008-07-10 03:29:11 +0000
@@ -3557,7 +3557,8 @@ static char clock_seq_and_node_str[]="-0
   number of 100-nanosecond intervals between
   1582-10-15 00:00:00.00 and 1970-01-01 00:00:00.00.
 */
-#define UUID_TIME_OFFSET ((ulonglong) 141427 * 24 * 60 * 60 * 1000 * 10 )
+#define UUID_TIME_OFFSET ((ulonglong) 141427 * 24 * 60 * 60 * \
+                          1000 * 1000 * 10)
 
 #define UUID_VERSION      0x1000
 #define UUID_VARIANT      0x8000
@@ -3616,24 +3617,64 @@ String *Item_func_uuid::val_str(String *
     set_clock_seq_str();
   }
 
-  ulonglong tv=my_getsystime() + UUID_TIME_OFFSET + nanoseq;
-  if (unlikely(tv < uuid_time))
-    set_clock_seq_str();
-  else if (unlikely(tv == uuid_time))
+  ulonglong tv= my_getsystime() + UUID_TIME_OFFSET + nanoseq;
+
+  if (likely(tv > uuid_time))
   {
-    /* special protection from low-res system clocks */
-    nanoseq++;
-    tv++;
+    /*
+      Current time is ahead of last timestamp, as it should be.
+      If we "borrowed time", give it back, just as long as we
+      stay ahead of the previous timestamp.
+    */
+    if (nanoseq)
+    {
+      DBUG_ASSERT((tv > uuid_time) && (nanoseq > 0));
+      /*
+        -1 so we won't make tv= uuid_time for nanoseq >= (tv - uuid_time)
+      */
+      long delta= min(nanoseq, tv - uuid_time -1);
+      tv-= delta;
+      nanoseq-= delta;
+    }
   }
   else
   {
-    if (nanoseq)
+    if (unlikely(tv == uuid_time))
     {
-      tv-=nanoseq;
-      nanoseq=0;
+      /*
+        For low-res system clocks. If several requests for UUIDs
+        end up on the same tick, we add a nano-second to make them
+        different.
+        ( current_timestamp + nanoseq * calls_in_this_period )
+        may end up > next_timestamp; this is OK. Nonetheless, we'll
+        try to unwind nanoseq when we get a chance to.
+        If nanoseq overflows, we'll start over with a new numberspace
+        (so the if() below is needed so we can avoid the ++tv and thus
+        match the follow-up if() if nanoseq overflows!).
+      */
+      if (likely(++nanoseq))
+        ++tv;
+    }
+
+    if (unlikely(tv <= uuid_time))
+    {
+      /*
+        If the admin changes the system clock (or due to Daylight
+        Saving Time), the system clock may be turned *back* so we
+        go through a period once more for which we already gave out
+        UUIDs.  To avoid duplicate UUIDs despite potentially identical
+        times, we make a new random component.
+        We also come here if the nanoseq "borrowing" overflows.
+        In either case, we throw away any nanoseq borrowing since it's
+        irrelevant in the new numberspace.
+      */
+      set_clock_seq_str();
+      tv= my_getsystime() + UUID_TIME_OFFSET;
+      nanoseq= 0;
+      DBUG_PRINT("uuid",("making new numberspace"));
     }
-    DBUG_ASSERT(tv > uuid_time);
   }
+
   uuid_time=tv;
   pthread_mutex_unlock(&LOCK_uuid_generator);
 

Thread
bzr push into mysql-6.0 branch (azundris:2705) Tatiana A. Nurnberg10 Jul