Commit d9bbc640 authored by Igor Babaev's avatar Igor Babaev

Fixed LP bug #672551.

Made sure that the function that copy a long varchar field from the record
buffer into a key buffer does not copy bytes after the field value.
parent 24f6a2ec
...@@ -5675,4 +5675,44 @@ f 5 ...@@ -5675,4 +5675,44 @@ f 5
f 5 f 5
SET SESSION join_cache_level = DEFAULT; SET SESSION join_cache_level = DEFAULT;
DROP TABLE t1,t2; DROP TABLE t1,t2;
#
# Bug #672551: hash join over a long varchar field
#
CREATE TABLE t1 (
pk int PRIMARY KEY,
a varchar(512) CHARSET latin1 COLLATE latin1_bin DEFAULT NULL,
INDEX idx (a)
);
INSERT INTO t1 VALUES (2, 'aa'), (5, 'ccccccc'), (3, 'bb');
CREATE TABLE t2(
pk int PRIMARY KEY,
a varchar(512) CHARSET latin1 COLLATE latin1_bin DEFAULT NULL,
INDEX idx (a)
);
INSERT INTO t2 VALUES
(10, 'a'), (20, 'c'), (30, 'aa'), (4, 'bb'),
(11, 'a'), (21, 'c'), (31, 'aa'), (41, 'cc'),
(12, 'a'), (22, 'c'), (32, 'bb'), (42, 'aa');
SELECT * FROM t1,t2 WHERE t2.a=t1.a;
pk a pk a
2 aa 30 aa
2 aa 31 aa
2 aa 42 aa
3 bb 4 bb
3 bb 32 bb
SET SESSION join_cache_level = 4;
EXPLAIN
SELECT * FROM t1,t2 WHERE t2.a=t1.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL idx NULL NULL NULL 3 Using where
1 SIMPLE t2 ref idx idx 515 test.t1.a 2 Using join buffer (flat, BNLH join)
SELECT * FROM t1,t2 WHERE t2.a=t1.a;
pk a pk a
2 aa 30 aa
3 bb 4 bb
2 aa 31 aa
3 bb 32 bb
2 aa 42 aa
SET SESSION join_cache_level = DEFAULT;
DROP TABLE t1,t2;
set @@optimizer_switch=@save_optimizer_switch; set @@optimizer_switch=@save_optimizer_switch;
...@@ -2358,5 +2358,37 @@ SET SESSION join_cache_level = DEFAULT; ...@@ -2358,5 +2358,37 @@ SET SESSION join_cache_level = DEFAULT;
DROP TABLE t1,t2; DROP TABLE t1,t2;
--echo #
--echo # Bug #672551: hash join over a long varchar field
--echo #
CREATE TABLE t1 (
pk int PRIMARY KEY,
a varchar(512) CHARSET latin1 COLLATE latin1_bin DEFAULT NULL,
INDEX idx (a)
);
INSERT INTO t1 VALUES (2, 'aa'), (5, 'ccccccc'), (3, 'bb');
CREATE TABLE t2(
pk int PRIMARY KEY,
a varchar(512) CHARSET latin1 COLLATE latin1_bin DEFAULT NULL,
INDEX idx (a)
);
INSERT INTO t2 VALUES
(10, 'a'), (20, 'c'), (30, 'aa'), (4, 'bb'),
(11, 'a'), (21, 'c'), (31, 'aa'), (41, 'cc'),
(12, 'a'), (22, 'c'), (32, 'bb'), (42, 'aa');
SELECT * FROM t1,t2 WHERE t2.a=t1.a;
SET SESSION join_cache_level = 4;
EXPLAIN
SELECT * FROM t1,t2 WHERE t2.a=t1.a;
SELECT * FROM t1,t2 WHERE t2.a=t1.a;
SET SESSION join_cache_level = DEFAULT;
DROP TABLE t1,t2;
# this must be the last command in the file # this must be the last command in the file
set @@optimizer_switch=@save_optimizer_switch; set @@optimizer_switch=@save_optimizer_switch;
...@@ -449,7 +449,8 @@ static void do_varstring1(Copy_field *copy) ...@@ -449,7 +449,8 @@ static void do_varstring1(Copy_field *copy)
if (length > copy->to_length- 1) if (length > copy->to_length- 1)
{ {
length=copy->to_length - 1; length=copy->to_length - 1;
if (copy->from_field->table->in_use->count_cuted_fields) if (copy->from_field->table->in_use->count_cuted_fields &&
copy->to_field)
copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
WARN_DATA_TRUNCATED, 1); WARN_DATA_TRUNCATED, 1);
} }
...@@ -485,7 +486,8 @@ static void do_varstring2(Copy_field *copy) ...@@ -485,7 +486,8 @@ static void do_varstring2(Copy_field *copy)
if (length > copy->to_length- HA_KEY_BLOB_LENGTH) if (length > copy->to_length- HA_KEY_BLOB_LENGTH)
{ {
length=copy->to_length-HA_KEY_BLOB_LENGTH; length=copy->to_length-HA_KEY_BLOB_LENGTH;
if (copy->from_field->table->in_use->count_cuted_fields) if (copy->from_field->table->in_use->count_cuted_fields &&
copy->to_field)
copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
WARN_DATA_TRUNCATED, 1); WARN_DATA_TRUNCATED, 1);
} }
...@@ -551,6 +553,13 @@ void Copy_field::set(uchar *to,Field *from) ...@@ -551,6 +553,13 @@ void Copy_field::set(uchar *to,Field *from)
else else
{ {
to_null_ptr= 0; // For easy debugging to_null_ptr= 0; // For easy debugging
/* Setup optimal copying for varchar */
if (from->real_type() == MYSQL_TYPE_VARCHAR)
{
do_copy= (((Field_varstring*) from)->length_bytes == 1 ?
do_varstring1 : do_varstring2);
}
else
do_copy= do_field_eq; do_copy= do_field_eq;
} }
} }
...@@ -710,6 +719,10 @@ Copy_field::get_copy_func(Field *to,Field *from) ...@@ -710,6 +719,10 @@ Copy_field::get_copy_func(Field *to,Field *from)
do_varstring1_mb) : do_varstring1_mb) :
(from->charset()->mbmaxlen == 1 ? do_varstring2 : (from->charset()->mbmaxlen == 1 ? do_varstring2 :
do_varstring2_mb)); do_varstring2_mb));
else
return (((Field_varstring*) from)->length_bytes == 1 ?
do_varstring1 : do_varstring2);
} }
else if (to_length < from_length) else if (to_length < from_length)
return (from->charset()->mbmaxlen == 1 ? return (from->charset()->mbmaxlen == 1 ?
......
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