@@ -275,69 +275,99 @@ bool prepare_sequence_fields(THD *thd, List<Create_field> *fields)
275
275
There is also a MDL lock on the table.
276
276
*/
277
277
278
- bool sequence_insert (THD *thd, LEX *lex, TABLE_LIST *table_list )
278
+ bool sequence_insert (THD *thd, LEX *lex, TABLE_LIST *org_table_list )
279
279
{
280
280
int error;
281
281
TABLE *table;
282
- TABLE_LIST::enum_open_strategy save_open_strategy;
283
282
Reprepare_observer *save_reprepare_observer;
284
283
sequence_definition *seq= lex->create_info .seq_create_info ;
285
- bool temporary_table= table_list->table != 0 ;
286
- TABLE_LIST *org_next_global= table_list->next_global ;
284
+ bool temporary_table= org_table_list->table != 0 ;
285
+ Open_tables_backup open_tables_backup;
286
+ Query_tables_list query_tables_list_backup;
287
+ TABLE_LIST table_list; // For sequence table
287
288
DBUG_ENTER (" sequence_insert" );
288
289
290
+ /*
291
+ seq is 0 if sequence was created with CREATE TABLE instead of
292
+ CREATE SEQUENCE
293
+ */
294
+ if (!seq)
295
+ {
296
+ if (!(seq= new (thd->mem_root ) sequence_definition))
297
+ DBUG_RETURN (TRUE );
298
+ }
299
+
289
300
/* If not temporary table */
290
301
if (!temporary_table)
291
302
{
292
- /* Table was locked as part of create table. Free it but keep MDL locks */
293
- close_thread_tables (thd);
294
- table_list->next_global = 0 ; // Close LIKE TABLE
295
- table_list->lock_type = TL_WRITE_DEFAULT;
296
- table_list->updating = 1 ;
303
+ /*
304
+ The following code works like open_system_tables_for_read() and
305
+ close_system_tables()
306
+ The idea is:
307
+ - Copy the table_list object for the sequence that was created
308
+ - Backup the current state of open tables and create a new
309
+ environment for open tables without any tables opened
310
+ - open the newly sequence table for write
311
+ This is safe as the sequence table has a mdl lock thanks to the
312
+ create sequence statement that is calling this function
313
+ */
314
+
315
+ table_list.init_one_table (&org_table_list->db ,
316
+ &org_table_list->table_name ,
317
+ NULL , TL_WRITE_DEFAULT);
318
+ table_list.updating = 1 ;
319
+ table_list.open_strategy = TABLE_LIST::OPEN_IF_EXISTS;
320
+ table_list.open_type = OT_BASE_ONLY;
321
+
322
+ DBUG_ASSERT (!thd->locked_tables_mode ||
323
+ (thd->variables .option_bits & OPTION_TABLE_LOCK));
324
+ lex->reset_n_backup_query_tables_list (&query_tables_list_backup);
325
+ thd->reset_n_backup_open_tables_state (&open_tables_backup);
326
+
297
327
/*
298
328
The FOR CREATE flag is needed to ensure that ha_open() doesn't try to
299
329
read the not yet existing row in the sequence table
300
330
*/
301
331
thd->open_options |= HA_OPEN_FOR_CREATE;
302
- save_open_strategy= table_list->open_strategy ;
303
332
/*
304
333
We have to reset the reprepare observer to be able to open the
305
334
table under prepared statements.
306
335
*/
307
336
save_reprepare_observer= thd->m_reprepare_observer ;
308
337
thd->m_reprepare_observer = 0 ;
309
- table_list->open_strategy = TABLE_LIST::OPEN_IF_EXISTS;
310
- table_list->open_type = OT_BASE_ONLY;
311
- error= open_and_lock_tables (thd, table_list, FALSE ,
338
+ lex->sql_command = SQLCOM_CREATE_SEQUENCE;
339
+ error= open_and_lock_tables (thd, &table_list, FALSE ,
312
340
MYSQL_LOCK_IGNORE_TIMEOUT |
313
341
MYSQL_OPEN_HAS_MDL_LOCK);
314
- table_list->open_strategy = save_open_strategy;
315
342
thd->open_options &= ~HA_OPEN_FOR_CREATE;
316
343
thd->m_reprepare_observer = save_reprepare_observer;
317
- table_list->next_global = org_next_global;
318
344
if (error)
319
- DBUG_RETURN (TRUE ); /* purify inspected */
320
- }
321
-
322
- table= table_list->table ;
323
-
324
- /*
325
- seq is 0 if sequence was created with CREATE TABLE instead of
326
- CREATE SEQUENCE
327
- */
328
- if (!seq)
329
- {
330
- if (!(seq= new (thd->mem_root ) sequence_definition))
331
- DBUG_RETURN (TRUE ); // EOM
345
+ {
346
+ lex->restore_backup_query_tables_list (&query_tables_list_backup);
347
+ thd->restore_backup_open_tables_state (&open_tables_backup);
348
+ DBUG_RETURN (error);
349
+ }
350
+ table= table_list.table ;
332
351
}
352
+ else
353
+ table= org_table_list->table ;
333
354
334
355
seq->reserved_until = seq->start ;
335
356
error= seq->write_initial_sequence (table);
336
357
337
358
trans_commit_stmt (thd);
338
359
trans_commit_implicit (thd);
360
+
339
361
if (!temporary_table)
362
+ {
340
363
close_thread_tables (thd);
364
+ lex->restore_backup_query_tables_list (&query_tables_list_backup);
365
+ thd->restore_backup_open_tables_state (&open_tables_backup);
366
+
367
+ /* OPTION_TABLE_LOCK was reset in trans_commit_implicit */
368
+ if (thd->locked_tables_mode )
369
+ thd->variables .option_bits |= OPTION_TABLE_LOCK;
370
+ }
341
371
DBUG_RETURN (error);
342
372
}
343
373
0 commit comments