mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
Bug#57688 Assertion `!table || (!table->write_set || bitmap_is_set(table->write_set, field
Lines below which were added in the patch for Bug#56814 cause this crash: + if (table->table) + table->table->maybe_null= FALSE; Consider following test case: -- CREATE TABLE t1(f1 INT NOT NULL); INSERT INTO t1 VALUES (16777214),(0); SELECT COUNT(*) FROM t1 LEFT JOIN t1 t2 ON 1 WHERE t2.f1 > 1 GROUP BY t2.f1; DROP TABLE t1; -- We set TABLE::maybe_null to FALSE for t2 table and in create_tmp_field() we create appropriate tmp table field using create_tmp_field_from_item() function instead of create_tmp_field_from_field. As a result we have LONGLONG field. As we have GROUP BY clause we calculate group buffer length, see calc_group_buffer(). Item from group list which is used for calculation refer to the field from real tables and have LONG type. So group buffer length become insufficient for storing of LONGLONG value. It leads to overwriting of wrong memory area in do_field_int() function which is called from end_update(). After some investigation I found out that create_tmp_field_from_item() is used only for OLAP grouping and can not be used for common grouping as it could be an incompatibility between tmp table fields and group buffer length. We can not remove create_tmp_field_from_item() call from create_tmp_field as OLAP needs it and we can not use this function for common grouping. So we should remove setting TABLE::maybe_null to FALSE from simplify_joins(). In this case we'll get wrong behaviour of list_contains_unique_index() back. To fix it we could use Field::real_maybe_null() check instead of Field::maybe_null() and add addition check of TABLE_LIST::outer_join. mysql-test/r/group_by.result: test case mysql-test/r/join_outer.result: test case mysql-test/t/group_by.test: test case mysql-test/t/join_outer.test: test case sql/sql_select.cc: --remove wrong code --use Field::real_maybe_null() check instead of Field::maybe_null() and add addition check of TABLE_LIST::outer_join
This commit is contained in:
parent
c04bf683fe
commit
4a23ac20d9
5 changed files with 83 additions and 8 deletions
|
@ -1845,4 +1845,14 @@ SELECT SUBSTRING(a,1,10), LENGTH(a) FROM t1 GROUP BY a;
|
|||
SUBSTRING(a,1,10) LENGTH(a)
|
||||
1111111111 1300
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Bug#57688 Assertion `!table || (!table->write_set || bitmap_is_set(table->write_set, field
|
||||
#
|
||||
CREATE TABLE t1(f1 INT NOT NULL);
|
||||
INSERT INTO t1 VALUES (16777214),(0);
|
||||
SELECT COUNT(*) FROM t1 LEFT JOIN t1 t2
|
||||
ON 1 WHERE t2.f1 > 1 GROUP BY t2.f1;
|
||||
COUNT(*)
|
||||
2
|
||||
DROP TABLE t1;
|
||||
# End of 5.1 tests
|
||||
|
|
|
@ -1397,4 +1397,34 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
Warnings:
|
||||
Note 1003 select straight_join `test`.`jt1`.`f1` AS `f1` from `test`.`t1` `jt6` left join (`test`.`t1` `jt3` join `test`.`t1` `jt4` left join `test`.`t1` `jt5` on(1) left join `test`.`t1` `jt2` on(1)) on((`test`.`jt6`.`f1` and 1)) left join `test`.`t1` `jt1` on(1) where 1
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Bug#57688 Assertion `!table || (!table->write_set || bitmap_is_set(table->write_set, field
|
||||
#
|
||||
CREATE TABLE t1 (f1 INT NOT NULL, PRIMARY KEY (f1));
|
||||
CREATE TABLE t2 (f1 INT NOT NULL, f2 INT NOT NULL, PRIMARY KEY (f1, f2));
|
||||
INSERT INTO t1 VALUES (4);
|
||||
INSERT INTO t2 VALUES (3, 3);
|
||||
INSERT INTO t2 VALUES (7, 7);
|
||||
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1
|
||||
WHERE t1.f1 = 4
|
||||
GROUP BY t2.f1, t2.f2;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 system PRIMARY NULL NULL NULL 1 Using temporary; Using filesort
|
||||
1 SIMPLE t2 ref PRIMARY PRIMARY 4 const 1 Using index
|
||||
SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1
|
||||
WHERE t1.f1 = 4
|
||||
GROUP BY t2.f1, t2.f2;
|
||||
f1 f1 f2
|
||||
4 NULL NULL
|
||||
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1
|
||||
WHERE t1.f1 = 4 AND t2.f1 IS NOT NULL AND t2.f2 IS NOT NULL
|
||||
GROUP BY t2.f1, t2.f2;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 system PRIMARY NULL NULL NULL 1 Using filesort
|
||||
1 SIMPLE t2 ref PRIMARY PRIMARY 4 const 1 Using where; Using index
|
||||
SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1
|
||||
WHERE t1.f1 = 4 AND t2.f1 IS NOT NULL AND t2.f2 IS NOT NULL
|
||||
GROUP BY t2.f1, t2.f2;
|
||||
f1 f1 f2
|
||||
DROP TABLE t1,t2;
|
||||
End of 5.1 tests
|
||||
|
|
|
@ -1235,5 +1235,16 @@ SELECT SUBSTRING(a,1,10), LENGTH(a) FROM t1 GROUP BY a;
|
|||
SELECT SUBSTRING(a,1,10), LENGTH(a) FROM t1 GROUP BY a;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # Bug#57688 Assertion `!table || (!table->write_set || bitmap_is_set(table->write_set, field
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1(f1 INT NOT NULL);
|
||||
INSERT INTO t1 VALUES (16777214),(0);
|
||||
|
||||
SELECT COUNT(*) FROM t1 LEFT JOIN t1 t2
|
||||
ON 1 WHERE t2.f1 > 1 GROUP BY t2.f1;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo # End of 5.1 tests
|
||||
|
|
|
@ -981,4 +981,33 @@ EXPLAIN EXTENDED SELECT STRAIGHT_JOIN jt1.f1 FROM t1 AS jt1
|
|||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # Bug#57688 Assertion `!table || (!table->write_set || bitmap_is_set(table->write_set, field
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (f1 INT NOT NULL, PRIMARY KEY (f1));
|
||||
CREATE TABLE t2 (f1 INT NOT NULL, f2 INT NOT NULL, PRIMARY KEY (f1, f2));
|
||||
|
||||
INSERT INTO t1 VALUES (4);
|
||||
INSERT INTO t2 VALUES (3, 3);
|
||||
INSERT INTO t2 VALUES (7, 7);
|
||||
|
||||
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1
|
||||
WHERE t1.f1 = 4
|
||||
GROUP BY t2.f1, t2.f2;
|
||||
|
||||
SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1
|
||||
WHERE t1.f1 = 4
|
||||
GROUP BY t2.f1, t2.f2;
|
||||
|
||||
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1
|
||||
WHERE t1.f1 = 4 AND t2.f1 IS NOT NULL AND t2.f2 IS NOT NULL
|
||||
GROUP BY t2.f1, t2.f2;
|
||||
|
||||
SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1
|
||||
WHERE t1.f1 = 4 AND t2.f1 IS NOT NULL AND t2.f2 IS NOT NULL
|
||||
GROUP BY t2.f1, t2.f2;
|
||||
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
--echo End of 5.1 tests
|
||||
|
|
|
@ -8832,13 +8832,6 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
|
|||
that reject nulls => the outer join can be replaced by an inner join.
|
||||
*/
|
||||
table->outer_join= 0;
|
||||
/*
|
||||
Update TABLE::maybe_null field as it could have
|
||||
the value(maybe_null==TRUE) based on the assumption
|
||||
that this join is outer(see setup_table_map() func).
|
||||
*/
|
||||
if (table->table)
|
||||
table->table->maybe_null= FALSE;
|
||||
if (table->on_expr)
|
||||
{
|
||||
/* Add on expression to the where condition. */
|
||||
|
@ -13219,6 +13212,8 @@ static bool
|
|||
list_contains_unique_index(TABLE *table,
|
||||
bool (*find_func) (Field *, void *), void *data)
|
||||
{
|
||||
if (table->pos_in_table_list->outer_join)
|
||||
return 0;
|
||||
for (uint keynr= 0; keynr < table->s->keys; keynr++)
|
||||
{
|
||||
if (keynr == table->s->primary_key ||
|
||||
|
@ -13232,7 +13227,7 @@ list_contains_unique_index(TABLE *table,
|
|||
key_part < key_part_end;
|
||||
key_part++)
|
||||
{
|
||||
if (key_part->field->maybe_null() ||
|
||||
if (key_part->field->real_maybe_null() ||
|
||||
!find_func(key_part->field, data))
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue