Commit ff3b4245 authored by Vladislav Vaintroub's avatar Vladislav Vaintroub

merge

parents 26a37b36 405c9310
...@@ -660,7 +660,7 @@ static ha_checksum checksum_format_specifier(const char* msg) ...@@ -660,7 +660,7 @@ static ha_checksum checksum_format_specifier(const char* msg)
case 'u': case 'u':
case 'x': case 'x':
case 's': 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 */ start= 0; /* Not in format specifier anymore */
break; break;
...@@ -1030,8 +1030,10 @@ static char *parse_text_line(char *pos) ...@@ -1030,8 +1030,10 @@ static char *parse_text_line(char *pos)
{ {
int i, nr; int i, nr;
char *row= pos; char *row= pos;
size_t len;
DBUG_ENTER("parse_text_line"); DBUG_ENTER("parse_text_line");
len= strlen (pos);
while (*pos) while (*pos)
{ {
if (*pos == '\\') if (*pos == '\\')
...@@ -1039,11 +1041,11 @@ static char *parse_text_line(char *pos) ...@@ -1039,11 +1041,11 @@ static char *parse_text_line(char *pos)
switch (*++pos) { switch (*++pos) {
case '\\': case '\\':
case '"': case '"':
VOID(strmov(pos - 1, pos)); VOID(memmove (pos - 1, pos, len - (row - pos)));
break; break;
case 'n': case 'n':
pos[-1]= '\n'; pos[-1]= '\n';
VOID(strmov(pos, pos + 1)); VOID(memmove (pos, pos + 1, len - (row - pos)));
break; break;
default: default:
if (*pos >= '0' && *pos < '8') if (*pos >= '0' && *pos < '8')
...@@ -1053,10 +1055,10 @@ static char *parse_text_line(char *pos) ...@@ -1053,10 +1055,10 @@ static char *parse_text_line(char *pos)
nr= nr * 8 + (*(pos++) - '0'); nr= nr * 8 + (*(pos++) - '0');
pos -= i; pos -= i;
pos[-1]= nr; pos[-1]= nr;
VOID(strmov(pos, pos + i)); VOID(memmove (pos, pos + i, len - (row - pos)));
} }
else if (*pos) else if (*pos)
VOID(strmov(pos - 1, pos)); /* Remove '\' */ VOID(memmove (pos - 1, pos, len - (row - pos))); /* Remove '\' */
} }
} }
else else
......
...@@ -1603,4 +1603,21 @@ SELECT str_to_date('', '%Y-%m-%d'); ...@@ -1603,4 +1603,21 @@ SELECT str_to_date('', '%Y-%m-%d');
str_to_date('', '%Y-%m-%d') str_to_date('', '%Y-%m-%d')
0000-00-00 0000-00-00
DROP TABLE t1, t2; 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 End of 5.1 tests
...@@ -1260,4 +1260,25 @@ SELECT str_to_date('', '%Y-%m-%d'); ...@@ -1260,4 +1260,25 @@ SELECT str_to_date('', '%Y-%m-%d');
DROP TABLE t1, t2; 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 --echo End of 5.1 tests
...@@ -386,7 +386,7 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, ...@@ -386,7 +386,7 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
if (tmp - val > 6) if (tmp - val > 6)
tmp= (char*) val + 6; tmp= (char*) val + 6;
l_time->second_part= (int) my_strtoll10(val, &tmp, &error); 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) if (frac_part > 0)
l_time->second_part*= (ulong) log_10_int[frac_part]; l_time->second_part*= (ulong) log_10_int[frac_part];
val= tmp; val= tmp;
...@@ -876,9 +876,9 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs, ...@@ -876,9 +876,9 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
value= value*LL(10) + (longlong) (*str - '0'); value= value*LL(10) + (longlong) (*str - '0');
if (transform_msec && i == count - 1) // microseconds always last 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) if (msec_length > 0)
value*= (long) log_10_int[msec_length]; value*= (long)log_10_int[msec_length];
} }
values[i]= value; values[i]= value;
while (str != end && !my_isdigit(cs,*str)) while (str != end && !my_isdigit(cs,*str))
......
...@@ -6671,6 +6671,7 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2) ...@@ -6671,6 +6671,7 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
else if ((cmp=tmp->cmp_max_to_min(key2)) < 0) else if ((cmp=tmp->cmp_max_to_min(key2)) < 0)
{ // Found tmp.max < key2.min { // Found tmp.max < key2.min
SEL_ARG *next=tmp->next; 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)) if (cmp == -2 && eq_tree(tmp->next_key_part,key2->next_key_part))
{ {
// Join near ranges like tmp.max < 0 and key2.min >= 0 // Join near ranges like tmp.max < 0 and key2.min >= 0
...@@ -6699,6 +6700,7 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2) ...@@ -6699,6 +6700,7 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
int tmp_cmp; int tmp_cmp;
if ((tmp_cmp=tmp->cmp_min_to_max(key2)) > 0) // if tmp.min > key2.max 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)) if (tmp_cmp == 2 && eq_tree(tmp->next_key_part,key2->next_key_part))
{ // ranges are connected { // ranges are connected
tmp->copy_min_to_min(key2); tmp->copy_min_to_min(key2);
...@@ -6733,25 +6735,52 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2) ...@@ -6733,25 +6735,52 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
} }
} }
// 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 (eq_tree(tmp->next_key_part,key2->next_key_part))
{ {
if (tmp->is_same(key2)) 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 tmp->merge_flags(key2); // Copy maybe flags
key2->increment_use_count(-1); // Free not used tree key2->increment_use_count(-1); // Free not used tree
} }
else else
{ {
SEL_ARG *last=tmp; 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 && while (last->next && last->next->cmp_min_to_max(key2) <= 0 &&
eq_tree(last->next->next_key_part,key2->next_key_part)) 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; SEL_ARG *save=last;
last=last->next; last=last->next;
key1=key1->tree_delete(save); 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); bool full_range= last->copy_min(key2);
if (!full_range) if (!full_range)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment