Skip to content

Commit 727a5c9

Browse files
kahatlenbjornmu
authored andcommitted
Bug#21808680: JSON + GENERATED COLUMN CORRUPTS TABLE CACHE MEMORY, CRASHES
In some cases pointers to stale data could be left in the Item tree of the generated column expression, which would lead to problems the next time the generated column was accessed. There is already code in place to avoid this situation. TABLE::cleanup_gc_items() calls Item::cleanup() on the generated column expression upon completion of a statement, and this is supposed to revert the Item tree to a pristine state, ready for reuse in a new statement. However, since the Item::cleanup() functions are not recursive, only the top-level item in the generated column expression will be cleaned up. Children, such as items representing the arguments of a function call, will not be cleaned up and can point to stale data inserted into the item tree during execution. The fix changes TABLE::cleanup_gc_items() so that it calls cleanup() on all the items in the generated column's item_free_list, and not only on the top-level item. The patch also removes an unused parameter from the function. (cherry picked from commit a16052827bbe17415cee5969f0fa46247f18e77d) Conflicts: mysql-test/suite/gcol/r/gcol_bugfixes.result mysql-test/suite/gcol/t/gcol_bugfixes.test
1 parent 02f8eaa commit 727a5c9

File tree

5 files changed

+30
-15
lines changed

5 files changed

+30
-15
lines changed

mysql-test/suite/gcol/r/gcol_bugfixes.result

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,3 +466,14 @@ SELECT * FROM t;
466466
a b
467467
1 1
468468
DROP TABLE t;
469+
#
470+
# Bug #21808680: JSON + GENERATED COLUMN CORRUPTS TABLE CACHE
471+
# MEMORY, CRASHES
472+
#
473+
CREATE TABLE t (a INT, b JSON, c TEXT GENERATED ALWAYS AS (REPEAT(a=b, 2)));
474+
INSERT INTO t (a, b) VALUES (1, '2'), (3, '3');
475+
SELECT * FROM t;
476+
a b c
477+
1 2 00
478+
3 3 11
479+
DROP TABLE t;

mysql-test/suite/gcol/t/gcol_bugfixes.test

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,3 +461,13 @@ SELECT f();
461461
DROP FUNCTION f;
462462
SELECT * FROM t;
463463
DROP TABLE t;
464+
465+
--echo #
466+
--echo # Bug #21808680: JSON + GENERATED COLUMN CORRUPTS TABLE CACHE
467+
--echo # MEMORY, CRASHES
468+
--echo #
469+
CREATE TABLE t (a INT, b JSON, c TEXT GENERATED ALWAYS AS (REPEAT(a=b, 2)));
470+
INSERT INTO t (a, b) VALUES (1, '2'), (3, '3');
471+
# The next statement used to crash.
472+
SELECT * FROM t;
473+
DROP TABLE t;

sql/sql_base.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1337,7 +1337,7 @@ static void mark_temp_tables_as_free_for_reuse(THD *thd)
13371337
if ((table->query_id == thd->query_id) && ! table->open_by_handler)
13381338
{
13391339
mark_tmp_table_for_reuse(table);
1340-
table->cleanup_gc_items(thd);
1340+
table->cleanup_gc_items();
13411341
}
13421342
}
13431343
}
@@ -1567,7 +1567,7 @@ void close_thread_tables(THD *thd)
15671567
{
15681568
DBUG_ASSERT(table->file);
15691569
table->file->extra(HA_EXTRA_DETACH_CHILDREN);
1570-
table->cleanup_gc_items(thd);
1570+
table->cleanup_gc_items();
15711571
}
15721572
}
15731573

sql/table.cc

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4646,17 +4646,13 @@ bool TABLE::refix_gc_items(THD *thd)
46464646
}
46474647

46484648

4649-
void TABLE::cleanup_gc_items(THD *thd)
4649+
void TABLE::cleanup_gc_items()
46504650
{
4651-
if (vfield)
4652-
{
4653-
for (Field **vfield_ptr= vfield; *vfield_ptr; vfield_ptr++)
4654-
{
4655-
Field *vfield= *vfield_ptr;
4656-
DBUG_ASSERT(vfield->gcol_info && vfield->gcol_info->expr_item);
4657-
vfield->gcol_info->expr_item->cleanup();
4658-
}
4659-
}
4651+
if (!has_gcol())
4652+
return;
4653+
4654+
for (Field **vfield_ptr= vfield; *vfield_ptr; vfield_ptr++)
4655+
cleanup_items((*vfield_ptr)->gcol_info->item_free_list);
46604656
}
46614657

46624658
/*

sql/table.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1426,10 +1426,8 @@ struct TABLE
14261426
/**
14271427
Clean any state in items associated with generated columns to be ready for
14281428
the next statement.
1429-
1430-
@param[in] thd the current thread
14311429
*/
1432-
void cleanup_gc_items(THD *thd);
1430+
void cleanup_gc_items();
14331431
};
14341432

14351433

0 commit comments

Comments
 (0)