Skip to content

Commit 6058e02

Browse files
committed
MDEV-37172 Server crashes in Item_func_nextval::update_table after INSERT to the table, that uses expression with nextval() as default
The issue was that unpack_vcol_info_from_frm() wrongly linked the used sequence tables into tables->internal_tables when more than one sequence table was used. Other things: - Fixed internal_table_exists() to take db into account. (This is making the code easier to read. As we where comparing pointers the old code also worked).
1 parent e3e4013 commit 6058e02

File tree

5 files changed

+68
-10
lines changed

5 files changed

+68
-10
lines changed

mysql-test/suite/sql_sequence/default.result

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,4 +313,37 @@ insert v1 values (default);
313313
ERROR HY000: The target table v1 of the INSERT is not insertable-into
314314
drop view v1;
315315
drop table t1;
316+
#
317+
# MDEV-37172 Server crashes in Item_func_nextval::update_table after
318+
# INSERT to the table, that uses expression with nextval() as default
319+
#
320+
create sequence s1;
321+
create sequence s2;
322+
create table t1 (id int default(nextval(s1)));
323+
create table t2 (id int default(nextval(s1)+nextval(s1)));
324+
create table t3 (id1 int default(nextval(s1)+nextval(s1)),
325+
id2 int default(nextval(s2)));
326+
insert t1 values ();
327+
select lastval(s1);
328+
lastval(s1)
329+
1
330+
select * from t1;
331+
id
332+
1
333+
insert t2 values ();
334+
select lastval(s1);
335+
lastval(s1)
336+
3
337+
select * from t2;
338+
id
339+
5
340+
insert t3 values ();
341+
select lastval(s1), lastval(s2);
342+
lastval(s1) lastval(s2)
343+
5 1
344+
select * from t3;
345+
id1 id2
346+
9 1
347+
drop table t1,t2,t3;
348+
drop sequence s1,s2;
316349
# End of 10.6 tests

mysql-test/suite/sql_sequence/default.test

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,4 +240,27 @@ insert v1 values (default);
240240
drop view v1;
241241
drop table t1;
242242

243+
--echo #
244+
--echo # MDEV-37172 Server crashes in Item_func_nextval::update_table after
245+
--echo # INSERT to the table, that uses expression with nextval() as default
246+
--echo #
247+
248+
create sequence s1;
249+
create sequence s2;
250+
create table t1 (id int default(nextval(s1)));
251+
create table t2 (id int default(nextval(s1)+nextval(s1)));
252+
create table t3 (id1 int default(nextval(s1)+nextval(s1)),
253+
id2 int default(nextval(s2)));
254+
insert t1 values ();
255+
select lastval(s1);
256+
select * from t1;
257+
insert t2 values ();
258+
select lastval(s1);
259+
select * from t2;
260+
insert t3 values ();
261+
select lastval(s1), lastval(s2);
262+
select * from t3;
263+
drop table t1,t2,t3;
264+
drop sequence s1,s2;
265+
243266
--echo # End of 10.6 tests

sql/sql_base.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4722,11 +4722,12 @@ bool table_already_fk_prelocked(TABLE_LIST *tl, LEX_CSTRING *db,
47224722

47234723

47244724
static TABLE_LIST *internal_table_exists(TABLE_LIST *global_list,
4725-
const char *table_name)
4725+
TABLE_LIST *table)
47264726
{
47274727
do
47284728
{
4729-
if (global_list->table_name.str == table_name)
4729+
if (global_list->table_name.str == table->table_name.str &&
4730+
global_list->db.str == table->db.str)
47304731
return global_list;
47314732
} while ((global_list= global_list->next_global));
47324733
return 0;
@@ -4747,8 +4748,7 @@ add_internal_tables(THD *thd, Query_tables_list *prelocking_ctx,
47474748
/*
47484749
Skip table if already in the list. Can happen with prepared statements
47494750
*/
4750-
if ((tmp= internal_table_exists(global_table_list,
4751-
tables->table_name.str)))
4751+
if ((tmp= internal_table_exists(global_table_list, tables)))
47524752
{
47534753
/*
47544754
Use the original value for the next local, used by the

sql/sql_parse.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8438,8 +8438,8 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
84388438
}
84398439
}
84408440
}
8441-
/* Store the table reference preceding the current one. */
8442-
TABLE_LIST *UNINIT_VAR(previous_table_ref); /* The table preceding the current one. */
8441+
/* Store the table reference preceding the current in previous_table_ref */
8442+
TABLE_LIST *UNINIT_VAR(previous_table_ref);
84438443
if (table_list.elements > 0 && likely(!ptr->sequence))
84448444
{
84458445
/*

sql/table.cc

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3942,6 +3942,7 @@ unpack_vcol_info_from_frm(THD *thd, TABLE *table,
39423942
LEX *old_lex= thd->lex;
39433943
LEX lex;
39443944
bool error;
3945+
TABLE_LIST *sequence, *last;
39453946
DBUG_ENTER("unpack_vcol_info_from_frm");
39463947

39473948
DBUG_ASSERT(vcol->expr == NULL);
@@ -3959,11 +3960,12 @@ unpack_vcol_info_from_frm(THD *thd, TABLE *table,
39593960
if (unlikely(error))
39603961
goto end;
39613962

3962-
if (lex.current_select->table_list.first[0].next_global)
3963+
if ((sequence= lex.current_select->table_list.first[0].next_global))
39633964
{
3964-
/* We are using NEXT VALUE FOR sequence. Remember table name for open */
3965-
TABLE_LIST *sequence= lex.current_select->table_list.first[0].next_global;
3966-
sequence->next_global= table->internal_tables;
3965+
/* We are using NEXT VALUE FOR sequence. Remember table for open */
3966+
for (last= sequence ; last->next_global ; last= last->next_global)
3967+
;
3968+
last->next_global= table->internal_tables;
39673969
table->internal_tables= sequence;
39683970
}
39693971

0 commit comments

Comments
 (0)