Bug #55568: user variable assignments crash server when used
within query The server could crash after materializing a derived table which requires a temporary table for grouping. When destroying the temporary table used to execute a query for a derived table, JOIN::destroy() did not clean up Item_fields pointing to fields in the temporary table. This led to dereferencing a dangling pointer when printing out the items tree later in the outer SELECT. The solution is an addendum to the patch for bug37362: in addition to cleaning up items in tmp_all_fields3, do the same for items in tmp_all_fields1, since now we have an example where this is necessary.
This commit is contained in:
parent
62aa8943b8
commit
0e74ac5028
@ -1184,4 +1184,55 @@ NULL
|
|||||||
NULL
|
NULL
|
||||||
1
|
1
|
||||||
DROP TABLE t1, t2, mm1;
|
DROP TABLE t1, t2, mm1;
|
||||||
|
#
|
||||||
|
# Bug #55568: user variable assignments crash server when used within
|
||||||
|
# query
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
INSERT INTO t1 VALUES (0), (1);
|
||||||
|
SELECT MULTIPOINT(
|
||||||
|
1,
|
||||||
|
(
|
||||||
|
SELECT MULTIPOINT(
|
||||||
|
MULTIPOINT(
|
||||||
|
1,
|
||||||
|
(SELECT COUNT(*) FROM (SELECT 1 FROM t1 GROUP BY a,a) d)
|
||||||
|
)
|
||||||
|
) FROM t1
|
||||||
|
)
|
||||||
|
) != COUNT(*) q FROM t1 GROUP BY a;
|
||||||
|
q
|
||||||
|
NULL
|
||||||
|
NULL
|
||||||
|
SELECT MULTIPOINT(
|
||||||
|
1,
|
||||||
|
(
|
||||||
|
SELECT MULTIPOINT(
|
||||||
|
MULTIPOINT(
|
||||||
|
1,
|
||||||
|
(SELECT COUNT(*) FROM (SELECT 1 FROM t1 GROUP BY a,a) d)
|
||||||
|
)
|
||||||
|
) FROM t1
|
||||||
|
)
|
||||||
|
) != COUNT(*) q FROM t1 GROUP BY a;
|
||||||
|
q
|
||||||
|
NULL
|
||||||
|
NULL
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Bug #54468: crash after item's print() function when ordering/grouping
|
||||||
|
# by subquery
|
||||||
|
#
|
||||||
|
CREATE TABLE t1(a INT, b INT);
|
||||||
|
INSERT INTO t1 VALUES (), ();
|
||||||
|
SELECT 1 FROM t1
|
||||||
|
GROUP BY
|
||||||
|
GREATEST(t1.a,
|
||||||
|
(SELECT 1 FROM
|
||||||
|
(SELECT t1.b FROM t1,t1 t2
|
||||||
|
ORDER BY t1.a, t1.a LIMIT 1) AS d)
|
||||||
|
);
|
||||||
|
1
|
||||||
|
1
|
||||||
|
DROP TABLE t1;
|
||||||
End of 5.1 tests
|
End of 5.1 tests
|
||||||
|
@ -851,4 +851,50 @@ ENGINE=MERGE UNION=(t1,t2);
|
|||||||
SELECT t1.a FROM mm1,t1;
|
SELECT t1.a FROM mm1,t1;
|
||||||
DROP TABLE t1, t2, mm1;
|
DROP TABLE t1, t2, mm1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug #55568: user variable assignments crash server when used within
|
||||||
|
--echo # query
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
|
||||||
|
INSERT INTO t1 VALUES (0), (1);
|
||||||
|
|
||||||
|
let $i=2;
|
||||||
|
while ($i)
|
||||||
|
{
|
||||||
|
SELECT MULTIPOINT(
|
||||||
|
1,
|
||||||
|
(
|
||||||
|
SELECT MULTIPOINT(
|
||||||
|
MULTIPOINT(
|
||||||
|
1,
|
||||||
|
(SELECT COUNT(*) FROM (SELECT 1 FROM t1 GROUP BY a,a) d)
|
||||||
|
)
|
||||||
|
) FROM t1
|
||||||
|
)
|
||||||
|
) != COUNT(*) q FROM t1 GROUP BY a;
|
||||||
|
dec $i;
|
||||||
|
}
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug #54468: crash after item's print() function when ordering/grouping
|
||||||
|
--echo # by subquery
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1(a INT, b INT);
|
||||||
|
INSERT INTO t1 VALUES (), ();
|
||||||
|
|
||||||
|
SELECT 1 FROM t1
|
||||||
|
GROUP BY
|
||||||
|
GREATEST(t1.a,
|
||||||
|
(SELECT 1 FROM
|
||||||
|
(SELECT t1.b FROM t1,t1 t2
|
||||||
|
ORDER BY t1.a, t1.a LIMIT 1) AS d)
|
||||||
|
);
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
--echo End of 5.1 tests
|
--echo End of 5.1 tests
|
||||||
|
@ -1535,7 +1535,7 @@ void Field::make_field(Send_field *field)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
field->org_table_name= field->db_name= "";
|
field->org_table_name= field->db_name= "";
|
||||||
if (orig_table)
|
if (orig_table && orig_table->alias)
|
||||||
{
|
{
|
||||||
field->table_name= orig_table->alias;
|
field->table_name= orig_table->alias;
|
||||||
field->org_col_name= field_name;
|
field->org_col_name= field_name;
|
||||||
|
@ -2378,13 +2378,8 @@ JOIN::destroy()
|
|||||||
|
|
||||||
cleanup(1);
|
cleanup(1);
|
||||||
/* Cleanup items referencing temporary table columns */
|
/* Cleanup items referencing temporary table columns */
|
||||||
if (!tmp_all_fields3.is_empty())
|
cleanup_item_list(tmp_all_fields1);
|
||||||
{
|
cleanup_item_list(tmp_all_fields3);
|
||||||
List_iterator_fast<Item> it(tmp_all_fields3);
|
|
||||||
Item *item;
|
|
||||||
while ((item= it++))
|
|
||||||
item->cleanup();
|
|
||||||
}
|
|
||||||
if (exec_tmp_table1)
|
if (exec_tmp_table1)
|
||||||
free_tmp_table(thd, exec_tmp_table1);
|
free_tmp_table(thd, exec_tmp_table1);
|
||||||
if (exec_tmp_table2)
|
if (exec_tmp_table2)
|
||||||
@ -2395,6 +2390,19 @@ JOIN::destroy()
|
|||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void JOIN::cleanup_item_list(List<Item> &items) const
|
||||||
|
{
|
||||||
|
if (!items.is_empty())
|
||||||
|
{
|
||||||
|
List_iterator_fast<Item> it(items);
|
||||||
|
Item *item;
|
||||||
|
while ((item= it++))
|
||||||
|
item->cleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
An entry point to single-unit select (a select without UNION).
|
An entry point to single-unit select (a select without UNION).
|
||||||
|
|
||||||
|
@ -577,6 +577,7 @@ private:
|
|||||||
*/
|
*/
|
||||||
bool implicit_grouping;
|
bool implicit_grouping;
|
||||||
bool make_simple_join(JOIN *join, TABLE *tmp_table);
|
bool make_simple_join(JOIN *join, TABLE *tmp_table);
|
||||||
|
void cleanup_item_list(List<Item> &items) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user