BUG#830993: Crash in end_read_record with derived table
- Let join buffering code correctly take into account rowids needed by DuplicateElimination when it is calculating minimum record sizes. - In JOIN_CACHE::write_record_data, added asserts that prevent us from writing beyond the end of the buffer.
This commit is contained in:
parent
528598c478
commit
5673aa41c3
@ -1811,4 +1811,84 @@ a
|
|||||||
0
|
0
|
||||||
DROP TABLE t2, t3, t4, t5;
|
DROP TABLE t2, t3, t4, t5;
|
||||||
set @@optimizer_switch=@tmp834739;
|
set @@optimizer_switch=@tmp834739;
|
||||||
|
#
|
||||||
|
# BUG#830993: Crash in end_read_record with derived table
|
||||||
|
#
|
||||||
|
set @tmp_830993=@@optimizer_switch;
|
||||||
|
set optimizer_switch='semijoin=on,loosescan=off,materialization=off,firstmatch=off';
|
||||||
|
set @tmp_830993_jbs= @@join_buffer_size;
|
||||||
|
set join_buffer_size=160;
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
a int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
b int(11) DEFAULT NULL,
|
||||||
|
c int(11) DEFAULT NULL,
|
||||||
|
d time DEFAULT NULL,
|
||||||
|
e varchar(1) DEFAULT NULL,
|
||||||
|
f varchar(1) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (a),
|
||||||
|
KEY c (c),
|
||||||
|
KEY d (d),
|
||||||
|
KEY e (e,c)
|
||||||
|
);
|
||||||
|
INSERT INTO t1 VALUES (10,NULL,8,'22:55:23','x','x'),
|
||||||
|
(11,8,7,'10:19:31','d','d'),(12,1,1,'14:40:36','r','r'),
|
||||||
|
(13,9,7,'04:37:47','f','f'),(14,4,9,'19:34:06','y','y'),
|
||||||
|
(15,3,NULL,'20:35:33','u','u'),(16,2,1,NULL,'m','m'),
|
||||||
|
(17,NULL,9,'14:43:37',NULL,NULL),(18,2,2,'02:23:09','o','o'),
|
||||||
|
(19,NULL,9,'01:22:45','w','w'),(20,6,2,'00:00:00','m','m'),
|
||||||
|
(21,7,4,'00:13:25','q','q'),(22,2,0,'03:47:16',NULL,NULL),
|
||||||
|
(23,5,4,'01:41:48','d','d'),(24,7,8,'00:00:00','g','g'),
|
||||||
|
(25,6,NULL,'22:32:04','x','x'),(26,6,NULL,'16:44:14','f','f'),
|
||||||
|
(27,2,0,'17:38:37','p','p'),(28,9,NULL,'08:46:48','j','j'),
|
||||||
|
(29,6,8,'14:11:27','c','c');
|
||||||
|
CREATE TABLE t2 like t1;
|
||||||
|
INSERT INTO t2 VALUES (1,2,4,'22:34:09','v','v'),
|
||||||
|
(2,150,62,'14:26:02','v','v'),(3,NULL,7,'14:03:03','c','c'),
|
||||||
|
(4,2,1,'01:46:09',NULL,NULL),(5,5,0,'16:21:18','x','x'),
|
||||||
|
(6,3,7,'18:56:33','i','i'),(7,1,7,NULL,'e','e'),
|
||||||
|
(8,4,1,'09:29:08','p','p'),(9,NULL,7,'19:11:10','s','s'),
|
||||||
|
(10,2,1,'11:57:26','j','j'),(11,6,5,'00:39:46','z','z'),
|
||||||
|
(12,6,2,'03:28:15','c','c'),(13,8,0,'06:44:18','a','a'),
|
||||||
|
(14,2,1,'14:36:39','q','q'),(15,6,8,'18:42:45','y','y'),
|
||||||
|
(16,8,1,'02:57:29',NULL,NULL),(17,3,1,'16:46:13','r','r'),
|
||||||
|
(18,3,9,'19:39:02','v','v'),(19,9,1,NULL,NULL,NULL),
|
||||||
|
(20,6,5,'20:58:33','r','r');
|
||||||
|
explain
|
||||||
|
SELECT
|
||||||
|
alias1.a, alias1.b, alias1.c, alias1.d, alias1.e, alias1.f,
|
||||||
|
alias2.a as a2_a, alias2.b as a2_b, alias2.c as a2_c, alias2.d as a2_d,
|
||||||
|
alias2.e as a2_e, alias2.f as a2_f,
|
||||||
|
t2.a as t2_a, t2.b as t2_b, t2.c as t2_c, t2.d as t2_d, t2.e as t2_e, t2.f as t2_f
|
||||||
|
FROM
|
||||||
|
(SELECT * FROM t2) AS alias1,
|
||||||
|
t1 AS alias2,
|
||||||
|
t2
|
||||||
|
WHERE
|
||||||
|
alias1.c IN (SELECT SQ3_alias1.b
|
||||||
|
FROM t2 AS SQ3_alias1 STRAIGHT_JOIN t2 AS SQ3_alias2)
|
||||||
|
LIMIT 100;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Start temporary
|
||||||
|
1 PRIMARY alias2 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
|
||||||
|
1 PRIMARY t2 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
|
||||||
|
1 PRIMARY SQ3_alias1 ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join)
|
||||||
|
1 PRIMARY SQ3_alias2 index NULL PRIMARY 4 NULL 20 Using index; End temporary; Using join buffer (flat, BNL join)
|
||||||
|
2 DERIVED t2 ALL NULL NULL NULL NULL 20
|
||||||
|
create table t3 as
|
||||||
|
SELECT
|
||||||
|
alias1.a, alias1.b, alias1.c, alias1.d, alias1.e, alias1.f,
|
||||||
|
alias2.a as a2_a, alias2.b as a2_b, alias2.c as a2_c, alias2.d as a2_d,
|
||||||
|
alias2.e as a2_e, alias2.f as a2_f,
|
||||||
|
t2.a as t2_a, t2.b as t2_b, t2.c as t2_c, t2.d as t2_d, t2.e as t2_e, t2.f as t2_f
|
||||||
|
FROM
|
||||||
|
(SELECT * FROM t2) AS alias1,
|
||||||
|
t1 AS alias2,
|
||||||
|
t2
|
||||||
|
WHERE
|
||||||
|
alias1.c IN (SELECT SQ3_alias1.b
|
||||||
|
FROM t2 AS SQ3_alias1 STRAIGHT_JOIN t2 AS SQ3_alias2)
|
||||||
|
LIMIT 100;
|
||||||
|
drop table t1,t2, t3;
|
||||||
|
set optimizer_switch=@tmp_830993;
|
||||||
|
set join_buffer_size= @tmp_830993_jbs;
|
||||||
set optimizer_switch=@subselect_sj_tmp;
|
set optimizer_switch=@subselect_sj_tmp;
|
||||||
|
@ -1822,6 +1822,86 @@ a
|
|||||||
0
|
0
|
||||||
DROP TABLE t2, t3, t4, t5;
|
DROP TABLE t2, t3, t4, t5;
|
||||||
set @@optimizer_switch=@tmp834739;
|
set @@optimizer_switch=@tmp834739;
|
||||||
|
#
|
||||||
|
# BUG#830993: Crash in end_read_record with derived table
|
||||||
|
#
|
||||||
|
set @tmp_830993=@@optimizer_switch;
|
||||||
|
set optimizer_switch='semijoin=on,loosescan=off,materialization=off,firstmatch=off';
|
||||||
|
set @tmp_830993_jbs= @@join_buffer_size;
|
||||||
|
set join_buffer_size=160;
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
a int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
b int(11) DEFAULT NULL,
|
||||||
|
c int(11) DEFAULT NULL,
|
||||||
|
d time DEFAULT NULL,
|
||||||
|
e varchar(1) DEFAULT NULL,
|
||||||
|
f varchar(1) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (a),
|
||||||
|
KEY c (c),
|
||||||
|
KEY d (d),
|
||||||
|
KEY e (e,c)
|
||||||
|
);
|
||||||
|
INSERT INTO t1 VALUES (10,NULL,8,'22:55:23','x','x'),
|
||||||
|
(11,8,7,'10:19:31','d','d'),(12,1,1,'14:40:36','r','r'),
|
||||||
|
(13,9,7,'04:37:47','f','f'),(14,4,9,'19:34:06','y','y'),
|
||||||
|
(15,3,NULL,'20:35:33','u','u'),(16,2,1,NULL,'m','m'),
|
||||||
|
(17,NULL,9,'14:43:37',NULL,NULL),(18,2,2,'02:23:09','o','o'),
|
||||||
|
(19,NULL,9,'01:22:45','w','w'),(20,6,2,'00:00:00','m','m'),
|
||||||
|
(21,7,4,'00:13:25','q','q'),(22,2,0,'03:47:16',NULL,NULL),
|
||||||
|
(23,5,4,'01:41:48','d','d'),(24,7,8,'00:00:00','g','g'),
|
||||||
|
(25,6,NULL,'22:32:04','x','x'),(26,6,NULL,'16:44:14','f','f'),
|
||||||
|
(27,2,0,'17:38:37','p','p'),(28,9,NULL,'08:46:48','j','j'),
|
||||||
|
(29,6,8,'14:11:27','c','c');
|
||||||
|
CREATE TABLE t2 like t1;
|
||||||
|
INSERT INTO t2 VALUES (1,2,4,'22:34:09','v','v'),
|
||||||
|
(2,150,62,'14:26:02','v','v'),(3,NULL,7,'14:03:03','c','c'),
|
||||||
|
(4,2,1,'01:46:09',NULL,NULL),(5,5,0,'16:21:18','x','x'),
|
||||||
|
(6,3,7,'18:56:33','i','i'),(7,1,7,NULL,'e','e'),
|
||||||
|
(8,4,1,'09:29:08','p','p'),(9,NULL,7,'19:11:10','s','s'),
|
||||||
|
(10,2,1,'11:57:26','j','j'),(11,6,5,'00:39:46','z','z'),
|
||||||
|
(12,6,2,'03:28:15','c','c'),(13,8,0,'06:44:18','a','a'),
|
||||||
|
(14,2,1,'14:36:39','q','q'),(15,6,8,'18:42:45','y','y'),
|
||||||
|
(16,8,1,'02:57:29',NULL,NULL),(17,3,1,'16:46:13','r','r'),
|
||||||
|
(18,3,9,'19:39:02','v','v'),(19,9,1,NULL,NULL,NULL),
|
||||||
|
(20,6,5,'20:58:33','r','r');
|
||||||
|
explain
|
||||||
|
SELECT
|
||||||
|
alias1.a, alias1.b, alias1.c, alias1.d, alias1.e, alias1.f,
|
||||||
|
alias2.a as a2_a, alias2.b as a2_b, alias2.c as a2_c, alias2.d as a2_d,
|
||||||
|
alias2.e as a2_e, alias2.f as a2_f,
|
||||||
|
t2.a as t2_a, t2.b as t2_b, t2.c as t2_c, t2.d as t2_d, t2.e as t2_e, t2.f as t2_f
|
||||||
|
FROM
|
||||||
|
(SELECT * FROM t2) AS alias1,
|
||||||
|
t1 AS alias2,
|
||||||
|
t2
|
||||||
|
WHERE
|
||||||
|
alias1.c IN (SELECT SQ3_alias1.b
|
||||||
|
FROM t2 AS SQ3_alias1 STRAIGHT_JOIN t2 AS SQ3_alias2)
|
||||||
|
LIMIT 100;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Start temporary
|
||||||
|
1 PRIMARY alias2 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
|
||||||
|
1 PRIMARY t2 ALL NULL NULL NULL NULL 20 Using join buffer (incremental, BNL join)
|
||||||
|
1 PRIMARY SQ3_alias1 ALL NULL NULL NULL NULL 20 Using where; Using join buffer (incremental, BNL join)
|
||||||
|
1 PRIMARY SQ3_alias2 index NULL PRIMARY 4 NULL 20 Using index; End temporary; Using join buffer (incremental, BNL join)
|
||||||
|
2 DERIVED t2 ALL NULL NULL NULL NULL 20
|
||||||
|
create table t3 as
|
||||||
|
SELECT
|
||||||
|
alias1.a, alias1.b, alias1.c, alias1.d, alias1.e, alias1.f,
|
||||||
|
alias2.a as a2_a, alias2.b as a2_b, alias2.c as a2_c, alias2.d as a2_d,
|
||||||
|
alias2.e as a2_e, alias2.f as a2_f,
|
||||||
|
t2.a as t2_a, t2.b as t2_b, t2.c as t2_c, t2.d as t2_d, t2.e as t2_e, t2.f as t2_f
|
||||||
|
FROM
|
||||||
|
(SELECT * FROM t2) AS alias1,
|
||||||
|
t1 AS alias2,
|
||||||
|
t2
|
||||||
|
WHERE
|
||||||
|
alias1.c IN (SELECT SQ3_alias1.b
|
||||||
|
FROM t2 AS SQ3_alias1 STRAIGHT_JOIN t2 AS SQ3_alias2)
|
||||||
|
LIMIT 100;
|
||||||
|
drop table t1,t2, t3;
|
||||||
|
set optimizer_switch=@tmp_830993;
|
||||||
|
set join_buffer_size= @tmp_830993_jbs;
|
||||||
set optimizer_switch=@subselect_sj_tmp;
|
set optimizer_switch=@subselect_sj_tmp;
|
||||||
#
|
#
|
||||||
# BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off
|
# BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off
|
||||||
|
@ -1642,5 +1642,85 @@ SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AN
|
|||||||
DROP TABLE t2, t3, t4, t5;
|
DROP TABLE t2, t3, t4, t5;
|
||||||
set @@optimizer_switch=@tmp834739;
|
set @@optimizer_switch=@tmp834739;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # BUG#830993: Crash in end_read_record with derived table
|
||||||
|
--echo #
|
||||||
|
set @tmp_830993=@@optimizer_switch;
|
||||||
|
set optimizer_switch='semijoin=on,loosescan=off,materialization=off,firstmatch=off';
|
||||||
|
set @tmp_830993_jbs= @@join_buffer_size;
|
||||||
|
--disable_warnings
|
||||||
|
set join_buffer_size=160;
|
||||||
|
--enable_warnings
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
a int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
b int(11) DEFAULT NULL,
|
||||||
|
c int(11) DEFAULT NULL,
|
||||||
|
d time DEFAULT NULL,
|
||||||
|
e varchar(1) DEFAULT NULL,
|
||||||
|
f varchar(1) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (a),
|
||||||
|
KEY c (c),
|
||||||
|
KEY d (d),
|
||||||
|
KEY e (e,c)
|
||||||
|
);
|
||||||
|
INSERT INTO t1 VALUES (10,NULL,8,'22:55:23','x','x'),
|
||||||
|
(11,8,7,'10:19:31','d','d'),(12,1,1,'14:40:36','r','r'),
|
||||||
|
(13,9,7,'04:37:47','f','f'),(14,4,9,'19:34:06','y','y'),
|
||||||
|
(15,3,NULL,'20:35:33','u','u'),(16,2,1,NULL,'m','m'),
|
||||||
|
(17,NULL,9,'14:43:37',NULL,NULL),(18,2,2,'02:23:09','o','o'),
|
||||||
|
(19,NULL,9,'01:22:45','w','w'),(20,6,2,'00:00:00','m','m'),
|
||||||
|
(21,7,4,'00:13:25','q','q'),(22,2,0,'03:47:16',NULL,NULL),
|
||||||
|
(23,5,4,'01:41:48','d','d'),(24,7,8,'00:00:00','g','g'),
|
||||||
|
(25,6,NULL,'22:32:04','x','x'),(26,6,NULL,'16:44:14','f','f'),
|
||||||
|
(27,2,0,'17:38:37','p','p'),(28,9,NULL,'08:46:48','j','j'),
|
||||||
|
(29,6,8,'14:11:27','c','c');
|
||||||
|
|
||||||
|
CREATE TABLE t2 like t1;
|
||||||
|
INSERT INTO t2 VALUES (1,2,4,'22:34:09','v','v'),
|
||||||
|
(2,150,62,'14:26:02','v','v'),(3,NULL,7,'14:03:03','c','c'),
|
||||||
|
(4,2,1,'01:46:09',NULL,NULL),(5,5,0,'16:21:18','x','x'),
|
||||||
|
(6,3,7,'18:56:33','i','i'),(7,1,7,NULL,'e','e'),
|
||||||
|
(8,4,1,'09:29:08','p','p'),(9,NULL,7,'19:11:10','s','s'),
|
||||||
|
(10,2,1,'11:57:26','j','j'),(11,6,5,'00:39:46','z','z'),
|
||||||
|
(12,6,2,'03:28:15','c','c'),(13,8,0,'06:44:18','a','a'),
|
||||||
|
(14,2,1,'14:36:39','q','q'),(15,6,8,'18:42:45','y','y'),
|
||||||
|
(16,8,1,'02:57:29',NULL,NULL),(17,3,1,'16:46:13','r','r'),
|
||||||
|
(18,3,9,'19:39:02','v','v'),(19,9,1,NULL,NULL,NULL),
|
||||||
|
(20,6,5,'20:58:33','r','r');
|
||||||
|
|
||||||
|
explain
|
||||||
|
SELECT
|
||||||
|
alias1.a, alias1.b, alias1.c, alias1.d, alias1.e, alias1.f,
|
||||||
|
alias2.a as a2_a, alias2.b as a2_b, alias2.c as a2_c, alias2.d as a2_d,
|
||||||
|
alias2.e as a2_e, alias2.f as a2_f,
|
||||||
|
t2.a as t2_a, t2.b as t2_b, t2.c as t2_c, t2.d as t2_d, t2.e as t2_e, t2.f as t2_f
|
||||||
|
FROM
|
||||||
|
(SELECT * FROM t2) AS alias1,
|
||||||
|
t1 AS alias2,
|
||||||
|
t2
|
||||||
|
WHERE
|
||||||
|
alias1.c IN (SELECT SQ3_alias1.b
|
||||||
|
FROM t2 AS SQ3_alias1 STRAIGHT_JOIN t2 AS SQ3_alias2)
|
||||||
|
LIMIT 100;
|
||||||
|
|
||||||
|
create table t3 as
|
||||||
|
SELECT
|
||||||
|
alias1.a, alias1.b, alias1.c, alias1.d, alias1.e, alias1.f,
|
||||||
|
alias2.a as a2_a, alias2.b as a2_b, alias2.c as a2_c, alias2.d as a2_d,
|
||||||
|
alias2.e as a2_e, alias2.f as a2_f,
|
||||||
|
t2.a as t2_a, t2.b as t2_b, t2.c as t2_c, t2.d as t2_d, t2.e as t2_e, t2.f as t2_f
|
||||||
|
FROM
|
||||||
|
(SELECT * FROM t2) AS alias1,
|
||||||
|
t1 AS alias2,
|
||||||
|
t2
|
||||||
|
WHERE
|
||||||
|
alias1.c IN (SELECT SQ3_alias1.b
|
||||||
|
FROM t2 AS SQ3_alias1 STRAIGHT_JOIN t2 AS SQ3_alias2)
|
||||||
|
LIMIT 100;
|
||||||
|
|
||||||
|
drop table t1,t2, t3;
|
||||||
|
set optimizer_switch=@tmp_830993;
|
||||||
|
set join_buffer_size= @tmp_830993_jbs;
|
||||||
|
|
||||||
# The following command must be the last one the file
|
# The following command must be the last one the file
|
||||||
set optimizer_switch=@subselect_sj_tmp;
|
set optimizer_switch=@subselect_sj_tmp;
|
||||||
|
@ -225,8 +225,6 @@ void JOIN_CACHE::calc_record_fields()
|
|||||||
flag_fields+= test(tab->table->maybe_null);
|
flag_fields+= test(tab->table->maybe_null);
|
||||||
fields+= tab->used_fields;
|
fields+= tab->used_fields;
|
||||||
blobs+= tab->used_blobs;
|
blobs+= tab->used_blobs;
|
||||||
|
|
||||||
fields+= tab->check_rowid_field();
|
|
||||||
}
|
}
|
||||||
if ((with_match_flag= join_tab->use_match_flag()))
|
if ((with_match_flag= join_tab->use_match_flag()))
|
||||||
flag_fields++;
|
flag_fields++;
|
||||||
@ -620,7 +618,12 @@ void JOIN_CACHE::create_remaining_fields()
|
|||||||
copy->type= CACHE_ROWID;
|
copy->type= CACHE_ROWID;
|
||||||
copy->field= 0;
|
copy->field= 0;
|
||||||
copy->referenced_field_no= 0;
|
copy->referenced_field_no= 0;
|
||||||
length+= copy->length;
|
/*
|
||||||
|
Note: this may seem odd, but at this point we have
|
||||||
|
table->file->ref==NULL while table->file->ref_length is already set
|
||||||
|
to correct value.
|
||||||
|
*/
|
||||||
|
length += table->file->ref_length;
|
||||||
data_field_count++;
|
data_field_count++;
|
||||||
copy++;
|
copy++;
|
||||||
}
|
}
|
||||||
@ -1297,6 +1300,7 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
|
|||||||
if (with_length)
|
if (with_length)
|
||||||
{
|
{
|
||||||
rec_len_ptr= cp;
|
rec_len_ptr= cp;
|
||||||
|
DBUG_ASSERT(cp + size_of_rec_len <= buff + buff_size);
|
||||||
cp+= size_of_rec_len;
|
cp+= size_of_rec_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1306,6 +1310,7 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
|
|||||||
*/
|
*/
|
||||||
if (prev_cache)
|
if (prev_cache)
|
||||||
{
|
{
|
||||||
|
DBUG_ASSERT(cp + prev_cache->get_size_of_rec_offset() <= buff + buff_size);
|
||||||
cp+= prev_cache->get_size_of_rec_offset();
|
cp+= prev_cache->get_size_of_rec_offset();
|
||||||
prev_cache->store_rec_ref(cp, link);
|
prev_cache->store_rec_ref(cp, link);
|
||||||
}
|
}
|
||||||
@ -1322,6 +1327,7 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
|
|||||||
flags_pos= cp;
|
flags_pos= cp;
|
||||||
for ( ; copy < copy_end; copy++)
|
for ( ; copy < copy_end; copy++)
|
||||||
{
|
{
|
||||||
|
DBUG_ASSERT(cp + copy->length <= buff + buff_size);
|
||||||
memcpy(cp, copy->str, copy->length);
|
memcpy(cp, copy->str, copy->length);
|
||||||
cp+= copy->length;
|
cp+= copy->length;
|
||||||
}
|
}
|
||||||
@ -1348,6 +1354,7 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
|
|||||||
{
|
{
|
||||||
last_rec_blob_data_is_in_rec_buff= 1;
|
last_rec_blob_data_is_in_rec_buff= 1;
|
||||||
/* Put down the length of the blob and the pointer to the data */
|
/* Put down the length of the blob and the pointer to the data */
|
||||||
|
DBUG_ASSERT(cp + copy->length + sizeof(char*) <= buff + buff_size);
|
||||||
blob_field->get_image(cp, copy->length+sizeof(char*),
|
blob_field->get_image(cp, copy->length+sizeof(char*),
|
||||||
blob_field->charset());
|
blob_field->charset());
|
||||||
cp+= copy->length+sizeof(char*);
|
cp+= copy->length+sizeof(char*);
|
||||||
@ -1357,6 +1364,7 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
|
|||||||
/* First put down the length of the blob and then copy the data */
|
/* First put down the length of the blob and then copy the data */
|
||||||
blob_field->get_image(cp, copy->length,
|
blob_field->get_image(cp, copy->length,
|
||||||
blob_field->charset());
|
blob_field->charset());
|
||||||
|
DBUG_ASSERT(cp + copy->length + copy->blob_length <= buff + buff_size);
|
||||||
memcpy(cp+copy->length, copy->str, copy->blob_length);
|
memcpy(cp+copy->length, copy->str, copy->blob_length);
|
||||||
cp+= copy->length+copy->blob_length;
|
cp+= copy->length+copy->blob_length;
|
||||||
}
|
}
|
||||||
@ -1367,12 +1375,14 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
|
|||||||
case CACHE_VARSTR1:
|
case CACHE_VARSTR1:
|
||||||
/* Copy the significant part of the short varstring field */
|
/* Copy the significant part of the short varstring field */
|
||||||
len= (uint) copy->str[0] + 1;
|
len= (uint) copy->str[0] + 1;
|
||||||
|
DBUG_ASSERT(cp + len <= buff + buff_size);
|
||||||
memcpy(cp, copy->str, len);
|
memcpy(cp, copy->str, len);
|
||||||
cp+= len;
|
cp+= len;
|
||||||
break;
|
break;
|
||||||
case CACHE_VARSTR2:
|
case CACHE_VARSTR2:
|
||||||
/* Copy the significant part of the long varstring field */
|
/* Copy the significant part of the long varstring field */
|
||||||
len= uint2korr(copy->str) + 2;
|
len= uint2korr(copy->str) + 2;
|
||||||
|
DBUG_ASSERT(cp + len <= buff + buff_size);
|
||||||
memcpy(cp, copy->str, len);
|
memcpy(cp, copy->str, len);
|
||||||
cp+= len;
|
cp+= len;
|
||||||
break;
|
break;
|
||||||
@ -1387,6 +1397,7 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
|
|||||||
end > str && end[-1] == ' ';
|
end > str && end[-1] == ' ';
|
||||||
end--) ;
|
end--) ;
|
||||||
len=(uint) (end-str);
|
len=(uint) (end-str);
|
||||||
|
DBUG_ASSERT(cp + len + 2 <= buff + buff_size);
|
||||||
int2store(cp, len);
|
int2store(cp, len);
|
||||||
memcpy(cp+2, str, len);
|
memcpy(cp+2, str, len);
|
||||||
cp+= len+2;
|
cp+= len+2;
|
||||||
@ -1406,6 +1417,7 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
|
|||||||
/* fall through */
|
/* fall through */
|
||||||
default:
|
default:
|
||||||
/* Copy the entire image of the field from the record buffer */
|
/* Copy the entire image of the field from the record buffer */
|
||||||
|
DBUG_ASSERT(cp + copy->length <= buff + buff_size);
|
||||||
memcpy(cp, copy->str, copy->length);
|
memcpy(cp, copy->str, copy->length);
|
||||||
cp+= copy->length;
|
cp+= copy->length;
|
||||||
}
|
}
|
||||||
@ -1425,6 +1437,7 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
|
|||||||
cnt++;
|
cnt++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
DBUG_ASSERT(cp + size_of_fld_ofs*cnt <= buff + buff_size);
|
||||||
cp+= size_of_fld_ofs*cnt;
|
cp+= size_of_fld_ofs*cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6572,6 +6572,16 @@ void JOIN_TAB::calc_used_field_length(bool max_fl)
|
|||||||
rec_length+=(table->s->null_fields+7)/8;
|
rec_length+=(table->s->null_fields+7)/8;
|
||||||
if (table->maybe_null)
|
if (table->maybe_null)
|
||||||
rec_length+=sizeof(my_bool);
|
rec_length+=sizeof(my_bool);
|
||||||
|
|
||||||
|
/* Take into account that DuplicateElimination may need to store rowid */
|
||||||
|
uint rowid_add_size= 0;
|
||||||
|
if (keep_current_rowid)
|
||||||
|
{
|
||||||
|
rowid_add_size= table->file->ref_length;
|
||||||
|
rec_length += rowid_add_size;
|
||||||
|
fields++;
|
||||||
|
}
|
||||||
|
|
||||||
if (max_fl)
|
if (max_fl)
|
||||||
{
|
{
|
||||||
// TODO: to improve this estimate for max expected length
|
// TODO: to improve this estimate for max expected length
|
||||||
@ -6585,13 +6595,9 @@ void JOIN_TAB::calc_used_field_length(bool max_fl)
|
|||||||
}
|
}
|
||||||
max_used_fieldlength= rec_length;
|
max_used_fieldlength= rec_length;
|
||||||
}
|
}
|
||||||
else if (table->file->stats.mean_rec_length)
|
else if (table->file->stats.mean_rec_length)
|
||||||
set_if_smaller(rec_length, table->file->stats.mean_rec_length);
|
set_if_smaller(rec_length, table->file->stats.mean_rec_length + rowid_add_size);
|
||||||
|
|
||||||
/*
|
|
||||||
TODO: why we don't count here rowid that we might need to store when
|
|
||||||
using DuplicateElimination?
|
|
||||||
*/
|
|
||||||
used_fields=fields;
|
used_fields=fields;
|
||||||
used_fieldlength=rec_length;
|
used_fieldlength=rec_length;
|
||||||
used_blobs=blobs;
|
used_blobs=blobs;
|
||||||
|
@ -288,7 +288,6 @@ typedef struct st_join_table {
|
|||||||
ulong max_used_fieldlength;
|
ulong max_used_fieldlength;
|
||||||
uint used_blobs;
|
uint used_blobs;
|
||||||
uint used_null_fields;
|
uint used_null_fields;
|
||||||
uint used_rowid_fields;
|
|
||||||
uint used_uneven_bit_fields;
|
uint used_uneven_bit_fields;
|
||||||
enum join_type type;
|
enum join_type type;
|
||||||
bool cached_eq_ref_table,eq_ref_table,not_used_in_distinct;
|
bool cached_eq_ref_table,eq_ref_table,not_used_in_distinct;
|
||||||
@ -387,15 +386,6 @@ typedef struct st_join_table {
|
|||||||
(select->quick->get_type() ==
|
(select->quick->get_type() ==
|
||||||
QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX));
|
QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX));
|
||||||
}
|
}
|
||||||
bool check_rowid_field()
|
|
||||||
{
|
|
||||||
if (keep_current_rowid && !used_rowid_fields)
|
|
||||||
{
|
|
||||||
used_rowid_fields= 1;
|
|
||||||
used_fieldlength+= table->file->ref_length;
|
|
||||||
}
|
|
||||||
return test(used_rowid_fields);
|
|
||||||
}
|
|
||||||
bool is_inner_table_of_semi_join_with_first_match()
|
bool is_inner_table_of_semi_join_with_first_match()
|
||||||
{
|
{
|
||||||
return first_sj_inner_tab != NULL;
|
return first_sj_inner_tab != NULL;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user