Merge
This commit is contained in:
commit
752d5d022d
@ -5155,7 +5155,7 @@ a b c
|
|||||||
8 8 8
|
8 8 8
|
||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
#
|
#
|
||||||
# Bug mdev-4413: another manifestations of bug mdev-2474
|
# Bug mdev-4413: another manifestations of bug mdev-4274
|
||||||
# (valgrind complains)
|
# (valgrind complains)
|
||||||
#
|
#
|
||||||
CREATE TABLE t1 (a int, b int) ENGINE=MyISAM;
|
CREATE TABLE t1 (a int, b int) ENGINE=MyISAM;
|
||||||
@ -5167,4 +5167,54 @@ WHERE c = a AND
|
|||||||
( 0 OR ( b BETWEEN 45 AND 300 OR a > 45 AND a < 100 ) AND b = c );
|
( 0 OR ( b BETWEEN 45 AND 300 OR a > 45 AND a < 100 ) AND b = c );
|
||||||
a b c
|
a b c
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
#
|
||||||
|
# Bug mdev-4355: equalities from the result of simplification of OR
|
||||||
|
# are not propagated to lower AND levels
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM;
|
||||||
|
INSERT INTO t1 VALUES (1,101),(2,102),(3,103),(4,104),(5,11);
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE (1 != 1 OR a = 5) AND (b != 1 OR a = 1);
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` = 5) and (`test`.`t1`.`b` <> 1))
|
||||||
|
SELECT * FROM t1 WHERE (1 != 1 OR a = 5) AND (b != 1 OR a = 1);
|
||||||
|
a b
|
||||||
|
5 11
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (1 != 1 OR a = 5);
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` = 5) and (`test`.`t1`.`b` <> 1))
|
||||||
|
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (1 != 1 OR a = 5);
|
||||||
|
a b
|
||||||
|
5 11
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (a = 5 OR 1 != 1);
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` = 5) and (`test`.`t1`.`b` <> 1))
|
||||||
|
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (a = 5 OR 1 != 1);
|
||||||
|
a b
|
||||||
|
5 11
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE (b = 1 OR a = 1) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where 0
|
||||||
|
SELECT * FROM t1 WHERE (b = 1 OR a = 1) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||||
|
a b
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE (b = 1 OR a = 5) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`b` = 5) and (`test`.`t1`.`a` = 5))
|
||||||
|
SELECT * FROM t1 WHERE (b = 1 OR a = 5) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||||
|
a b
|
||||||
|
DROP TABLE t1;
|
||||||
End of 5.3 tests
|
End of 5.3 tests
|
||||||
|
@ -5166,7 +5166,7 @@ a b c
|
|||||||
8 8 8
|
8 8 8
|
||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
#
|
#
|
||||||
# Bug mdev-4413: another manifestations of bug mdev-2474
|
# Bug mdev-4413: another manifestations of bug mdev-4274
|
||||||
# (valgrind complains)
|
# (valgrind complains)
|
||||||
#
|
#
|
||||||
CREATE TABLE t1 (a int, b int) ENGINE=MyISAM;
|
CREATE TABLE t1 (a int, b int) ENGINE=MyISAM;
|
||||||
@ -5178,6 +5178,56 @@ WHERE c = a AND
|
|||||||
( 0 OR ( b BETWEEN 45 AND 300 OR a > 45 AND a < 100 ) AND b = c );
|
( 0 OR ( b BETWEEN 45 AND 300 OR a > 45 AND a < 100 ) AND b = c );
|
||||||
a b c
|
a b c
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
#
|
||||||
|
# Bug mdev-4355: equalities from the result of simplification of OR
|
||||||
|
# are not propagated to lower AND levels
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM;
|
||||||
|
INSERT INTO t1 VALUES (1,101),(2,102),(3,103),(4,104),(5,11);
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE (1 != 1 OR a = 5) AND (b != 1 OR a = 1);
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` = 5) and (`test`.`t1`.`b` <> 1))
|
||||||
|
SELECT * FROM t1 WHERE (1 != 1 OR a = 5) AND (b != 1 OR a = 1);
|
||||||
|
a b
|
||||||
|
5 11
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (1 != 1 OR a = 5);
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` = 5) and (`test`.`t1`.`b` <> 1))
|
||||||
|
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (1 != 1 OR a = 5);
|
||||||
|
a b
|
||||||
|
5 11
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (a = 5 OR 1 != 1);
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` = 5) and (`test`.`t1`.`b` <> 1))
|
||||||
|
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (a = 5 OR 1 != 1);
|
||||||
|
a b
|
||||||
|
5 11
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE (b = 1 OR a = 1) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where 0
|
||||||
|
SELECT * FROM t1 WHERE (b = 1 OR a = 1) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||||
|
a b
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE (b = 1 OR a = 5) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`b` = 5) and (`test`.`t1`.`a` = 5))
|
||||||
|
SELECT * FROM t1 WHERE (b = 1 OR a = 5) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||||
|
a b
|
||||||
|
DROP TABLE t1;
|
||||||
End of 5.3 tests
|
End of 5.3 tests
|
||||||
set join_cache_level=default;
|
set join_cache_level=default;
|
||||||
show variables like 'join_cache_level';
|
show variables like 'join_cache_level';
|
||||||
|
@ -5155,7 +5155,7 @@ a b c
|
|||||||
8 8 8
|
8 8 8
|
||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
#
|
#
|
||||||
# Bug mdev-4413: another manifestations of bug mdev-2474
|
# Bug mdev-4413: another manifestations of bug mdev-4274
|
||||||
# (valgrind complains)
|
# (valgrind complains)
|
||||||
#
|
#
|
||||||
CREATE TABLE t1 (a int, b int) ENGINE=MyISAM;
|
CREATE TABLE t1 (a int, b int) ENGINE=MyISAM;
|
||||||
@ -5167,4 +5167,54 @@ WHERE c = a AND
|
|||||||
( 0 OR ( b BETWEEN 45 AND 300 OR a > 45 AND a < 100 ) AND b = c );
|
( 0 OR ( b BETWEEN 45 AND 300 OR a > 45 AND a < 100 ) AND b = c );
|
||||||
a b c
|
a b c
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
#
|
||||||
|
# Bug mdev-4355: equalities from the result of simplification of OR
|
||||||
|
# are not propagated to lower AND levels
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM;
|
||||||
|
INSERT INTO t1 VALUES (1,101),(2,102),(3,103),(4,104),(5,11);
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE (1 != 1 OR a = 5) AND (b != 1 OR a = 1);
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` = 5) and (`test`.`t1`.`b` <> 1))
|
||||||
|
SELECT * FROM t1 WHERE (1 != 1 OR a = 5) AND (b != 1 OR a = 1);
|
||||||
|
a b
|
||||||
|
5 11
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (1 != 1 OR a = 5);
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` = 5) and (`test`.`t1`.`b` <> 1))
|
||||||
|
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (1 != 1 OR a = 5);
|
||||||
|
a b
|
||||||
|
5 11
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (a = 5 OR 1 != 1);
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` = 5) and (`test`.`t1`.`b` <> 1))
|
||||||
|
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (a = 5 OR 1 != 1);
|
||||||
|
a b
|
||||||
|
5 11
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE (b = 1 OR a = 1) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where 0
|
||||||
|
SELECT * FROM t1 WHERE (b = 1 OR a = 1) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||||
|
a b
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE (b = 1 OR a = 5) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`b` = 5) and (`test`.`t1`.`a` = 5))
|
||||||
|
SELECT * FROM t1 WHERE (b = 1 OR a = 5) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||||
|
a b
|
||||||
|
DROP TABLE t1;
|
||||||
End of 5.3 tests
|
End of 5.3 tests
|
||||||
|
@ -1380,7 +1380,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||||||
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 100.00 Using where
|
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||||
2 MATERIALIZED t3 hash_ALL NULL #hash#$hj 5 test.t2.i2 3 100.00 Using where; Using join buffer (flat, BNLH join)
|
2 MATERIALIZED t3 hash_ALL NULL #hash#$hj 5 test.t2.i2 3 100.00 Using where; Using join buffer (flat, BNLH join)
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select `test`.`t1`.`i1` AS `i1` from `test`.`t1` semi join (`test`.`t2` join `test`.`t3`) where ((`test`.`t3`.`i3` = `test`.`t2`.`i2`) and (`test`.`t1`.`i1` = `test`.`t2`.`i2`) and (`test`.`t2`.`i2` > 0))
|
Note 1003 select `test`.`t1`.`i1` AS `i1` from `test`.`t1` semi join (`test`.`t2` join `test`.`t3`) where ((`test`.`t3`.`i3` = `test`.`t2`.`i2`) and (`test`.`t1`.`i1` = `test`.`t2`.`i2`) and (`test`.`t3`.`i3` > 0))
|
||||||
SELECT * FROM t1
|
SELECT * FROM t1
|
||||||
WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 > 0 AND i3 = i2 OR 1=2);
|
WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 > 0 AND i3 = i2 OR 1=2);
|
||||||
i1
|
i1
|
||||||
|
@ -4326,7 +4326,7 @@ SELECT * FROM t1 INNER JOIN t2 ON ( c = a )
|
|||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # Bug mdev-4413: another manifestations of bug mdev-2474
|
--echo # Bug mdev-4413: another manifestations of bug mdev-4274
|
||||||
--echo # (valgrind complains)
|
--echo # (valgrind complains)
|
||||||
--echo #
|
--echo #
|
||||||
|
|
||||||
@ -4342,4 +4342,34 @@ SELECT * FROM t1, t2
|
|||||||
|
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug mdev-4355: equalities from the result of simplification of OR
|
||||||
|
--echo # are not propagated to lower AND levels
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM;
|
||||||
|
INSERT INTO t1 VALUES (1,101),(2,102),(3,103),(4,104),(5,11);
|
||||||
|
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE (1 != 1 OR a = 5) AND (b != 1 OR a = 1);
|
||||||
|
SELECT * FROM t1 WHERE (1 != 1 OR a = 5) AND (b != 1 OR a = 1);
|
||||||
|
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (1 != 1 OR a = 5);
|
||||||
|
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (1 != 1 OR a = 5);
|
||||||
|
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (a = 5 OR 1 != 1);
|
||||||
|
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (a = 5 OR 1 != 1);
|
||||||
|
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE (b = 1 OR a = 1) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||||
|
SELECT * FROM t1 WHERE (b = 1 OR a = 1) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||||
|
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE (b = 1 OR a = 5) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||||
|
SELECT * FROM t1 WHERE (b = 1 OR a = 5) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
--echo End of 5.3 tests
|
--echo End of 5.3 tests
|
||||||
|
@ -5608,10 +5608,12 @@ void Item_equal::merge(Item_equal *item)
|
|||||||
@brief
|
@brief
|
||||||
Merge members of another Item_equal object into this one
|
Merge members of another Item_equal object into this one
|
||||||
|
|
||||||
@param item multiple equality whose members are to be merged
|
@param item multiple equality whose members are to be merged
|
||||||
|
@param save_merged keep the list of equalities in 'item' intact
|
||||||
|
(e.g. for other merges)
|
||||||
|
|
||||||
@details
|
@details
|
||||||
If the Item_equal 'item' happened to have some elements of the list
|
If the Item_equal 'item' happens to have some elements of the list
|
||||||
of equal items belonging to 'this' object then the function merges
|
of equal items belonging to 'this' object then the function merges
|
||||||
the equal items from 'item' into this list.
|
the equal items from 'item' into this list.
|
||||||
If both lists contains constants and they are different then
|
If both lists contains constants and they are different then
|
||||||
@ -5626,24 +5628,45 @@ void Item_equal::merge(Item_equal *item)
|
|||||||
The method 'merge' just joins the list of equal items belonging to 'item'
|
The method 'merge' just joins the list of equal items belonging to 'item'
|
||||||
to the list of equal items belonging to this object assuming that the lists
|
to the list of equal items belonging to this object assuming that the lists
|
||||||
are disjoint. It would be more correct to call the method 'join'.
|
are disjoint. It would be more correct to call the method 'join'.
|
||||||
The method 'merge_with_check' really merges two lists of equal items if they
|
The method 'merge_into_with_check' really merges two lists of equal items if
|
||||||
have common members.
|
they have common members.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool Item_equal::merge_with_check(Item_equal *item)
|
bool Item_equal::merge_with_check(Item_equal *item, bool save_merged)
|
||||||
{
|
{
|
||||||
bool intersected= FALSE;
|
bool intersected= FALSE;
|
||||||
Item_equal_fields_iterator_slow fi(*this);
|
Item_equal_fields_iterator_slow fi(*item);
|
||||||
|
|
||||||
while (fi++)
|
while (fi++)
|
||||||
{
|
{
|
||||||
if (item->contains(fi.get_curr_field()))
|
if (contains(fi.get_curr_field()))
|
||||||
{
|
{
|
||||||
fi.remove();
|
|
||||||
intersected= TRUE;
|
intersected= TRUE;
|
||||||
|
if (!save_merged)
|
||||||
|
fi.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (intersected)
|
if (intersected)
|
||||||
item->merge(this);
|
{
|
||||||
|
if (!save_merged)
|
||||||
|
merge(item);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Item *c= item->get_const();
|
||||||
|
if (c)
|
||||||
|
add_const(c);
|
||||||
|
if (!cond_false)
|
||||||
|
{
|
||||||
|
Item *item;
|
||||||
|
fi.rewind();
|
||||||
|
while ((item= fi++))
|
||||||
|
{
|
||||||
|
if (!contains(fi.get_curr_field()))
|
||||||
|
add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return intersected;
|
return intersected;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5652,17 +5675,25 @@ bool Item_equal::merge_with_check(Item_equal *item)
|
|||||||
@brief
|
@brief
|
||||||
Merge this object into a list of Item_equal objects
|
Merge this object into a list of Item_equal objects
|
||||||
|
|
||||||
@param list the list of Item_equal objects to merge into
|
@param list the list of Item_equal objects to merge into
|
||||||
|
@param save_merged keep the list of equalities in 'this' intact
|
||||||
|
(e.g. for other merges)
|
||||||
|
@param only_intersected do not merge if there are no common members
|
||||||
|
in any of Item_equal objects from the list
|
||||||
|
and this Item_equal
|
||||||
|
|
||||||
@details
|
@details
|
||||||
If the list of equal items from 'this' object contains common members
|
If the list of equal items from 'this' object contains common members
|
||||||
with the lists of equal items belonging to Item_equal objects from 'list'
|
with the lists of equal items belonging to Item_equal objects from 'list'
|
||||||
then all involved Item_equal objects e1,...,ek are merged into one
|
then all involved Item_equal objects e1,...,ek are merged into one
|
||||||
Item equal that replaces e1,...,ek in the 'list'. Otherwise this
|
Item equal that replaces e1,...,ek in the 'list'. Otherwise, in the case
|
||||||
|
when the value of the parameter only_if_intersected is false, this
|
||||||
Item_equal is joined to the 'list'.
|
Item_equal is joined to the 'list'.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Item_equal::merge_into_list(List<Item_equal> *list)
|
void Item_equal::merge_into_list(List<Item_equal> *list,
|
||||||
|
bool save_merged,
|
||||||
|
bool only_intersected)
|
||||||
{
|
{
|
||||||
Item_equal *item;
|
Item_equal *item;
|
||||||
List_iterator<Item_equal> it(*list);
|
List_iterator<Item_equal> it(*list);
|
||||||
@ -5671,16 +5702,16 @@ void Item_equal::merge_into_list(List<Item_equal> *list)
|
|||||||
{
|
{
|
||||||
if (!merge_into)
|
if (!merge_into)
|
||||||
{
|
{
|
||||||
if (merge_with_check(item))
|
if (item->merge_with_check(this, save_merged))
|
||||||
merge_into= item;
|
merge_into= item;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (item->merge_with_check(merge_into))
|
if (merge_into->merge_with_check(item, false))
|
||||||
it.remove();
|
it.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!merge_into)
|
if (!only_intersected && !merge_into)
|
||||||
list->push_back(this);
|
list->push_back(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1761,8 +1761,9 @@ public:
|
|||||||
/** Get number of field items / references to field items in this object */
|
/** Get number of field items / references to field items in this object */
|
||||||
uint n_field_items() { return equal_items.elements-test(with_const); }
|
uint n_field_items() { return equal_items.elements-test(with_const); }
|
||||||
void merge(Item_equal *item);
|
void merge(Item_equal *item);
|
||||||
bool merge_with_check(Item_equal *equal_item);
|
bool merge_with_check(Item_equal *equal_item, bool save_merged);
|
||||||
void merge_into_list(List<Item_equal> *list);
|
void merge_into_list(List<Item_equal> *list, bool save_merged,
|
||||||
|
bool only_intersected);
|
||||||
void update_const();
|
void update_const();
|
||||||
enum Functype functype() const { return MULT_EQUAL_FUNC; }
|
enum Functype functype() const { return MULT_EQUAL_FUNC; }
|
||||||
longlong val_int();
|
longlong val_int();
|
||||||
|
@ -13133,14 +13133,175 @@ optimize_cond(JOIN *join, COND *conds,
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Remove const and eq items.
|
@brief
|
||||||
|
Propagate multiple equalities to the sub-expressions of a condition
|
||||||
|
|
||||||
|
@param thd thread handle
|
||||||
|
@param cond the condition where equalities are to be propagated
|
||||||
|
@param *new_equalities the multiple equalities to be propagated
|
||||||
|
@param inherited path to all inherited multiple equality items
|
||||||
|
@param[out] is_simplifiable_cond 'cond' may be simplified after the
|
||||||
|
propagation of the equalities
|
||||||
|
|
||||||
|
@details
|
||||||
|
The function recursively traverses the tree of the condition 'cond' and
|
||||||
|
for each its AND sub-level of any depth the function merges the multiple
|
||||||
|
equalities from the list 'new_equalities' into the multiple equalities
|
||||||
|
attached to the AND item created for this sub-level.
|
||||||
|
The function also [re]sets references to the equalities formed by the
|
||||||
|
merges of multiple equalities in all field items occurred in 'cond'
|
||||||
|
that are encountered in the equalities.
|
||||||
|
If the result of any merge of multiple equalities is an impossible
|
||||||
|
condition the function returns TRUE in the parameter is_simplifiable_cond.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void propagate_new_equalities(THD *thd, Item *cond,
|
||||||
|
List<Item_equal> *new_equalities,
|
||||||
|
COND_EQUAL *inherited,
|
||||||
|
bool *is_simplifiable_cond)
|
||||||
|
{
|
||||||
|
if (cond->type() == Item::COND_ITEM)
|
||||||
|
{
|
||||||
|
bool and_level= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC;
|
||||||
|
if (and_level)
|
||||||
|
{
|
||||||
|
Item_cond_and *cond_and= (Item_cond_and *) cond;
|
||||||
|
List<Item_equal> *cond_equalities= &cond_and->cond_equal.current_level;
|
||||||
|
inherited= cond_and->cond_equal.upper_levels;
|
||||||
|
if (!cond_equalities->is_empty() && cond_equalities != new_equalities)
|
||||||
|
{
|
||||||
|
Item_equal *equal_item;
|
||||||
|
List_iterator<Item_equal> it(*new_equalities);
|
||||||
|
while ((equal_item= it++))
|
||||||
|
{
|
||||||
|
equal_item->merge_into_list(cond_equalities, true, true);
|
||||||
|
}
|
||||||
|
List_iterator<Item_equal> ei(*cond_equalities);
|
||||||
|
while ((equal_item= ei++))
|
||||||
|
{
|
||||||
|
if (equal_item->const_item() && !equal_item->val_int())
|
||||||
|
{
|
||||||
|
*is_simplifiable_cond= true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item *item;
|
||||||
|
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
|
||||||
|
while ((item= li++))
|
||||||
|
{
|
||||||
|
propagate_new_equalities(thd, item, new_equalities, inherited,
|
||||||
|
is_simplifiable_cond);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (cond->type() == Item::FUNC_ITEM &&
|
||||||
|
((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
|
||||||
|
{
|
||||||
|
Item_equal *equal_item;
|
||||||
|
List_iterator<Item_equal> it(*new_equalities);
|
||||||
|
Item_equal *equality= (Item_equal *) cond;
|
||||||
|
while ((equal_item= it++))
|
||||||
|
{
|
||||||
|
equality->merge_with_check(equal_item, true);
|
||||||
|
}
|
||||||
|
if (equality->const_item() && !equality->val_int())
|
||||||
|
*is_simplifiable_cond= true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uchar* is_subst_valid= (uchar *) Item::ANY_SUBST;
|
||||||
|
cond= cond->compile(&Item::subst_argument_checker,
|
||||||
|
&is_subst_valid,
|
||||||
|
&Item::equal_fields_propagator,
|
||||||
|
(uchar *) inherited);
|
||||||
|
cond->update_used_tables();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief
|
||||||
|
Evaluate all constant boolean sub-expressions in a condition
|
||||||
|
|
||||||
|
@param thd thread handle
|
||||||
|
@param cond condition where where to evaluate constant sub-expressions
|
||||||
|
@param[out] cond_value : the returned value of the condition
|
||||||
|
(TRUE/FALSE/UNKNOWN:
|
||||||
|
Item::COND_TRUE/Item::COND_FALSE/Item::COND_OK)
|
||||||
@return
|
@return
|
||||||
Return new item, or NULL if no condition @n
|
the item that is the result of the substitution of all inexpensive constant
|
||||||
cond_value is set to according:
|
boolean sub-expressions into cond, or,
|
||||||
- COND_OK : query is possible (field = constant)
|
NULL if the condition is constant and is evaluated to FALSE.
|
||||||
- COND_TRUE : always true ( 1 = 1 )
|
|
||||||
- COND_FALSE : always false ( 1 = 2 )
|
@details
|
||||||
|
This function looks for all inexpensive constant boolean sub-expressions in
|
||||||
|
the given condition 'cond' and substitutes them for their values.
|
||||||
|
For example, the condition 2 > (5 + 1) or a < (10 / 2)
|
||||||
|
will be transformed to the condition a < (10 / 2).
|
||||||
|
Note that a constant sub-expression is evaluated only if it is constant and
|
||||||
|
inexpensive. A sub-expression with an uncorrelated subquery may be evaluated
|
||||||
|
only if the subquery is considered as inexpensive.
|
||||||
|
The function does not evaluate a constant sub-expression if it is not on one
|
||||||
|
of AND/OR levels of the condition 'cond'. For example, the subquery in the
|
||||||
|
condition a > (select max(b) from t1 where b > 5) will never be evaluated
|
||||||
|
by this function.
|
||||||
|
If a constant boolean sub-expression is evaluated to TRUE then:
|
||||||
|
- when the sub-expression is a conjunct of an AND formula it is simply
|
||||||
|
removed from this formula
|
||||||
|
- when the sub-expression is a disjunct of an OR formula the whole OR
|
||||||
|
formula is converted to TRUE
|
||||||
|
If a constant boolean sub-expression is evaluated to FALSE then:
|
||||||
|
- when the sub-expression is a disjunct of an OR formula it is simply
|
||||||
|
removed from this formula
|
||||||
|
- when the sub-expression is a conjuct of an AND formula the whole AND
|
||||||
|
formula is converted to FALSE
|
||||||
|
When a disjunct/conjunct is removed from an OR/AND formula it might happen
|
||||||
|
that there is only one conjunct/disjunct remaining. In this case this
|
||||||
|
remaining disjunct/conjunct must be merged into underlying AND/OR formula,
|
||||||
|
because AND/OR levels must alternate in the same way as they alternate
|
||||||
|
after fix_fields() is called for the original condition.
|
||||||
|
The specifics of merging a formula f into an AND formula A appears
|
||||||
|
when A contains multiple equalities and f contains multiple equalities.
|
||||||
|
In this case the multiple equalities from f and A have to be merged.
|
||||||
|
After this the resulting multiple equalities have to be propagated into
|
||||||
|
the all AND/OR levels of the formula A (see propagate_new_equalities()).
|
||||||
|
The propagation of multiple equalities might result in forming multiple
|
||||||
|
equalities that are always FALSE. This, in its turn, might trigger further
|
||||||
|
simplification of the condition.
|
||||||
|
|
||||||
|
@note
|
||||||
|
EXAMPLE 1:
|
||||||
|
SELECT * FROM t1 WHERE (b = 1 OR a = 1) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||||
|
First 1 != 1 will be removed from the second conjunct:
|
||||||
|
=> SELECT * FROM t1 WHERE (b = 1 OR a = 1) AND (b = 5 AND a = 5);
|
||||||
|
Then (b = 5 AND a = 5) will be merged into the top level condition:
|
||||||
|
=> SELECT * FROM t1 WHERE (b = 1 OR a = 1) AND (b = 5) AND (a = 5);
|
||||||
|
Then (b = 5), (a = 5) will be propagated into the disjuncs of
|
||||||
|
(b = 1 OR a = 1):
|
||||||
|
=> SELECT * FROM t1 WHERE ((b = 1) AND (b = 5) AND (a = 5) OR
|
||||||
|
(a = 1) AND (b = 5) AND (a = 5)) AND
|
||||||
|
(b = 5) AND (a = 5)
|
||||||
|
=> SELECT * FROM t1 WHERE ((FALSE AND (a = 5)) OR
|
||||||
|
(FALSE AND (b = 5))) AND
|
||||||
|
(b = 5) AND (a = 5)
|
||||||
|
After this an additional call of remove_eq_conds() converts it
|
||||||
|
to FALSE
|
||||||
|
|
||||||
|
EXAMPLE 2:
|
||||||
|
SELECT * FROM t1 WHERE (b = 1 OR a = 5) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||||
|
=> SELECT * FROM t1 WHERE (b = 1 OR a = 5) AND (b = 5 AND a = 5);
|
||||||
|
=> SELECT * FROM t1 WHERE (b = 1 OR a = 5) AND (b = 5) AND (a = 5);
|
||||||
|
=> SELECT * FROM t1 WHERE ((b = 1) AND (b = 5) AND (a = 5) OR
|
||||||
|
(a = 5) AND (b = 5) AND (a = 5)) AND
|
||||||
|
(b = 5) AND (a = 5)
|
||||||
|
=> SELECT * FROM t1 WHERE ((FALSE AND (a = 5)) OR
|
||||||
|
((b = 5) AND (a = 5))) AND
|
||||||
|
(b = 5) AND (a = 5)
|
||||||
|
After this an additional call of remove_eq_conds() converts it to
|
||||||
|
=> SELECT * FROM t1 WHERE (b = 5) AND (a = 5)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
COND *
|
COND *
|
||||||
@ -13148,9 +13309,11 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
|
|||||||
{
|
{
|
||||||
if (cond->type() == Item::COND_ITEM)
|
if (cond->type() == Item::COND_ITEM)
|
||||||
{
|
{
|
||||||
|
List<Item_equal> new_equalities;
|
||||||
bool and_level= ((Item_cond*) cond)->functype()
|
bool and_level= ((Item_cond*) cond)->functype()
|
||||||
== Item_func::COND_AND_FUNC;
|
== Item_func::COND_AND_FUNC;
|
||||||
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
|
List<Item> *cond_arg_list= ((Item_cond*) cond)->argument_list();
|
||||||
|
List_iterator<Item> li(*cond_arg_list);
|
||||||
Item::cond_result tmp_cond_value;
|
Item::cond_result tmp_cond_value;
|
||||||
bool should_fix_fields=0;
|
bool should_fix_fields=0;
|
||||||
|
|
||||||
@ -13160,92 +13323,72 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
|
|||||||
{
|
{
|
||||||
Item *new_item=remove_eq_conds(thd, item, &tmp_cond_value);
|
Item *new_item=remove_eq_conds(thd, item, &tmp_cond_value);
|
||||||
if (!new_item)
|
if (!new_item)
|
||||||
|
{
|
||||||
|
/* This can happen only when item is converted to TRUE or FALSE */
|
||||||
li.remove();
|
li.remove();
|
||||||
|
}
|
||||||
else if (item != new_item)
|
else if (item != new_item)
|
||||||
{
|
{
|
||||||
if (and_level)
|
/*
|
||||||
{
|
This can happen when:
|
||||||
/*
|
- item was an OR formula converted to one disjunct
|
||||||
Take a special care of multiple equality predicates
|
- item was an AND formula converted to one conjunct
|
||||||
that may be part of 'cond' and 'new_item'.
|
In these cases the disjunct/conjunct must be merged into the
|
||||||
Those multiple equalities that have common members
|
argument list of cond.
|
||||||
must be merged.
|
*/
|
||||||
*/
|
if (new_item->type() == Item::COND_ITEM)
|
||||||
Item_cond_and *cond_and= (Item_cond_and *) cond;
|
{
|
||||||
List<Item_equal> *cond_equal_items=
|
DBUG_ASSERT(((Item_cond *) cond)->functype() ==
|
||||||
&cond_and->cond_equal.current_level;
|
((Item_cond *) new_item)->functype());
|
||||||
List<Item> *cond_and_list= cond_and->argument_list();
|
List<Item> *new_item_arg_list=
|
||||||
|
((Item_cond *) new_item)->argument_list();
|
||||||
if (new_item->type() == Item::COND_ITEM &&
|
if (and_level)
|
||||||
((Item_cond*) new_item)->functype() == Item_func::COND_AND_FUNC)
|
|
||||||
{
|
|
||||||
Item_cond_and *new_item_and= (Item_cond_and *) new_item;
|
|
||||||
List<Item_equal> *new_item_equal_items=
|
|
||||||
&new_item_and->cond_equal.current_level;
|
|
||||||
List<Item> *new_item_and_list= new_item_and->argument_list();
|
|
||||||
cond_and_list->disjoin((List<Item>*) cond_equal_items);
|
|
||||||
new_item_and_list->disjoin((List<Item>*) new_item_equal_items);
|
|
||||||
Item_equal *equal_item;
|
|
||||||
List_iterator<Item_equal> it(*new_item_equal_items);
|
|
||||||
while ((equal_item= it++))
|
|
||||||
{
|
|
||||||
equal_item->merge_into_list(cond_equal_items);
|
|
||||||
}
|
|
||||||
if (new_item_and_list->is_empty())
|
|
||||||
li.remove();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Item *list_item;
|
|
||||||
Item *new_list_item;
|
|
||||||
uint cnt= new_item_and_list->elements;
|
|
||||||
List_iterator<Item> it(*new_item_and_list);
|
|
||||||
while ((list_item= it++))
|
|
||||||
{
|
|
||||||
uchar* is_subst_valid= (uchar *) Item::ANY_SUBST;
|
|
||||||
new_list_item=
|
|
||||||
list_item->compile(&Item::subst_argument_checker,
|
|
||||||
&is_subst_valid,
|
|
||||||
&Item::equal_fields_propagator,
|
|
||||||
(uchar *) &cond_and->cond_equal);
|
|
||||||
if (new_list_item != list_item)
|
|
||||||
it.replace(new_list_item);
|
|
||||||
new_list_item->update_used_tables();
|
|
||||||
}
|
|
||||||
li.replace(*new_item_and_list);
|
|
||||||
for (cnt--; cnt; cnt--)
|
|
||||||
item= li++;
|
|
||||||
}
|
|
||||||
cond_and_list->concat((List<Item>*) cond_equal_items);
|
|
||||||
}
|
|
||||||
else if (new_item->type() == Item::FUNC_ITEM &&
|
|
||||||
((Item_cond*) new_item)->functype() ==
|
|
||||||
Item_func::MULT_EQUAL_FUNC)
|
|
||||||
{
|
{
|
||||||
cond_and_list->disjoin((List<Item>*) cond_equal_items);
|
/*
|
||||||
((Item_equal *) new_item)->merge_into_list(cond_equal_items);
|
If new_item is an AND formula then multiple equalities
|
||||||
li.remove();
|
of new_item_arg_list must merged into multiple equalities
|
||||||
cond_and_list->concat((List<Item>*) cond_equal_items);
|
of cond_arg_list.
|
||||||
|
*/
|
||||||
|
List<Item_equal> *new_item_equalities=
|
||||||
|
&((Item_cond_and *) new_item)->cond_equal.current_level;
|
||||||
|
if (!new_item_equalities->is_empty())
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Cut the multiple equalities from the new_item_arg_list and
|
||||||
|
append them on the list new_equalities. Later the equalities
|
||||||
|
from this list will be merged into the multiple equalities
|
||||||
|
of cond_arg_list all together.
|
||||||
|
*/
|
||||||
|
new_item_arg_list->disjoin((List<Item> *) new_item_equalities);
|
||||||
|
new_equalities.concat(new_item_equalities);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
if (new_item_arg_list->is_empty())
|
||||||
li.replace(new_item);
|
li.remove();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint cnt= new_item_arg_list->elements;
|
||||||
|
li.replace(*new_item_arg_list);
|
||||||
|
/* Make iterator li ignore new items */
|
||||||
|
for (cnt--; cnt; cnt--)
|
||||||
|
li++;
|
||||||
|
should_fix_fields= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (and_level &&
|
||||||
|
new_item->type() == Item::FUNC_ITEM &&
|
||||||
|
((Item_cond*) new_item)->functype() ==
|
||||||
|
Item_func::MULT_EQUAL_FUNC)
|
||||||
|
{
|
||||||
|
li.remove();
|
||||||
|
new_equalities.push_back((Item_equal *) new_item);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (new_item->type() == Item::COND_ITEM &&
|
li.replace(new_item);
|
||||||
((Item_cond*) new_item)->functype() ==
|
should_fix_fields= 1;
|
||||||
((Item_cond*) cond)->functype())
|
|
||||||
{
|
|
||||||
List<Item> *arg_list= ((Item_cond*) new_item)->argument_list();
|
|
||||||
uint cnt= arg_list->elements;
|
|
||||||
li.replace(*arg_list);
|
|
||||||
for ( cnt--; cnt; cnt--)
|
|
||||||
item= li++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
li.replace(new_item);
|
|
||||||
}
|
}
|
||||||
should_fix_fields=1;
|
}
|
||||||
}
|
|
||||||
if (*cond_value == Item::COND_UNDEF)
|
if (*cond_value == Item::COND_UNDEF)
|
||||||
*cond_value=tmp_cond_value;
|
*cond_value=tmp_cond_value;
|
||||||
switch (tmp_cond_value) {
|
switch (tmp_cond_value) {
|
||||||
@ -13271,6 +13414,53 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
|
|||||||
break; /* purecov: deadcode */
|
break; /* purecov: deadcode */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!new_equalities.is_empty())
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(and_level);
|
||||||
|
/*
|
||||||
|
Merge multiple equalities that were cut from the results of
|
||||||
|
simplification of OR formulas converted into AND formulas.
|
||||||
|
These multiple equalities are to be merged into the
|
||||||
|
multiple equalities of cond_arg_list.
|
||||||
|
*/
|
||||||
|
COND_EQUAL *cond_equal= &((Item_cond_and *) cond)->cond_equal;
|
||||||
|
List<Item_equal> *cond_equalities= &cond_equal->current_level;
|
||||||
|
cond_arg_list->disjoin((List<Item> *) cond_equalities);
|
||||||
|
Item_equal *equality;
|
||||||
|
List_iterator_fast<Item_equal> it(new_equalities);
|
||||||
|
while ((equality= it++))
|
||||||
|
{
|
||||||
|
equality->merge_into_list(cond_equalities, false, false);
|
||||||
|
List_iterator_fast<Item_equal> ei(*cond_equalities);
|
||||||
|
while ((equality= ei++))
|
||||||
|
{
|
||||||
|
if (equality->const_item() && !equality->val_int())
|
||||||
|
{
|
||||||
|
*cond_value= Item::COND_FALSE;
|
||||||
|
return (COND*) 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cond_arg_list->concat((List<Item> *) cond_equalities);
|
||||||
|
/*
|
||||||
|
Propagate the newly formed multiple equalities to
|
||||||
|
the all AND/OR levels of cond
|
||||||
|
*/
|
||||||
|
bool is_simplifiable_cond= true;
|
||||||
|
propagate_new_equalities(thd, cond, cond_equalities,
|
||||||
|
cond_equal->upper_levels,
|
||||||
|
&is_simplifiable_cond);
|
||||||
|
/*
|
||||||
|
If the above propagation of multiple equalities brings us
|
||||||
|
to multiple equalities that are always FALSE then try to
|
||||||
|
simplify the condition with remove_eq_cond() again.
|
||||||
|
*/
|
||||||
|
if (is_simplifiable_cond)
|
||||||
|
{
|
||||||
|
if (!(cond= remove_eq_conds(thd, cond, cond_value)))
|
||||||
|
return cond;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (should_fix_fields)
|
if (should_fix_fields)
|
||||||
cond->update_used_tables();
|
cond->update_used_tables();
|
||||||
|
|
||||||
@ -13382,6 +13572,7 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
|
|||||||
return cond; // Point at next and level
|
return cond; // Point at next and level
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Check if equality can be used in removing components of GROUP BY/DISTINCT
|
Check if equality can be used in removing components of GROUP BY/DISTINCT
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user