Commit 136408b1 authored by Sergey Petrunya's avatar Sergey Petrunya

Bug #899962: materialized subquery with join_cache_level=3

- Make create_tmp_table() set KEY_PART_INFO attributes for the keys it creates.
  This wasn't needed before but is needed now, when temp. tables that are 
  results of SJ-Materialization are being used for joins.
  This particular bug depended on HA_VAR_LENGTH_PART being set,
  but also added code to set HA_BLOB_PART and HA_NULL_PART when appropriate.
parent a85454de
...@@ -955,6 +955,28 @@ pk a b ...@@ -955,6 +955,28 @@ pk a b
set optimizer_switch=@tmp_optimizer_switch; set optimizer_switch=@tmp_optimizer_switch;
set join_cache_level=default; set join_cache_level=default;
DROP TABLE t1,t2,t3,t4; DROP TABLE t1,t2,t3,t4;
#
# Bug #899962: materialized subquery with join_cache_level=3
#
CREATE TABLE t1 (a varchar(1), b varchar(1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES ('v','v');
CREATE TABLE t2 (a varchar(1), b varchar(1)) ENGINE=InnoDB;
INSERT INTO t2 VALUES ('v','v');
set @tmp_optimizer_switch=@@optimizer_switch;
SET optimizer_switch = 'semijoin_with_cache=on';
SET join_cache_level = 3;
EXPLAIN
SELECT * FROM t1 WHERE b IN (SELECT a FROM t2 GROUP BY a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 1 Using where
1 PRIMARY <subquery2> hash_ALL distinct_key #hash#distinct_key 5 test.t1.b 1 Using join buffer (flat, BNLH join)
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 1 Using temporary
SELECT * FROM t1 WHERE b IN (SELECT a FROM t2 GROUP BY a);
a b
v v
set optimizer_switch=@tmp_optimizer_switch;
set join_cache_level=default;
DROP TABLE t1,t2;
set join_cache_level=default; set join_cache_level=default;
show variables like 'join_cache_level'; show variables like 'join_cache_level';
Variable_name Value Variable_name Value
......
...@@ -73,6 +73,30 @@ set join_cache_level=default; ...@@ -73,6 +73,30 @@ set join_cache_level=default;
DROP TABLE t1,t2,t3,t4; DROP TABLE t1,t2,t3,t4;
--echo #
--echo # Bug #899962: materialized subquery with join_cache_level=3
--echo #
CREATE TABLE t1 (a varchar(1), b varchar(1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES ('v','v');
CREATE TABLE t2 (a varchar(1), b varchar(1)) ENGINE=InnoDB;
INSERT INTO t2 VALUES ('v','v');
set @tmp_optimizer_switch=@@optimizer_switch;
SET optimizer_switch = 'semijoin_with_cache=on';
SET join_cache_level = 3;
EXPLAIN
SELECT * FROM t1 WHERE b IN (SELECT a FROM t2 GROUP BY a);
SELECT * FROM t1 WHERE b IN (SELECT a FROM t2 GROUP BY a);
set optimizer_switch=@tmp_optimizer_switch;
set join_cache_level=default;
DROP TABLE t1,t2;
set join_cache_level=default; set join_cache_level=default;
show variables like 'join_cache_level'; show variables like 'join_cache_level';
......
...@@ -13937,10 +13937,22 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields, ...@@ -13937,10 +13937,22 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
key_part_info->store_length= key_part_info->length; key_part_info->store_length= key_part_info->length;
if ((*reg_field)->real_maybe_null()) if ((*reg_field)->real_maybe_null())
{
key_part_info->store_length+= HA_KEY_NULL_LENGTH; key_part_info->store_length+= HA_KEY_NULL_LENGTH;
key_part_info->key_part_flag |= HA_NULL_PART;
}
if ((*reg_field)->type() == MYSQL_TYPE_BLOB ||
(*reg_field)->real_type() == MYSQL_TYPE_VARCHAR ||
(*reg_field)->type() == MYSQL_TYPE_GEOMETRY)
{
if ((*reg_field)->type() == MYSQL_TYPE_BLOB || if ((*reg_field)->type() == MYSQL_TYPE_BLOB ||
(*reg_field)->real_type() == MYSQL_TYPE_VARCHAR) (*reg_field)->type() == MYSQL_TYPE_GEOMETRY)
key_part_info->store_length+= HA_KEY_BLOB_LENGTH; key_part_info->key_part_flag|= HA_BLOB_PART;
else
key_part_info->key_part_flag|= HA_VAR_LENGTH_PART;
key_part_info->store_length+=HA_KEY_BLOB_LENGTH;
}
keyinfo->key_length+= key_part_info->store_length; keyinfo->key_length+= key_part_info->store_length;
......
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