List:Commits« Previous MessageNext Message »
From:Vladislav Vaintroub Date:November 20 2009 1:20pm
Subject:bzr commit into mysql-5.1-bugteam branch (vvaintroub:3209)
View as plain text  
#At file:///H:/bzr/mysql-5.1-bugteam/ based on revid:vvaintroub@stripped

 3209 Vladislav Vaintroub	2009-11-20 [merge]
      merge

    modified:
      extra/comp_err.c
      mysql-test/r/range.result
      mysql-test/t/range.test
      sql/item_timefunc.cc
      sql/opt_range.cc
=== modified file 'extra/comp_err.c'
--- a/extra/comp_err.c	2009-02-13 16:41:47 +0000
+++ b/extra/comp_err.c	2009-11-20 10:11:31 +0000
@@ -660,7 +660,7 @@ static ha_checksum checksum_format_speci
       case 'u':
       case 'x':
       case 's':
-        chksum= my_checksum(chksum, start, (uint) (p - start));
+        chksum= my_checksum(chksum, start, (uint) (p + 1 - start));
         start= 0; /* Not in format specifier anymore */
         break;
 
@@ -1030,8 +1030,10 @@ static char *parse_text_line(char *pos)
 {
   int i, nr;
   char *row= pos;
+  size_t len;
   DBUG_ENTER("parse_text_line");
 
+  len= strlen (pos);
   while (*pos)
   {
     if (*pos == '\\')
@@ -1039,11 +1041,11 @@ static char *parse_text_line(char *pos)
       switch (*++pos) {
       case '\\':
       case '"':
-	VOID(strmov(pos - 1, pos));
+	VOID(memmove (pos - 1, pos, len - (row - pos)));
 	break;
       case 'n':
 	pos[-1]= '\n';
-	VOID(strmov(pos, pos + 1));
+	VOID(memmove (pos, pos + 1, len - (row - pos)));
 	break;
       default:
 	if (*pos >= '0' && *pos < '8')
@@ -1053,10 +1055,10 @@ static char *parse_text_line(char *pos)
 	    nr= nr * 8 + (*(pos++) - '0');
 	  pos -= i;
 	  pos[-1]= nr;
-	  VOID(strmov(pos, pos + i));
+	  VOID(memmove (pos, pos + i, len - (row - pos)));
 	}
 	else if (*pos)
-	  VOID(strmov(pos - 1, pos));		/* Remove '\' */
+	  VOID(memmove (pos - 1, pos, len - (row - pos)));		/* Remove '\' */
       }
     }
     else

=== modified file 'mysql-test/r/range.result'
--- a/mysql-test/r/range.result	2009-11-02 12:24:07 +0000
+++ b/mysql-test/r/range.result	2009-11-19 16:26:19 +0000
@@ -1603,4 +1603,21 @@ SELECT str_to_date('', '%Y-%m-%d');
 str_to_date('', '%Y-%m-%d')
 0000-00-00
 DROP TABLE t1, t2;
+#
+# Bug #48665: sql-bench's insert test fails due to wrong result
+#
+CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a));
+INSERT INTO t1 VALUES (0,0), (1,1);
+EXPLAIN 
+SELECT * FROM t1 FORCE INDEX (PRIMARY) 
+WHERE (a>=1 AND a<=2) OR (a>=4 AND a<=5) OR (a>=0 AND a <=10);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+@	@	@	range	@	@	@	@	@	@
+# Should return 2 rows
+SELECT * FROM t1 FORCE INDEX (PRIMARY) 
+WHERE (a>=1 AND a<=2) OR (a>=4 AND a<=5) OR (a>=0 AND a <=10);
+a	b
+0	0
+1	1
+DROP TABLE t1;
 End of 5.1 tests

=== modified file 'mysql-test/t/range.test'
--- a/mysql-test/t/range.test	2009-11-02 12:24:07 +0000
+++ b/mysql-test/t/range.test	2009-11-19 16:26:19 +0000
@@ -1260,4 +1260,25 @@ SELECT str_to_date('', '%Y-%m-%d');
 
 DROP TABLE t1, t2;
 
+
+--echo #
+--echo # Bug #48665: sql-bench's insert test fails due to wrong result
+--echo #
+
+CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a));
+
+INSERT INTO t1 VALUES (0,0), (1,1);
+
+--replace_column 1 @ 2 @ 3 @ 5 @ 6 @ 7 @ 8 @ 9 @ 10 @
+EXPLAIN 
+SELECT * FROM t1 FORCE INDEX (PRIMARY) 
+ WHERE (a>=1 AND a<=2) OR (a>=4 AND a<=5) OR (a>=0 AND a <=10);
+
+--echo # Should return 2 rows
+SELECT * FROM t1 FORCE INDEX (PRIMARY) 
+ WHERE (a>=1 AND a<=2) OR (a>=4 AND a<=5) OR (a>=0 AND a <=10);
+
+DROP TABLE t1;
+
+
 --echo End of 5.1 tests

