mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Merge
This commit is contained in:
@ -5179,4 +5179,51 @@ a b
|
|||||||
SET SESSION join_cache_level = DEFAULT;
|
SET SESSION join_cache_level = DEFAULT;
|
||||||
SET optimizer_switch=@tmp887479_optimizer_switch;
|
SET optimizer_switch=@tmp887479_optimizer_switch;
|
||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
|
#
|
||||||
|
# Bug #899777: join_cache_level=4 + semijoin=on
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a int, b int, c int, UNIQUE INDEX idx (a));
|
||||||
|
INSERT INTO t1 VALUES (1,8,6), (2,2,8);
|
||||||
|
CREATE TABLE t2 (a int, b int, c int, UNIQUE INDEX idx (a));
|
||||||
|
INSERT INTO t2 VALUES (1,8,6), (2,2,8);
|
||||||
|
CREATE TABLE t3 (a int, b int, c int, UNIQUE INDEX idx (a));
|
||||||
|
INSERT INTO t3 VALUES (1,8,6), (2,2,8);
|
||||||
|
CREATE TABLE t4 (a int, b int, c int, UNIQUE INDEX idx (a));
|
||||||
|
INSERT INTO t4 VALUES (1,8,6), (2,2,8);
|
||||||
|
SET @tmp_optimizer_switch=@@optimizer_switch;
|
||||||
|
SET SESSION optimizer_switch='semijoin=on';
|
||||||
|
SET SESSION optimizer_switch='semijoin_with_cache=on';
|
||||||
|
SET SESSION join_cache_level=1;
|
||||||
|
EXPLAIN
|
||||||
|
SELECT t1.* FROM t1,t2
|
||||||
|
WHERE (t1.b,t2.b) IN (SELECT t3.b,t4.b FROM t3,t4 WHERE t4.c=t3.b)
|
||||||
|
AND t1.a = 1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY t1 const idx idx 5 const 1
|
||||||
|
1 PRIMARY t2 ALL NULL NULL NULL NULL 2
|
||||||
|
1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; Start temporary; Using join buffer (flat, BNL join)
|
||||||
|
1 PRIMARY t4 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
|
||||||
|
SELECT t1.* FROM t1,t2
|
||||||
|
WHERE (t1.b,t2.b) IN (SELECT t3.b,t4.b FROM t3,t4 WHERE t4.c=t3.b)
|
||||||
|
AND t1.a = 1;
|
||||||
|
a b c
|
||||||
|
1 8 6
|
||||||
|
SET SESSION join_cache_level=4;
|
||||||
|
EXPLAIN
|
||||||
|
SELECT t1.* FROM t1,t2
|
||||||
|
WHERE (t1.b,t2.b) IN (SELECT t3.b,t4.b FROM t3,t4 WHERE t4.c=t3.b)
|
||||||
|
AND t1.a = 1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY t1 const idx idx 5 const 1
|
||||||
|
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
|
||||||
|
1 PRIMARY t3 hash_ALL NULL #hash#$hj 5 const 2 Using where; Start temporary; Using join buffer (flat, BNLH join)
|
||||||
|
1 PRIMARY t4 hash_ALL NULL #hash#$hj 10 const,test.t2.b 2 Using where; End temporary; Using join buffer (incremental, BNLH join)
|
||||||
|
SELECT t1.* FROM t1,t2
|
||||||
|
WHERE (t1.b,t2.b) IN (SELECT t3.b,t4.b FROM t3,t4 WHERE t4.c=t3.b)
|
||||||
|
AND t1.a = 1;
|
||||||
|
a b c
|
||||||
|
1 8 6
|
||||||
|
SET SESSION join_cache_level = DEFAULT;
|
||||||
|
SET optimizer_switch=@tmp_optimizer_switch;
|
||||||
|
DROP TABLE t1,t2,t3,t4;
|
||||||
set @@optimizer_switch=@save_optimizer_switch;
|
set @@optimizer_switch=@save_optimizer_switch;
|
||||||
|
@ -3254,5 +3254,45 @@ SET optimizer_switch=@tmp887479_optimizer_switch;
|
|||||||
|
|
||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug #899777: join_cache_level=4 + semijoin=on
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a int, b int, c int, UNIQUE INDEX idx (a));
|
||||||
|
INSERT INTO t1 VALUES (1,8,6), (2,2,8);
|
||||||
|
CREATE TABLE t2 (a int, b int, c int, UNIQUE INDEX idx (a));
|
||||||
|
INSERT INTO t2 VALUES (1,8,6), (2,2,8);
|
||||||
|
CREATE TABLE t3 (a int, b int, c int, UNIQUE INDEX idx (a));
|
||||||
|
INSERT INTO t3 VALUES (1,8,6), (2,2,8);
|
||||||
|
CREATE TABLE t4 (a int, b int, c int, UNIQUE INDEX idx (a));
|
||||||
|
INSERT INTO t4 VALUES (1,8,6), (2,2,8);
|
||||||
|
|
||||||
|
SET @tmp_optimizer_switch=@@optimizer_switch;
|
||||||
|
SET SESSION optimizer_switch='semijoin=on';
|
||||||
|
SET SESSION optimizer_switch='semijoin_with_cache=on';
|
||||||
|
|
||||||
|
SET SESSION join_cache_level=1;
|
||||||
|
EXPLAIN
|
||||||
|
SELECT t1.* FROM t1,t2
|
||||||
|
WHERE (t1.b,t2.b) IN (SELECT t3.b,t4.b FROM t3,t4 WHERE t4.c=t3.b)
|
||||||
|
AND t1.a = 1;
|
||||||
|
SELECT t1.* FROM t1,t2
|
||||||
|
WHERE (t1.b,t2.b) IN (SELECT t3.b,t4.b FROM t3,t4 WHERE t4.c=t3.b)
|
||||||
|
AND t1.a = 1;
|
||||||
|
|
||||||
|
SET SESSION join_cache_level=4;
|
||||||
|
EXPLAIN
|
||||||
|
SELECT t1.* FROM t1,t2
|
||||||
|
WHERE (t1.b,t2.b) IN (SELECT t3.b,t4.b FROM t3,t4 WHERE t4.c=t3.b)
|
||||||
|
AND t1.a = 1;
|
||||||
|
SELECT t1.* FROM t1,t2
|
||||||
|
WHERE (t1.b,t2.b) IN (SELECT t3.b,t4.b FROM t3,t4 WHERE t4.c=t3.b)
|
||||||
|
AND t1.a = 1;
|
||||||
|
|
||||||
|
SET SESSION join_cache_level = DEFAULT;
|
||||||
|
SET optimizer_switch=@tmp_optimizer_switch;
|
||||||
|
|
||||||
|
DROP TABLE t1,t2,t3,t4;
|
||||||
|
|
||||||
# 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;
|
||||||
|
@ -7183,10 +7183,26 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab,
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (!(~used_tables & keyuse->used_tables) &&
|
if (!(~used_tables & keyuse->used_tables))
|
||||||
(first_keyuse || keyuse->keypart != (keyuse-1)->keypart))
|
{
|
||||||
key_parts++;
|
if (first_keyuse)
|
||||||
first_keyuse= FALSE;
|
{
|
||||||
|
key_parts++;
|
||||||
|
first_keyuse= FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
KEYUSE *curr= org_keyuse;
|
||||||
|
for( ; curr < keyuse; curr++)
|
||||||
|
{
|
||||||
|
if (curr->keypart == keyuse->keypart &&
|
||||||
|
!(~used_tables & curr->used_tables))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (curr == keyuse)
|
||||||
|
key_parts++;
|
||||||
|
}
|
||||||
|
}
|
||||||
keyuse++;
|
keyuse++;
|
||||||
} while (keyuse->table == table && keyuse->is_for_hash_join());
|
} while (keyuse->table == table && keyuse->is_for_hash_join());
|
||||||
if (!key_parts)
|
if (!key_parts)
|
||||||
@ -7211,15 +7227,31 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab,
|
|||||||
keyuse= org_keyuse;
|
keyuse= org_keyuse;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (!(~used_tables & keyuse->used_tables) &&
|
if (!(~used_tables & keyuse->used_tables))
|
||||||
(first_keyuse || keyuse->keypart != (keyuse-1)->keypart))
|
|
||||||
{
|
{
|
||||||
Field *field= table->field[keyuse->keypart];
|
bool add_key_part= TRUE;
|
||||||
uint fieldnr= keyuse->keypart+1;
|
if (!first_keyuse)
|
||||||
table->create_key_part_by_field(keyinfo, key_part_info, field, fieldnr);
|
{
|
||||||
first_keyuse= FALSE;
|
for(KEYUSE *curr= org_keyuse; curr < keyuse; curr++)
|
||||||
key_part_info++;
|
{
|
||||||
|
if (curr->keypart == keyuse->keypart &&
|
||||||
|
!(~used_tables & curr->used_tables))
|
||||||
|
{
|
||||||
|
keyuse->keypart= NO_KEYPART;
|
||||||
|
add_key_part= FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (add_key_part)
|
||||||
|
{
|
||||||
|
Field *field= table->field[keyuse->keypart];
|
||||||
|
uint fieldnr= keyuse->keypart+1;
|
||||||
|
table->create_key_part_by_field(keyinfo, key_part_info, field, fieldnr);
|
||||||
|
key_part_info++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
first_keyuse= FALSE;
|
||||||
keyuse++;
|
keyuse++;
|
||||||
} while (keyuse->table == table && keyuse->is_for_hash_join());
|
} while (keyuse->table == table && keyuse->is_for_hash_join());
|
||||||
|
|
||||||
@ -7302,8 +7334,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j,
|
|||||||
{
|
{
|
||||||
if (are_tables_local(j, keyuse->val->used_tables()))
|
if (are_tables_local(j, keyuse->val->used_tables()))
|
||||||
{
|
{
|
||||||
if ((is_hash_join_key_no(key) &&
|
if ((is_hash_join_key_no(key) && keyuse->keypart != NO_KEYPART) ||
|
||||||
(keyparts == 0 || keyuse->keypart != (keyuse-1)->keypart)) ||
|
|
||||||
(!is_hash_join_key_no(key) && keyparts == keyuse->keypart &&
|
(!is_hash_join_key_no(key) && keyparts == keyuse->keypart &&
|
||||||
!(found_part_ref_or_null & keyuse->optimize)))
|
!(found_part_ref_or_null & keyuse->optimize)))
|
||||||
{
|
{
|
||||||
@ -7357,6 +7388,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j,
|
|||||||
for (i=0 ; i < keyparts ; keyuse++,i++)
|
for (i=0 ; i < keyparts ; keyuse++,i++)
|
||||||
{
|
{
|
||||||
while (((~used_tables) & keyuse->used_tables) ||
|
while (((~used_tables) & keyuse->used_tables) ||
|
||||||
|
keyuse->keypart == NO_KEYPART ||
|
||||||
(keyuse->keypart !=
|
(keyuse->keypart !=
|
||||||
(is_hash_join_key_no(key) ?
|
(is_hash_join_key_no(key) ?
|
||||||
keyinfo->key_part[i].field->field_index : i)) ||
|
keyinfo->key_part[i].field->field_index : i)) ||
|
||||||
|
@ -77,6 +77,8 @@ typedef struct keyuse_t {
|
|||||||
bool is_for_hash_join() { return is_hash_join_key_no(key); }
|
bool is_for_hash_join() { return is_hash_join_key_no(key); }
|
||||||
} KEYUSE;
|
} KEYUSE;
|
||||||
|
|
||||||
|
#define NO_KEYPART ((uint)(-1))
|
||||||
|
|
||||||
class store_key;
|
class store_key;
|
||||||
|
|
||||||
const int NO_REF_PART= uint(-1);
|
const int NO_REF_PART= uint(-1);
|
||||||
|
Reference in New Issue
Block a user