automerge
This commit is contained in:
commit
38cb188e24
@ -4383,6 +4383,34 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||||||
1 PRIMARY C ALL NULL NULL NULL NULL 20 100.00 Using where
|
1 PRIMARY C ALL NULL NULL NULL NULL 20 100.00 Using where
|
||||||
DROP TABLE C;
|
DROP TABLE C;
|
||||||
# End of test for bug#45061.
|
# End of test for bug#45061.
|
||||||
|
#
|
||||||
|
# Bug #46749: Segfault in add_key_fields() with outer subquery level
|
||||||
|
# field references
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
a int,
|
||||||
|
b int,
|
||||||
|
UNIQUE (a), KEY (b)
|
||||||
|
);
|
||||||
|
INSERT INTO t1 VALUES (1,1), (2,1);
|
||||||
|
CREATE TABLE st1 like t1;
|
||||||
|
INSERT INTO st1 VALUES (1,1), (2,1);
|
||||||
|
CREATE TABLE st2 like t1;
|
||||||
|
INSERT INTO st2 VALUES (1,1), (2,1);
|
||||||
|
EXPLAIN
|
||||||
|
SELECT MAX(b), (SELECT COUNT(*) FROM st1,st2 WHERE st2.b <= t1.b)
|
||||||
|
FROM t1
|
||||||
|
WHERE a = 230;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
|
2 DEPENDENT SUBQUERY st1 index NULL a 5 NULL 2 Using index
|
||||||
|
2 DEPENDENT SUBQUERY st2 index b b 5 NULL 2 Using where; Using index; Using join buffer
|
||||||
|
SELECT MAX(b), (SELECT COUNT(*) FROM st1,st2 WHERE st2.b <= t1.b)
|
||||||
|
FROM t1
|
||||||
|
WHERE a = 230;
|
||||||
|
MAX(b) (SELECT COUNT(*) FROM st1,st2 WHERE st2.b <= t1.b)
|
||||||
|
NULL 0
|
||||||
|
DROP TABLE t1, st1, st2;
|
||||||
End of 5.0 tests.
|
End of 5.0 tests.
|
||||||
CREATE TABLE t1 (a INT, b INT);
|
CREATE TABLE t1 (a INT, b INT);
|
||||||
INSERT INTO t1 VALUES (2,22),(1,11),(2,22);
|
INSERT INTO t1 VALUES (2,22),(1,11),(2,22);
|
||||||
|
@ -3336,6 +3336,38 @@ EXPLAIN EXTENDED SELECT * FROM C WHERE `int_key` IN (SELECT `int_nokey`);
|
|||||||
DROP TABLE C;
|
DROP TABLE C;
|
||||||
--echo # End of test for bug#45061.
|
--echo # End of test for bug#45061.
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug #46749: Segfault in add_key_fields() with outer subquery level
|
||||||
|
--echo # field references
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
a int,
|
||||||
|
b int,
|
||||||
|
UNIQUE (a), KEY (b)
|
||||||
|
);
|
||||||
|
INSERT INTO t1 VALUES (1,1), (2,1);
|
||||||
|
|
||||||
|
CREATE TABLE st1 like t1;
|
||||||
|
INSERT INTO st1 VALUES (1,1), (2,1);
|
||||||
|
|
||||||
|
CREATE TABLE st2 like t1;
|
||||||
|
INSERT INTO st2 VALUES (1,1), (2,1);
|
||||||
|
|
||||||
|
# should have "impossible where"
|
||||||
|
EXPLAIN
|
||||||
|
SELECT MAX(b), (SELECT COUNT(*) FROM st1,st2 WHERE st2.b <= t1.b)
|
||||||
|
FROM t1
|
||||||
|
WHERE a = 230;
|
||||||
|
|
||||||
|
# should not crash
|
||||||
|
SELECT MAX(b), (SELECT COUNT(*) FROM st1,st2 WHERE st2.b <= t1.b)
|
||||||
|
FROM t1
|
||||||
|
WHERE a = 230;
|
||||||
|
|
||||||
|
DROP TABLE t1, st1, st2;
|
||||||
|
|
||||||
--echo End of 5.0 tests.
|
--echo End of 5.0 tests.
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -3299,6 +3299,28 @@ add_key_equal_fields(KEY_FIELD **key_fields, uint and_level,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Check if an expression is a non-outer field.
|
||||||
|
|
||||||
|
Checks if an expression is a field and belongs to the current select.
|
||||||
|
|
||||||
|
@param field Item expression to check
|
||||||
|
|
||||||
|
@return boolean
|
||||||
|
@retval TRUE the expression is a local field
|
||||||
|
@retval FALSE it's something else
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline static bool
|
||||||
|
is_local_field (Item *field)
|
||||||
|
{
|
||||||
|
field= field->real_item();
|
||||||
|
return field->type() == Item::FIELD_ITEM &&
|
||||||
|
!((Item_field *)field)->depended_from;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
|
add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
|
||||||
COND *cond, table_map usable_tables,
|
COND *cond, table_map usable_tables,
|
||||||
@ -3374,13 +3396,12 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
|
|||||||
{
|
{
|
||||||
Item **values;
|
Item **values;
|
||||||
// BETWEEN, IN, NE
|
// BETWEEN, IN, NE
|
||||||
if (cond_func->key_item()->real_item()->type() == Item::FIELD_ITEM &&
|
if (is_local_field (cond_func->key_item()) &&
|
||||||
!(cond_func->used_tables() & OUTER_REF_TABLE_BIT))
|
!(cond_func->used_tables() & OUTER_REF_TABLE_BIT))
|
||||||
{
|
{
|
||||||
values= cond_func->arguments()+1;
|
values= cond_func->arguments()+1;
|
||||||
if (cond_func->functype() == Item_func::NE_FUNC &&
|
if (cond_func->functype() == Item_func::NE_FUNC &&
|
||||||
cond_func->arguments()[1]->real_item()->type() == Item::FIELD_ITEM &&
|
is_local_field (cond_func->arguments()[1]))
|
||||||
!(cond_func->arguments()[0]->used_tables() & OUTER_REF_TABLE_BIT))
|
|
||||||
values--;
|
values--;
|
||||||
DBUG_ASSERT(cond_func->functype() != Item_func::IN_FUNC ||
|
DBUG_ASSERT(cond_func->functype() != Item_func::IN_FUNC ||
|
||||||
cond_func->argument_count() != 2);
|
cond_func->argument_count() != 2);
|
||||||
@ -3396,9 +3417,7 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
|
|||||||
for (uint i= 1 ; i < cond_func->argument_count() ; i++)
|
for (uint i= 1 ; i < cond_func->argument_count() ; i++)
|
||||||
{
|
{
|
||||||
Item_field *field_item;
|
Item_field *field_item;
|
||||||
if (cond_func->arguments()[i]->real_item()->type() == Item::FIELD_ITEM
|
if (is_local_field (cond_func->arguments()[i]))
|
||||||
&&
|
|
||||||
!(cond_func->arguments()[i]->used_tables() & OUTER_REF_TABLE_BIT))
|
|
||||||
{
|
{
|
||||||
field_item= (Item_field *) (cond_func->arguments()[i]->real_item());
|
field_item= (Item_field *) (cond_func->arguments()[i]->real_item());
|
||||||
add_key_equal_fields(key_fields, *and_level, cond_func,
|
add_key_equal_fields(key_fields, *and_level, cond_func,
|
||||||
@ -3414,8 +3433,7 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
|
|||||||
bool equal_func=(cond_func->functype() == Item_func::EQ_FUNC ||
|
bool equal_func=(cond_func->functype() == Item_func::EQ_FUNC ||
|
||||||
cond_func->functype() == Item_func::EQUAL_FUNC);
|
cond_func->functype() == Item_func::EQUAL_FUNC);
|
||||||
|
|
||||||
if (cond_func->arguments()[0]->real_item()->type() == Item::FIELD_ITEM &&
|
if (is_local_field (cond_func->arguments()[0]))
|
||||||
!(cond_func->arguments()[0]->used_tables() & OUTER_REF_TABLE_BIT))
|
|
||||||
{
|
{
|
||||||
add_key_equal_fields(key_fields, *and_level, cond_func,
|
add_key_equal_fields(key_fields, *and_level, cond_func,
|
||||||
(Item_field*) (cond_func->arguments()[0])->real_item(),
|
(Item_field*) (cond_func->arguments()[0])->real_item(),
|
||||||
@ -3423,9 +3441,8 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
|
|||||||
cond_func->arguments()+1, 1, usable_tables,
|
cond_func->arguments()+1, 1, usable_tables,
|
||||||
sargables);
|
sargables);
|
||||||
}
|
}
|
||||||
if (cond_func->arguments()[1]->real_item()->type() == Item::FIELD_ITEM &&
|
if (is_local_field (cond_func->arguments()[1]) &&
|
||||||
cond_func->functype() != Item_func::LIKE_FUNC &&
|
cond_func->functype() != Item_func::LIKE_FUNC)
|
||||||
!(cond_func->arguments()[1]->used_tables() & OUTER_REF_TABLE_BIT))
|
|
||||||
{
|
{
|
||||||
add_key_equal_fields(key_fields, *and_level, cond_func,
|
add_key_equal_fields(key_fields, *and_level, cond_func,
|
||||||
(Item_field*) (cond_func->arguments()[1])->real_item(),
|
(Item_field*) (cond_func->arguments()[1])->real_item(),
|
||||||
@ -3437,7 +3454,7 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
|
|||||||
}
|
}
|
||||||
case Item_func::OPTIMIZE_NULL:
|
case Item_func::OPTIMIZE_NULL:
|
||||||
/* column_name IS [NOT] NULL */
|
/* column_name IS [NOT] NULL */
|
||||||
if (cond_func->arguments()[0]->real_item()->type() == Item::FIELD_ITEM &&
|
if (is_local_field (cond_func->arguments()[0]) &&
|
||||||
!(cond_func->used_tables() & OUTER_REF_TABLE_BIT))
|
!(cond_func->used_tables() & OUTER_REF_TABLE_BIT))
|
||||||
{
|
{
|
||||||
Item *tmp=new Item_null;
|
Item *tmp=new Item_null;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user