Fixed crash with SEQUENCE when using REPAIR
This commit is contained in:
parent
c619fbeafe
commit
276b0c8ef0
42
mysql-test/suite/sql_sequence/other.result
Normal file
42
mysql-test/suite/sql_sequence/other.result
Normal file
@ -0,0 +1,42 @@
|
||||
#
|
||||
# Create and check
|
||||
#
|
||||
create sequence s1 engine=innodb;
|
||||
check table s1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.s1 check note The storage engine for the table doesn't support check
|
||||
select next value for s1;
|
||||
next value for s1
|
||||
1
|
||||
flush tables;
|
||||
check table s1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.s1 check note The storage engine for the table doesn't support check
|
||||
select next value for s1;
|
||||
next value for s1
|
||||
1001
|
||||
flush tables;
|
||||
repair table s1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.s1 repair note The storage engine for the table doesn't support repair
|
||||
select next value for s1;
|
||||
next value for s1
|
||||
2001
|
||||
drop sequence s1;
|
||||
create or replace sequence s1 engine=innodb;
|
||||
select next value for s1;
|
||||
next value for s1
|
||||
1
|
||||
repair table s1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.s1 repair note The storage engine for the table doesn't support repair
|
||||
check table s1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.s1 check note The storage engine for the table doesn't support check
|
||||
select next value for s1;
|
||||
next value for s1
|
||||
1001
|
||||
select * from s1;
|
||||
next_value min_value max_value start increment cache cycle round
|
||||
2001 1 9223372036854775806 1 1 1000 0 0
|
||||
drop sequence s1;
|
29
mysql-test/suite/sql_sequence/other.test
Normal file
29
mysql-test/suite/sql_sequence/other.test
Normal file
@ -0,0 +1,29 @@
|
||||
--source include/have_sequence.inc
|
||||
--source include/have_innodb.inc
|
||||
|
||||
#
|
||||
# Test various combinations of operations on sequence
|
||||
#
|
||||
|
||||
--echo #
|
||||
--echo # Create and check
|
||||
--echo #
|
||||
|
||||
create sequence s1 engine=innodb;
|
||||
check table s1;
|
||||
select next value for s1;
|
||||
flush tables;
|
||||
check table s1;
|
||||
select next value for s1;
|
||||
flush tables;
|
||||
repair table s1;
|
||||
select next value for s1;
|
||||
drop sequence s1;
|
||||
|
||||
create or replace sequence s1 engine=innodb;
|
||||
select next value for s1;
|
||||
repair table s1;
|
||||
check table s1;
|
||||
select next value for s1;
|
||||
select * from s1;
|
||||
drop sequence s1;
|
@ -110,6 +110,8 @@ int ha_sequence::open(const char *name, int mode, uint flags)
|
||||
if ((error= table->s->sequence->read_initial_values(table)))
|
||||
file->ha_close();
|
||||
}
|
||||
else
|
||||
table->m_needs_reopen= true;
|
||||
}
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
@ -189,11 +191,13 @@ int ha_sequence::write_row(uchar *buf)
|
||||
DBUG_ASSERT(table->record[0] == buf);
|
||||
|
||||
row_already_logged= 0;
|
||||
if (!sequence->initialized)
|
||||
if (unlikely(sequence->initialized == SEQUENCE::SEQ_IN_PREPARE))
|
||||
{
|
||||
/* This calls is from ha_open() as part of create table */
|
||||
DBUG_RETURN(file->write_row(buf));
|
||||
}
|
||||
if (unlikely(sequence->initialized != SEQUENCE::SEQ_READY_TO_USE))
|
||||
DBUG_RETURN(HA_ERR_WRONG_COMMAND);
|
||||
|
||||
/*
|
||||
User tries to write a row
|
||||
|
@ -327,7 +327,9 @@ bool sequence_insert(THD *thd, LEX *lex, TABLE_LIST *table_list)
|
||||
tmp_disable_binlog(thd);
|
||||
save_write_set= table->write_set;
|
||||
table->write_set= &table->s->all_set;
|
||||
table->s->sequence->initialized= SEQUENCE::SEQ_IN_PREPARE;
|
||||
error= table->file->ha_write_row(table->record[0]);
|
||||
table->s->sequence->initialized= SEQUENCE::SEQ_UNINTIALIZED;
|
||||
reenable_binlog(thd);
|
||||
table->write_set= save_write_set;
|
||||
|
||||
@ -339,7 +341,7 @@ bool sequence_insert(THD *thd, LEX *lex, TABLE_LIST *table_list)
|
||||
Sequence structure is up to date and table has one row,
|
||||
sequence is now usable
|
||||
*/
|
||||
table->s->sequence->initialized= 1;
|
||||
table->s->sequence->initialized= SEQUENCE::SEQ_READY_TO_USE;
|
||||
}
|
||||
|
||||
trans_commit_stmt(thd);
|
||||
@ -353,7 +355,7 @@ bool sequence_insert(THD *thd, LEX *lex, TABLE_LIST *table_list)
|
||||
|
||||
/* Create a SQUENCE object */
|
||||
|
||||
SEQUENCE::SEQUENCE() :initialized(0), all_values_used(0), table(0)
|
||||
SEQUENCE::SEQUENCE() :all_values_used(0), initialized(SEQ_UNINTIALIZED), table(0)
|
||||
{
|
||||
mysql_mutex_init(key_LOCK_SEQUENCE, &mutex, MY_MUTEX_INIT_SLOW);
|
||||
}
|
||||
@ -376,11 +378,11 @@ int SEQUENCE::read_initial_values(TABLE *table_arg)
|
||||
MDL_request mdl_request; // Empty constructor!
|
||||
DBUG_ENTER("SEQUENCE::read_initial_values");
|
||||
|
||||
if (likely(initialized))
|
||||
if (likely(initialized != SEQ_UNINTIALIZED))
|
||||
DBUG_RETURN(0);
|
||||
table= table_arg;
|
||||
mysql_mutex_lock(&mutex);
|
||||
if (unlikely(!initialized))
|
||||
if (likely(initialized == SEQ_UNINTIALIZED))
|
||||
{
|
||||
MYSQL_LOCK *lock;
|
||||
bool mdl_lock_used= 0;
|
||||
@ -419,7 +421,7 @@ int SEQUENCE::read_initial_values(TABLE *table_arg)
|
||||
DBUG_RETURN(HA_ERR_LOCK_WAIT_TIMEOUT);
|
||||
}
|
||||
if (!(error= read_stored_values()))
|
||||
initialized= 1;
|
||||
initialized= SEQ_READY_TO_USE;
|
||||
mysql_unlock_tables(thd, lock, 0);
|
||||
if (mdl_lock_used)
|
||||
thd->mdl_context.release_lock(mdl_request.ticket);
|
||||
|
@ -66,6 +66,7 @@ public:
|
||||
class SEQUENCE :public sequence_definition
|
||||
{
|
||||
public:
|
||||
enum seq_init { SEQ_UNINTIALIZED, SEQ_IN_PREPARE, SEQ_READY_TO_USE };
|
||||
SEQUENCE();
|
||||
~SEQUENCE();
|
||||
int read_initial_values(TABLE *table);
|
||||
@ -87,8 +88,9 @@ public:
|
||||
}
|
||||
longlong next_value(TABLE *table, bool second_round, int *error);
|
||||
|
||||
bool initialized; // If row has been read
|
||||
bool all_values_used;
|
||||
seq_init initialized;
|
||||
|
||||
private:
|
||||
TABLE *table;
|
||||
mysql_mutex_t mutex;
|
||||
|
Loading…
x
Reference in New Issue
Block a user