=== modified file 'sql/item_timefunc.cc'
--- a/sql/item_timefunc.cc	2009-09-23 13:21:29 +0000
+++ b/sql/item_timefunc.cc	2009-11-19 22:49:13 +0000
@@ -386,7 +386,7 @@ static bool extract_date_time(DATE_TIME_
 	if (tmp - val > 6)
 	  tmp= (char*) val + 6;
 	l_time->second_part= (int) my_strtoll10(val, &tmp, &error);
-	frac_part= 6 - (uint) (tmp - val);
+	frac_part= 6 - (int) (tmp - val);
 	if (frac_part > 0)
 	  l_time->second_part*= (ulong) log_10_int[frac_part];
 	val= tmp;
@@ -876,9 +876,9 @@ static bool get_interval_info(const char
       value= value*LL(10) + (longlong) (*str - '0');
     if (transform_msec && i == count - 1) // microseconds always last
     {
-      long msec_length= 6 - (uint) (str - start);
+      int msec_length= 6 - (int)(str - start);
       if (msec_length > 0)
-	value*= (long) log_10_int[msec_length];
+        value*= (long)log_10_int[msec_length];
     }
     values[i]= value;
     while (str != end && !my_isdigit(cs,*str))

=== modified file 'sql/opt_range.cc'
--- a/sql/opt_range.cc	2009-11-02 12:24:07 +0000
+++ b/sql/opt_range.cc	2009-11-19 16:26:19 +0000
@@ -6671,6 +6671,7 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *
     else if ((cmp=tmp->cmp_max_to_min(key2)) < 0)
     {						// Found tmp.max < key2.min
       SEL_ARG *next=tmp->next;
+      /* key1 on the left of key2 non-overlapping */
       if (cmp == -2 && eq_tree(tmp->next_key_part,key2->next_key_part))
       {
 	// Join near ranges like tmp.max < 0 and key2.min >= 0
@@ -6699,6 +6700,7 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *
       int tmp_cmp;
       if ((tmp_cmp=tmp->cmp_min_to_max(key2)) > 0) // if tmp.min > key2.max
       {
+        /* tmp is on the right of key2 non-overlapping */
 	if (tmp_cmp == 2 && eq_tree(tmp->next_key_part,key2->next_key_part))
 	{					// ranges are connected
 	  tmp->copy_min_to_min(key2);
@@ -6733,25 +6735,52 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *
       }
     }
 
-    // tmp.max >= key2.min && tmp.min <= key.max  (overlapping ranges)
+    /* 
+      tmp.min >= key2.min && tmp.min <= key.max  (overlapping ranges)
+      key2.min <= tmp.min <= key2.max 
+    */  
     if (eq_tree(tmp->next_key_part,key2->next_key_part))
     {
       if (tmp->is_same(key2))
       {
+        /* 
+          Found exact match of key2 inside key1. 
+          Use the relevant range in key1.
+        */
 	tmp->merge_flags(key2);			// Copy maybe flags
 	key2->increment_use_count(-1);		// Free not used tree
       }
       else
       {
 	SEL_ARG *last=tmp;
+        SEL_ARG *first=tmp;
+        /* 
+          Find the last range in tmp that overlaps key2 and has the same 
+          condition on the rest of the keyparts.
+        */
 	while (last->next && last->next->cmp_min_to_max(key2) <= 0 &&
 	       eq_tree(last->next->next_key_part,key2->next_key_part))
 	{
+          /*
+            We've found the last overlapping key1 range in last.
+            This means that the ranges between (and including) the 
+            first overlapping range (tmp) and the last overlapping range
+            (last) are fully nested into the current range of key2 
+            and can safely be discarded. We just need the minimum endpoint
+            of the first overlapping range (tmp) so we can compare it with
+            the minimum endpoint of the enclosing key2 range.
+          */
 	  SEL_ARG *save=last;
 	  last=last->next;
 	  key1=key1->tree_delete(save);
 	}
-        last->copy_min(tmp);
+        /*
+          The tmp range (the first overlapping range) could have been discarded
+          by the previous loop. We should re-direct tmp to the new united range 
+          that's taking its place.
+        */
+        tmp= last;
+        last->copy_min(first);
         bool full_range= last->copy_min(key2);
         if (!full_range)
         {


Attachment: [text/bzr-bundle] bzr/vvaintroub@mysql.com-20091120132001-p6an2pcctd6efeks.bundle
Thread
bzr commit into mysql-5.1-bugteam branch (vvaintroub:3209)Vladislav Vaintroub20 Nov