30
30
- For each SQL statement mysql_lock_tables() is called for all involved
32
32
- mysql_lock_tables() will call
33
table_handler->external_lock(session,locktype) for each table.
33
table_handler->external_lock(thd,locktype) for each table.
34
34
This is followed by a call to thr_multi_lock() for all tables.
36
36
- When statement is done, we call mysql_unlock_tables().
37
37
This will call thr_multi_unlock() followed by
38
table_handler->external_lock(session, F_UNLCK) for each table.
38
table_handler->external_lock(thd, F_UNLCK) for each table.
40
40
- Note that mysql_unlock_tables() may be called several times as
41
41
MySQL in some cases can free some tables earlier than others.
43
43
- The above is true both for normal and temporary tables.
45
45
- Temporary non transactional tables are never passed to thr_multi_lock()
46
and we never call external_lock(session, F_UNLOCK) on these.
46
and we never call external_lock(thd, F_UNLOCK) on these.
48
48
When using LOCK TABLES:
50
- LOCK Table will call mysql_lock_tables() for all tables.
50
- LOCK TABLE will call mysql_lock_tables() for all tables.
51
51
mysql_lock_tables() will call
52
table_handler->external_lock(session,locktype) for each table.
52
table_handler->external_lock(thd,locktype) for each table.
53
53
This is followed by a call to thr_multi_lock() for all tables.
55
- For each statement, we will call table_handler->start_stmt(Session)
55
- For each statement, we will call table_handler->start_stmt(THD)
56
56
to inform the table handler that we are using the table.
58
58
The tables used can only be tables used in LOCK TABLES or a
61
- When statement is done, we will call ha_commit_stmt(session);
61
- When statement is done, we will call ha_commit_stmt(thd);
63
63
- When calling UNLOCK TABLES we call mysql_unlock_tables() for all
64
64
tables used in LOCK TABLES
66
If table_handler->external_lock(session, locktype) fails, we call
67
table_handler->external_lock(session, F_UNLCK) for each table that was locked,
66
If table_handler->external_lock(thd, locktype) fails, we call
67
table_handler->external_lock(thd, F_UNLCK) for each table that was locked,
68
68
excluding one that caused failure. That means handler must cleanup itself
69
69
in case external_lock() fails.
72
Change to use malloc() ONLY when using LOCK TABLES command or when
72
Change to use my_malloc() ONLY when using LOCK TABLES command or when
73
73
we are forced to use mysql_lock_merge.
75
#include <drizzled/server_includes.h>
76
#include <drizzled/error.h>
77
#include <mysys/hash.h>
78
#include <mysys/thr_lock.h>
79
#include <drizzled/session.h>
80
#include <drizzled/sql_base.h>
81
#include <drizzled/lock.h>
76
#include "mysql_priv.h"
84
81
@defgroup Locking Locking
91
88
#define GET_LOCK_UNLOCK 1
92
89
#define GET_LOCK_STORE_LOCKS 2
94
static DRIZZLE_LOCK *get_lock_data(Session *session, Table **table,
96
uint32_t flags, Table **write_locked);
97
static int lock_external(Session *session, Table **table,uint32_t count);
98
static int unlock_external(Session *session, Table **table,uint32_t count);
91
static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table,uint count,
92
uint flags, TABLE **write_locked);
93
static int lock_external(THD *thd, TABLE **table,uint count);
94
static int unlock_external(THD *thd, TABLE **table,uint count);
99
95
static void print_lock_error(int error, const char *);
105
101
mysql_lock_tables()
106
session The current thread.
102
thd The current thread.
107
103
tables An array of pointers to the tables to lock.
108
104
count The number of tables to lock.
110
DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK Ignore a global read lock
111
DRIZZLE_LOCK_IGNORE_FLUSH Ignore a flush tables.
112
DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN Instead of reopening altered
106
MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK Ignore a global read lock
107
MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY Ignore SET GLOBAL READ_ONLY
108
MYSQL_LOCK_IGNORE_FLUSH Ignore a flush tables.
109
MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN Instead of reopening altered
113
110
or dropped tables by itself,
114
111
mysql_lock_tables() should
115
112
notify upper level and rely
126
123
static int thr_lock_errno_to_mysql[]=
127
124
{ 0, 1, ER_LOCK_WAIT_TIMEOUT, ER_LOCK_DEADLOCK };
127
Perform semantic checks for mysql_lock_tables.
128
@param thd The current thread
129
@param tables The tables to lock
130
@param count The number of tables to lock
131
@param flags Lock flags
132
@return 0 if all the check passed, non zero if a check failed.
134
int mysql_lock_tables_check(THD *thd, TABLE **tables, uint count, uint flags)
139
DBUG_ENTER("mysql_lock_tables_check");
143
for (i=0 ; i<count; i++)
147
/* Protect against 'fake' partially initialized TABLE_SHARE */
148
DBUG_ASSERT(t->s->table_category != TABLE_UNKNOWN_CATEGORY);
150
if ((t->s->table_category == TABLE_CATEGORY_SYSTEM) &&
151
(t->reginfo.lock_type >= TL_WRITE_ALLOW_WRITE))
158
Locking of system tables is restricted:
159
locking a mix of system and non-system tables in the same lock
160
is prohibited, to prevent contention.
162
if ((system_count > 0) && (system_count < count))
164
my_error(ER_WRONG_LOCK_OF_SYSTEM_TABLE, MYF(0));
131
173
Reset lock type in lock data and free.
160
202
/* Reset lock type. */
161
203
(*ldata)->type= TL_UNLOCK;
163
free((unsigned char*) sql_lock);
205
my_free((uchar*) sql_lock, MYF(0));
168
DRIZZLE_LOCK *mysql_lock_tables(Session *session, Table **tables, uint32_t count,
169
uint32_t flags, bool *need_reopen)
210
MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
211
uint flags, bool *need_reopen)
171
DRIZZLE_LOCK *sql_lock;
172
Table *write_lock_used;
213
MYSQL_LOCK *sql_lock;
214
TABLE *write_lock_used;
217
DBUG_ENTER("mysql_lock_tables");
221
if (mysql_lock_tables_check(thd, tables, count, flags))
179
if (! (sql_lock= get_lock_data(session, tables, count, GET_LOCK_STORE_LOCKS,
226
if (! (sql_lock= get_lock_data(thd, tables, count, GET_LOCK_STORE_LOCKS,
180
227
&write_lock_used)))
183
230
if (global_read_lock && write_lock_used &&
184
! (flags & DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK))
231
! (flags & MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK))
187
234
Someone has issued LOCK ALL TABLES FOR READ and we want a write lock
188
235
Wait until the lock is gone
190
if (wait_if_global_read_lock(session, 1, 1))
237
if (wait_if_global_read_lock(thd, 1, 1))
192
239
/* Clear the lock type of all lock data to avoid reusage. */
193
240
reset_lock_data_and_free(&sql_lock);
196
if (session->version != refresh_version)
243
if (thd->version != refresh_version)
198
245
/* Clear the lock type of all lock data to avoid reusage. */
199
246
reset_lock_data_and_free(&sql_lock);
204
session->set_proc_info("System lock");
205
if (sql_lock->table_count && lock_external(session, sql_lock->table,
251
if (!(flags & MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY) &&
257
Someone has issued SET GLOBAL READ_ONLY=1 and we want a write lock.
258
We do not wait for READ_ONLY=0, and fail.
260
reset_lock_data_and_free(&sql_lock);
261
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
265
thd_proc_info(thd, "System lock");
266
DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info));
267
if (sql_lock->table_count && lock_external(thd, sql_lock->table,
206
268
sql_lock->table_count))
208
270
/* Clear the lock type of all lock data to avoid reusage. */
209
271
reset_lock_data_and_free(&sql_lock);
212
session->set_proc_info("Table lock");
274
thd_proc_info(thd, "Table lock");
275
DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info));
213
276
/* Copy the lock data array. thr_multi_lock() reorders its contens. */
214
277
memcpy(sql_lock->locks + sql_lock->lock_count, sql_lock->locks,
215
278
sql_lock->lock_count * sizeof(*sql_lock->locks));
217
280
rc= thr_lock_errno_to_mysql[(int) thr_multi_lock(sql_lock->locks +
218
281
sql_lock->lock_count,
219
282
sql_lock->lock_count,
221
284
if (rc > 1) /* a timeout or a deadlock */
223
286
if (sql_lock->table_count)
224
unlock_external(session, sql_lock->table, sql_lock->table_count);
287
VOID(unlock_external(thd, sql_lock->table, sql_lock->table_count));
225
288
reset_lock_data_and_free(&sql_lock);
226
289
my_error(rc, MYF(0));
229
292
else if (rc == 1) /* aborted */
231
session->some_tables_deleted=1; // Try again
294
thd->some_tables_deleted=1; // Try again
232
295
sql_lock->lock_count= 0; // Locks are already freed
233
296
// Fall through: unlock, reset lock data, free and retry
235
else if (!session->some_tables_deleted || (flags & DRIZZLE_LOCK_IGNORE_FLUSH))
298
else if (!thd->some_tables_deleted || (flags & MYSQL_LOCK_IGNORE_FLUSH))
238
301
Thread was killed or lock aborted. Let upper level close all
243
else if (!session->open_tables)
306
else if (!thd->open_tables)
245
308
// Only using temporary tables, no need to unlock
246
session->some_tables_deleted=0;
309
thd->some_tables_deleted=0;
249
session->set_proc_info(0);
312
thd_proc_info(thd, 0);
251
314
/* going to retry, unlock all tables */
252
315
if (sql_lock->lock_count)
253
316
thr_multi_unlock(sql_lock->locks, sql_lock->lock_count);
255
318
if (sql_lock->table_count)
256
unlock_external(session, sql_lock->table, sql_lock->table_count);
319
VOID(unlock_external(thd, sql_lock->table, sql_lock->table_count));
259
322
If thr_multi_lock fails it resets lock type for tables, which
263
326
reset_lock_data_and_free(&sql_lock);
265
if (flags & DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN)
328
if (flags & MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN)
270
if (wait_for_tables(session))
333
if (wait_for_tables(thd))
271
334
break; // Couldn't open tables
273
session->set_proc_info(0);
336
thd_proc_info(thd, 0);
276
session->send_kill_message();
339
thd->send_kill_message();
279
mysql_unlock_tables(session,sql_lock);
342
mysql_unlock_tables(thd,sql_lock);
284
session->set_time_after_lock();
347
thd->set_time_after_lock();
348
DBUG_RETURN (sql_lock);
289
static int lock_external(Session *session, Table **tables, uint32_t count)
352
static int lock_external(THD *thd, TABLE **tables, uint count)
292
355
int lock_type,error;
356
DBUG_ENTER("lock_external");
358
DBUG_PRINT("info", ("count %d", count));
293
359
for (i=1 ; i <= count ; i++, tables++)
295
assert((*tables)->reginfo.lock_type >= TL_READ);
361
DBUG_ASSERT((*tables)->reginfo.lock_type >= TL_READ);
296
362
lock_type=F_WRLCK; /* Lock exclusive */
297
363
if ((*tables)->db_stat & HA_READ_ONLY ||
298
364
((*tables)->reginfo.lock_type >= TL_READ &&
299
365
(*tables)->reginfo.lock_type <= TL_READ_NO_INSERT))
300
366
lock_type=F_RDLCK;
302
if ((error=(*tables)->file->ha_external_lock(session,lock_type)))
368
if ((error=(*tables)->file->ha_external_lock(thd,lock_type)))
304
370
print_lock_error(error, (*tables)->file->table_type());
308
(*tables)->file->ha_external_lock(session, F_UNLCK);
374
(*tables)->file->ha_external_lock(thd, F_UNLCK);
309
375
(*tables)->current_lock=F_UNLCK;
316
382
(*tables)->current_lock= lock_type;
323
void mysql_unlock_tables(Session *session, DRIZZLE_LOCK *sql_lock)
389
void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock)
391
DBUG_ENTER("mysql_unlock_tables");
325
392
if (sql_lock->lock_count)
326
393
thr_multi_unlock(sql_lock->locks,sql_lock->lock_count);
327
394
if (sql_lock->table_count)
328
unlock_external(session,sql_lock->table,sql_lock->table_count);
329
free((unsigned char*) sql_lock);
395
VOID(unlock_external(thd,sql_lock->table,sql_lock->table_count));
396
my_free((uchar*) sql_lock,MYF(0));
336
403
This will work even if get_lock_data fails (next unlock will free all)
339
void mysql_unlock_some_tables(Session *session, Table **table,uint32_t count)
406
void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count)
341
DRIZZLE_LOCK *sql_lock;
342
Table *write_lock_used;
343
if ((sql_lock= get_lock_data(session, table, count, GET_LOCK_UNLOCK,
408
MYSQL_LOCK *sql_lock;
409
TABLE *write_lock_used;
410
if ((sql_lock= get_lock_data(thd, table, count, GET_LOCK_UNLOCK,
344
411
&write_lock_used)))
345
mysql_unlock_tables(session, sql_lock);
412
mysql_unlock_tables(thd, sql_lock);
375
443
/* Then do the same for the external locks */
376
444
/* Move all write locked tables first */
377
Table **table=sql_lock->table;
445
TABLE **table=sql_lock->table;
378
446
for (i=found=0 ; i < sql_lock->table_count ; i++)
380
assert(sql_lock->table[i]->lock_position == i);
381
if ((uint32_t) sql_lock->table[i]->reginfo.lock_type >= TL_WRITE_ALLOW_READ)
448
DBUG_ASSERT(sql_lock->table[i]->lock_position == i);
449
if ((uint) sql_lock->table[i]->reginfo.lock_type >= TL_WRITE_ALLOW_READ)
383
std::swap(*table, sql_lock->table[i]);
451
swap_variables(TABLE *, *table, sql_lock->table[i]);
419
487
unlock_external() we call handler::external_lock(F_UNLCK) only
420
488
if table->current_lock is not F_UNLCK.
422
@param session thread context
490
@param thd thread context
423
491
@param locked list of locked tables
424
492
@param table the table to unlock
425
493
@param always_unlock specify explicitly if the legacy side
426
494
effect is desired.
429
void mysql_lock_remove(Session *session, DRIZZLE_LOCK *locked,Table *table,
497
void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table,
430
498
bool always_unlock)
432
if (always_unlock == true)
433
mysql_unlock_some_tables(session, &table, /* table count */ 1);
500
if (always_unlock == TRUE)
501
mysql_unlock_some_tables(thd, &table, /* table count */ 1);
437
505
for (i=0; i < locked->table_count; i++)
439
507
if (locked->table[i] == table)
441
uint32_t j, removed_locks, old_tables;
443
uint32_t lock_data_end;
509
uint j, removed_locks, old_tables;
445
assert(table->lock_position == i);
513
DBUG_ASSERT(table->lock_position == i);
447
515
/* Unlock if not yet unlocked */
448
if (always_unlock == false)
449
mysql_unlock_some_tables(session, &table, /* table count */ 1);
516
if (always_unlock == FALSE)
517
mysql_unlock_some_tables(thd, &table, /* table count */ 1);
451
519
/* Decrement table_count in advance, making below expressions easier */
452
520
old_tables= --locked->table_count;
455
523
removed_locks= table->lock_count;
457
525
/* Move down all table pointers above 'i'. */
458
memmove((locked->table+i), (locked->table+i+1),
459
(old_tables - i) * sizeof(Table*));
526
bmove((char*) (locked->table+i),
527
(char*) (locked->table+i+1),
528
(old_tables - i) * sizeof(TABLE*));
461
530
lock_data_end= table->lock_data_start + table->lock_count;
462
531
/* Move down all lock data pointers above 'table->lock_data_end-1' */
463
memmove((locked->locks + table->lock_data_start),
464
(locked->locks + lock_data_end),
465
(locked->lock_count - lock_data_end) *
466
sizeof(THR_LOCK_DATA*));
532
bmove((char*) (locked->locks + table->lock_data_start),
533
(char*) (locked->locks + lock_data_end),
534
(locked->lock_count - lock_data_end) *
535
sizeof(THR_LOCK_DATA*));
469
538
Fix moved table elements.
492
561
/* Downgrade all locks on a table to new WRITE level from WRITE_ONLY */
494
void mysql_lock_downgrade_write(Session *session, Table *table,
563
void mysql_lock_downgrade_write(THD *thd, TABLE *table,
495
564
thr_lock_type new_lock_type)
497
DRIZZLE_LOCK *locked;
498
Table *write_lock_used;
499
if ((locked = get_lock_data(session, &table, 1, GET_LOCK_UNLOCK,
567
TABLE *write_lock_used;
568
if ((locked = get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK,
500
569
&write_lock_used)))
502
for (uint32_t i=0; i < locked->lock_count; i++)
571
for (uint i=0; i < locked->lock_count; i++)
503
572
thr_downgrade_write_lock(locked->locks[i], new_lock_type);
504
free((unsigned char*) locked);
573
my_free((uchar*) locked,MYF(0));
509
578
/** Abort all other threads waiting to get lock in table. */
511
void mysql_lock_abort(Session *session, Table *table, bool upgrade_lock)
580
void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock)
513
DRIZZLE_LOCK *locked;
514
Table *write_lock_used;
583
TABLE *write_lock_used;
584
DBUG_ENTER("mysql_lock_abort");
516
if ((locked= get_lock_data(session, &table, 1, GET_LOCK_UNLOCK,
586
if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK,
517
587
&write_lock_used)))
519
for (uint32_t i=0; i < locked->lock_count; i++)
589
for (uint i=0; i < locked->lock_count; i++)
520
590
thr_abort_locks(locked->locks[i]->lock, upgrade_lock);
521
free((unsigned char*) locked);
591
my_free((uchar*) locked,MYF(0));
528
598
Abort one thread / table combination.
530
@param session Thread handler
600
@param thd Thread handler
531
601
@param table Table that should be removed from lock queue
536
606
1 Table was locked by at least one other thread
539
bool mysql_lock_abort_for_thread(Session *session, Table *table)
609
bool mysql_lock_abort_for_thread(THD *thd, TABLE *table)
541
DRIZZLE_LOCK *locked;
542
Table *write_lock_used;
612
TABLE *write_lock_used;
614
DBUG_ENTER("mysql_lock_abort_for_thread");
545
if ((locked= get_lock_data(session, &table, 1, GET_LOCK_UNLOCK,
616
if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK,
546
617
&write_lock_used)))
548
for (uint32_t i=0; i < locked->lock_count; i++)
619
for (uint i=0; i < locked->lock_count; i++)
550
621
if (thr_abort_locks_for_thread(locked->locks[i]->lock,
551
622
table->in_use->thread_id))
554
free((unsigned char*) locked);
625
my_free((uchar*) locked,MYF(0));
560
DRIZZLE_LOCK *mysql_lock_merge(DRIZZLE_LOCK *a,DRIZZLE_LOCK *b)
631
MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b)
562
DRIZZLE_LOCK *sql_lock;
563
Table **table, **end_table;
633
MYSQL_LOCK *sql_lock;
634
TABLE **table, **end_table;
635
DBUG_ENTER("mysql_lock_merge");
565
if (!(sql_lock= (DRIZZLE_LOCK*)
566
malloc(sizeof(*sql_lock)+
567
sizeof(THR_LOCK_DATA*)*(a->lock_count+b->lock_count)+
568
sizeof(Table*)*(a->table_count+b->table_count))))
569
return(0); // Fatal error
637
if (!(sql_lock= (MYSQL_LOCK*)
638
my_malloc(sizeof(*sql_lock)+
639
sizeof(THR_LOCK_DATA*)*(a->lock_count+b->lock_count)+
640
sizeof(TABLE*)*(a->table_count+b->table_count),MYF(MY_WME))))
641
DBUG_RETURN(0); // Fatal error
570
642
sql_lock->lock_count=a->lock_count+b->lock_count;
571
643
sql_lock->table_count=a->table_count+b->table_count;
572
644
sql_lock->locks=(THR_LOCK_DATA**) (sql_lock+1);
573
sql_lock->table=(Table**) (sql_lock->locks+sql_lock->lock_count);
645
sql_lock->table=(TABLE**) (sql_lock->locks+sql_lock->lock_count);
574
646
memcpy(sql_lock->locks,a->locks,a->lock_count*sizeof(*a->locks));
575
647
memcpy(sql_lock->locks+a->lock_count,b->locks,
576
648
b->lock_count*sizeof(*b->locks));
577
649
memcpy(sql_lock->table,a->table,a->table_count*sizeof(*a->table));
578
650
memcpy(sql_lock->table+a->table_count,b->table,
579
b->table_count*sizeof(*b->table));
651
b->table_count*sizeof(*b->table));
582
654
Now adjust lock_position and lock_data_start for all objects that was
621
693
!NULL First table from 'haystack' that matches a lock on 'needle'.
624
TableList *mysql_lock_have_duplicate(Session *session, TableList *needle,
696
TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
697
TABLE_LIST *haystack)
627
DRIZZLE_LOCK *mylock;
631
703
THR_LOCK_DATA **lock_locks;
632
704
THR_LOCK_DATA **table_lock_data;
633
705
THR_LOCK_DATA **end_data;
634
706
THR_LOCK_DATA **lock_data2;
635
707
THR_LOCK_DATA **end_data2;
708
DBUG_ENTER("mysql_lock_have_duplicate");
638
711
Table may not be defined for derived or view tables.
721
797
} while (--count);
798
DBUG_RETURN(error_code);
727
803
Get lock structures from table structs and initialize locks.
729
@param session Thread handler
805
@param thd Thread handler
730
806
@param table_ptr Pointer to tables that should be locks
731
807
@param flags One of:
732
808
- GET_LOCK_UNLOCK : If we should send TL_IGNORE to store lock
733
- GET_LOCK_STORE_LOCKS : Store lock info in Table
809
- GET_LOCK_STORE_LOCKS : Store lock info in TABLE
734
810
@param write_lock_used Store pointer to last table with WRITE_ALLOW_WRITE
737
static DRIZZLE_LOCK *get_lock_data(Session *session, Table **table_ptr, uint32_t count,
738
uint32_t flags, Table **write_lock_used)
813
static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
814
uint flags, TABLE **write_lock_used)
740
uint32_t i,tables,lock_count;
741
DRIZZLE_LOCK *sql_lock;
816
uint i,tables,lock_count;
817
MYSQL_LOCK *sql_lock;
742
818
THR_LOCK_DATA **locks, **locks_buf, **locks_start;
743
Table **to, **table_buf;
745
assert((flags == GET_LOCK_UNLOCK) || (flags == GET_LOCK_STORE_LOCKS));
819
TABLE **to, **table_buf;
820
DBUG_ENTER("get_lock_data");
822
DBUG_ASSERT((flags == GET_LOCK_UNLOCK) || (flags == GET_LOCK_STORE_LOCKS));
824
DBUG_PRINT("info", ("count %d", count));
747
825
*write_lock_used=0;
748
826
for (i=tables=lock_count=0 ; i < count ; i++)
750
Table *t= table_ptr[i];
828
TABLE *t= table_ptr[i];
752
830
if (t->s->tmp_table != NON_TRANSACTIONAL_TMP_TABLE)
762
840
update the table values. So the second part of the array is copied
763
841
from the first part immediately before calling thr_multi_lock().
765
if (!(sql_lock= (DRIZZLE_LOCK*)
766
malloc(sizeof(*sql_lock) +
767
sizeof(THR_LOCK_DATA*) * tables * 2 +
768
sizeof(table_ptr) * lock_count)))
843
if (!(sql_lock= (MYSQL_LOCK*)
844
my_malloc(sizeof(*sql_lock) +
845
sizeof(THR_LOCK_DATA*) * tables * 2 +
846
sizeof(table_ptr) * lock_count,
770
849
locks= locks_buf= sql_lock->locks= (THR_LOCK_DATA**) (sql_lock + 1);
771
to= table_buf= sql_lock->table= (Table**) (locks + tables * 2);
850
to= table_buf= sql_lock->table= (TABLE**) (locks + tables * 2);
772
851
sql_lock->table_count=lock_count;
774
853
for (i=0 ; i < count ; i++)
777
856
enum thr_lock_type lock_type;
779
858
if ((table=table_ptr[i])->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE)
781
860
lock_type= table->reginfo.lock_type;
782
assert (lock_type != TL_WRITE_DEFAULT);
861
DBUG_ASSERT (lock_type != TL_WRITE_DEFAULT);
783
862
if (lock_type >= TL_WRITE_ALLOW_WRITE)
785
864
*write_lock_used=table;
789
868
/* Clear the lock type of the lock data that are stored already. */
790
869
sql_lock->lock_count= locks - sql_lock->locks;
791
870
reset_lock_data_and_free(&sql_lock);
874
THR_LOCK_DATA **org_locks = locks;
795
875
locks_start= locks;
796
locks= table->file->store_lock(session, locks,
876
locks= table->file->store_lock(thd, locks,
797
877
(flags & GET_LOCK_UNLOCK) ? TL_IGNORE :
799
879
if (flags & GET_LOCK_STORE_LOCKS)
801
table->lock_position= (uint32_t) (to - table_buf);
802
table->lock_data_start= (uint32_t) (locks_start - locks_buf);
803
table->lock_count= (uint32_t) (locks - locks_start);
881
table->lock_position= (uint) (to - table_buf);
882
table->lock_data_start= (uint) (locks_start - locks_buf);
883
table->lock_count= (uint) (locks - locks_start);
887
for ( ; org_locks != locks ; org_locks++)
888
(*org_locks)->debug_print_param= (void *) table;
808
891
We do not use 'tables', because there are cases where store_lock()
847
int lock_and_wait_for_table_name(Session *session, TableList *table_list)
932
int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list)
849
934
int lock_retcode;
936
DBUG_ENTER("lock_and_wait_for_table_name");
852
if (wait_if_global_read_lock(session, 0, 1))
854
pthread_mutex_lock(&LOCK_open);
855
if ((lock_retcode = lock_table_name(session, table_list, true)) < 0)
938
if (wait_if_global_read_lock(thd, 0, 1))
940
VOID(pthread_mutex_lock(&LOCK_open));
941
if ((lock_retcode = lock_table_name(thd, table_list, TRUE)) < 0)
857
if (lock_retcode && wait_for_locked_table_names(session, table_list))
943
if (lock_retcode && wait_for_locked_table_names(thd, table_list))
859
unlock_table_name(session, table_list);
945
unlock_table_name(thd, table_list);
865
951
pthread_mutex_unlock(&LOCK_open);
866
start_waiting_global_read_lock(session);
952
start_waiting_global_read_lock(thd);
872
958
Put a not open table with an old refresh version in the table cache.
874
@param session Thread handler
960
@param thd Thread handler
875
961
@param table_list Lock first table in this list
876
962
@param check_in_use Do we need to check if table already in use by us
895
981
> 0 table locked, but someone is using it
898
int lock_table_name(Session *session, TableList *table_list, bool check_in_use)
984
int lock_table_name(THD *thd, TABLE_LIST *table_list, bool check_in_use)
901
987
char key[MAX_DBKEY_LENGTH];
902
988
char *db= table_list->db;
904
bool found_locked_table= false;
990
bool found_locked_table= FALSE;
905
991
HASH_SEARCH_STATE state;
992
DBUG_ENTER("lock_table_name");
993
DBUG_PRINT("enter",("db: %s name: %s", db, table_list->table_name));
907
key_length= create_table_def_key(session, key, table_list, 0);
995
key_length= create_table_def_key(thd, key, table_list, 0);
909
997
if (check_in_use)
911
999
/* Only insert the table if we haven't insert it already */
912
for (table=(Table*) hash_first(&open_cache, (unsigned char*)key,
1000
for (table=(TABLE*) hash_first(&open_cache, (uchar*)key,
913
1001
key_length, &state);
915
table = (Table*) hash_next(&open_cache,(unsigned char*) key,
1003
table = (TABLE*) hash_next(&open_cache,(uchar*) key,
916
1004
key_length, &state))
918
1006
if (table->reginfo.lock_type < TL_WRITE)
920
if (table->in_use == session)
921
found_locked_table= true;
1008
if (table->in_use == thd)
1009
found_locked_table= TRUE;
925
if (table->in_use == session)
1013
if (table->in_use == thd)
1015
DBUG_PRINT("info", ("Table is in use"));
927
1016
table->s->version= 0; // Ensure no one can use this
928
1017
table->locked_by_name= 1;
934
if (session->locked_tables && session->locked_tables->table_count &&
935
! find_temporary_table(session, table_list->db, table_list->table_name))
1023
if (thd->locked_tables && thd->locked_tables->table_count &&
1024
! find_temporary_table(thd, table_list->db, table_list->table_name))
937
1026
if (found_locked_table)
938
1027
my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), table_list->alias);
940
1029
my_error(ER_TABLE_NOT_LOCKED, MYF(0), table_list->alias);
945
if (!(table= table_cache_insert_placeholder(session, key, key_length)))
1034
if (!(table= table_cache_insert_placeholder(thd, key, key_length)))
948
1037
table_list->table=table;
950
1039
/* Return 1 if table is in use */
951
return(test(remove_table_from_cache(session, db, table_list->table_name,
1040
DBUG_RETURN(test(remove_table_from_cache(thd, db, table_list->table_name,
952
1041
check_in_use ? RTFC_NO_FLAG : RTFC_WAIT_OTHER_THREAD_FLAG)));
956
void unlock_table_name(Session *,
957
TableList *table_list)
1045
void unlock_table_name(THD *thd, TABLE_LIST *table_list)
959
1047
if (table_list->table)
961
hash_delete(&open_cache, (unsigned char*) table_list->table);
1049
hash_delete(&open_cache, (uchar*) table_list->table);
962
1050
broadcast_refresh();
967
static bool locked_named_table(Session *,
968
TableList *table_list)
1055
static bool locked_named_table(THD *thd, TABLE_LIST *table_list)
970
1057
for (; table_list ; table_list=table_list->next_local)
972
Table *table= table_list->table;
1059
TABLE *table= table_list->table;
975
Table *save_next= table->next;
1062
TABLE *save_next= table->next;
978
1065
result= table_is_used(table_list->table, 0);
988
bool wait_for_locked_table_names(Session *session, TableList *table_list)
1075
bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list)
1078
DBUG_ENTER("wait_for_locked_table_names");
992
1080
safe_mutex_assert_owner(&LOCK_open);
994
while (locked_named_table(session,table_list))
1082
while (locked_named_table(thd,table_list))
1001
wait_for_condition(session, &LOCK_open, &COND_refresh);
1089
wait_for_condition(thd, &LOCK_open, &COND_refresh);
1002
1090
pthread_mutex_lock(&LOCK_open);
1092
DBUG_RETURN(result);
1024
1112
1 Fatal error (end of memory ?)
1027
bool lock_table_names(Session *session, TableList *table_list)
1115
bool lock_table_names(THD *thd, TABLE_LIST *table_list)
1029
1117
bool got_all_locks=1;
1030
TableList *lock_table;
1118
TABLE_LIST *lock_table;
1032
1120
for (lock_table= table_list; lock_table; lock_table= lock_table->next_local)
1035
if ((got_lock=lock_table_name(session,lock_table, true)) < 0)
1123
if ((got_lock=lock_table_name(thd,lock_table, TRUE)) < 0)
1036
1124
goto end; // Fatal error
1038
1126
got_all_locks=0; // Someone is using table
1041
1129
/* If some table was in use, wait until we got the lock */
1042
if (!got_all_locks && wait_for_locked_table_names(session, table_list))
1130
if (!got_all_locks && wait_for_locked_table_names(thd, table_list))
1047
unlock_table_names(session, table_list, lock_table);
1135
unlock_table_names(thd, table_list, lock_table);
1068
1156
@retval FALSE Name lock successfully acquired.
1071
bool lock_table_names_exclusively(Session *session, TableList *table_list)
1159
bool lock_table_names_exclusively(THD *thd, TABLE_LIST *table_list)
1073
if (lock_table_names(session, table_list))
1161
if (lock_table_names(thd, table_list))
1077
1165
Upgrade the table name locks from semi-exclusive to exclusive locks.
1079
for (TableList *table= table_list; table; table= table->next_global)
1167
for (TABLE_LIST *table= table_list; table; table= table->next_global)
1081
1169
if (table->table)
1082
1170
table->table->open_placeholder= 1;
1089
1177
Test is 'table' is protected by an exclusive name lock.
1091
@param[in] session The current thread handler
1179
@param[in] thd The current thread handler
1092
1180
@param[in] table_list Table container containing the single table to be
1103
is_table_name_exclusively_locked_by_this_thread(Session *session,
1104
TableList *table_list)
1191
is_table_name_exclusively_locked_by_this_thread(THD *thd,
1192
TABLE_LIST *table_list)
1106
1194
char key[MAX_DBKEY_LENGTH];
1107
uint32_t key_length;
1109
key_length= create_table_def_key(session, key, table_list, 0);
1111
return is_table_name_exclusively_locked_by_this_thread(session, (unsigned char *)key,
1197
key_length= create_table_def_key(thd, key, table_list, 0);
1199
return is_table_name_exclusively_locked_by_this_thread(thd, (uchar *)key,
1130
is_table_name_exclusively_locked_by_this_thread(Session *session, unsigned char *key,
1218
is_table_name_exclusively_locked_by_this_thread(THD *thd, uchar *key,
1131
1219
int key_length)
1133
1221
HASH_SEARCH_STATE state;
1136
for (table= (Table*) hash_first(&open_cache, key,
1224
for (table= (TABLE*) hash_first(&open_cache, key,
1137
1225
key_length, &state);
1139
table= (Table*) hash_next(&open_cache, key,
1227
table= (TABLE*) hash_next(&open_cache, key,
1140
1228
key_length, &state))
1142
if (table->in_use == session &&
1230
if (table->in_use == thd &&
1143
1231
table->open_placeholder == 1 &&
1144
1232
table->s->version == 0)
1152
1240
Unlock all tables in list with a name lock.
1155
session Thread handle
1157
1245
table_list Names of tables to unlock
1172
1260
1 Fatal error (end of memory ?)
1175
void unlock_table_names(Session *session, TableList *table_list,
1176
TableList *last_table)
1263
void unlock_table_names(THD *thd, TABLE_LIST *table_list,
1264
TABLE_LIST *last_table)
1178
for (TableList *table= table_list;
1266
DBUG_ENTER("unlock_table_names");
1267
for (TABLE_LIST *table= table_list;
1179
1268
table != last_table;
1180
1269
table= table->next_local)
1181
unlock_table_name(session,table);
1270
unlock_table_name(thd,table);
1182
1271
broadcast_refresh();
1187
1276
static void print_lock_error(int error, const char *table)
1279
DBUG_ENTER("print_lock_error");
1191
1281
switch (error) {
1192
1282
case HA_ERR_LOCK_WAIT_TIMEOUT:
1275
1365
If we have merged 1) and 3) into 1), we would have had this deadlock:
1276
1366
imagine thread 1 and 2, in non-autocommit mode, thread 3, and an InnoDB
1278
session1: SELECT * FROM t FOR UPDATE;
1279
session2: UPDATE t SET a=1; # blocked by row-level locks of session1
1280
session3: FLUSH TABLES WITH READ LOCK; # blocked in close_cached_tables() by the
1281
table instance of session2
1282
session1: COMMIT; # blocked by session3.
1283
session1 blocks session2 which blocks session3 which blocks session1: deadlock.
1368
thd1: SELECT * FROM t FOR UPDATE;
1369
thd2: UPDATE t SET a=1; # blocked by row-level locks of thd1
1370
thd3: FLUSH TABLES WITH READ LOCK; # blocked in close_cached_tables() by the
1371
table instance of thd2
1372
thd1: COMMIT; # blocked by thd3.
1373
thd1 blocks thd2 which blocks thd3 which blocks thd1: deadlock.
1285
1375
Note that we need to support that one thread does
1286
1376
FLUSH TABLES WITH READ LOCK; and then COMMIT;
1291
1381
****************************************************************************/
1293
volatile uint32_t global_read_lock=0;
1294
volatile uint32_t global_read_lock_blocks_commit=0;
1295
static volatile uint32_t protect_against_global_read_lock=0;
1296
static volatile uint32_t waiting_for_read_lock=0;
1383
volatile uint global_read_lock=0;
1384
volatile uint global_read_lock_blocks_commit=0;
1385
static volatile uint protect_against_global_read_lock=0;
1386
static volatile uint waiting_for_read_lock=0;
1298
1388
#define GOT_GLOBAL_READ_LOCK 1
1299
1389
#define MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT 2
1301
bool lock_global_read_lock(Session *session)
1391
bool lock_global_read_lock(THD *thd)
1303
if (!session->global_read_lock)
1393
DBUG_ENTER("lock_global_read_lock");
1395
if (!thd->global_read_lock)
1305
1397
const char *old_message;
1306
1398
(void) pthread_mutex_lock(&LOCK_global_read_lock);
1307
old_message=session->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
1399
old_message=thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
1308
1400
"Waiting to get readlock");
1402
("waiting_for: %d protect_against: %d",
1403
waiting_for_read_lock, protect_against_global_read_lock));
1310
1405
waiting_for_read_lock++;
1311
while (protect_against_global_read_lock && !session->killed)
1406
while (protect_against_global_read_lock && !thd->killed)
1312
1407
pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock);
1313
1408
waiting_for_read_lock--;
1314
if (session->killed)
1316
session->exit_cond(old_message);
1411
thd->exit_cond(old_message);
1319
session->global_read_lock= GOT_GLOBAL_READ_LOCK;
1414
thd->global_read_lock= GOT_GLOBAL_READ_LOCK;
1320
1415
global_read_lock++;
1321
session->exit_cond(old_message); // this unlocks LOCK_global_read_lock
1416
thd->exit_cond(old_message); // this unlocks LOCK_global_read_lock
1324
1419
We DON'T set global_read_lock_blocks_commit now, it will be set after
1328
1423
forbid it before, or we can have a 3-thread deadlock if 2 do SELECT FOR
1329
1424
UPDATE and one does FLUSH TABLES WITH READ LOCK).
1335
void unlock_global_read_lock(Session *session)
1430
void unlock_global_read_lock(THD *thd)
1433
DBUG_ENTER("unlock_global_read_lock");
1435
("global_read_lock: %u global_read_lock_blocks_commit: %u",
1436
global_read_lock, global_read_lock_blocks_commit));
1339
1438
pthread_mutex_lock(&LOCK_global_read_lock);
1340
1439
tmp= --global_read_lock;
1341
if (session->global_read_lock == MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT)
1440
if (thd->global_read_lock == MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT)
1342
1441
--global_read_lock_blocks_commit;
1343
1442
pthread_mutex_unlock(&LOCK_global_read_lock);
1344
1443
/* Send the signal outside the mutex to avoid a context switch */
1446
DBUG_PRINT("signal", ("Broadcasting COND_global_read_lock"));
1347
1447
pthread_cond_broadcast(&COND_global_read_lock);
1349
session->global_read_lock= 0;
1449
thd->global_read_lock= 0;
1354
1454
#define must_wait (global_read_lock && \
1355
1455
(is_not_commit || \
1356
1456
global_read_lock_blocks_commit))
1358
bool wait_if_global_read_lock(Session *session, bool abort_on_refresh,
1458
bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh,
1359
1459
bool is_not_commit)
1361
1461
const char *old_message= NULL;
1362
1462
bool result= 0, need_exit_cond;
1463
DBUG_ENTER("wait_if_global_read_lock");
1365
1466
Assert that we do not own LOCK_open. If we would own it, other
1382
1483
This allowance is needed to not break existing versions of innobackup
1383
1484
which do a BEGIN; INSERT; FLUSH TABLES WITH READ LOCK; COMMIT.
1385
return(is_not_commit);
1486
DBUG_RETURN(is_not_commit);
1387
old_message=session->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
1488
old_message=thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
1388
1489
"Waiting for release of readlock");
1389
while (must_wait && ! session->killed &&
1390
(!abort_on_refresh || session->version == refresh_version))
1490
while (must_wait && ! thd->killed &&
1491
(!abort_on_refresh || thd->version == refresh_version))
1493
DBUG_PRINT("signal", ("Waiting for COND_global_read_lock"));
1392
1494
(void) pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock);
1495
DBUG_PRINT("signal", ("Got COND_global_read_lock"));
1394
if (session->killed)
1397
1500
if (!abort_on_refresh && !result)
1401
1504
and if old_message is set
1403
1506
if (unlikely(need_exit_cond))
1404
session->exit_cond(old_message); // this unlocks LOCK_global_read_lock
1507
thd->exit_cond(old_message); // this unlocks LOCK_global_read_lock
1406
1509
pthread_mutex_unlock(&LOCK_global_read_lock);
1510
DBUG_RETURN(result);
1411
void start_waiting_global_read_lock(Session *session)
1514
void start_waiting_global_read_lock(THD *thd)
1414
if (unlikely(session->global_read_lock))
1517
DBUG_ENTER("start_waiting_global_read_lock");
1518
if (unlikely(thd->global_read_lock))
1416
1520
(void) pthread_mutex_lock(&LOCK_global_read_lock);
1417
1521
tmp= (!--protect_against_global_read_lock &&
1418
1522
(waiting_for_read_lock || global_read_lock_blocks_commit));
1419
1523
(void) pthread_mutex_unlock(&LOCK_global_read_lock);
1421
1525
pthread_cond_broadcast(&COND_global_read_lock);
1426
bool make_global_read_lock_block_commit(Session *session)
1530
bool make_global_read_lock_block_commit(THD *thd)
1429
1533
const char *old_message;
1534
DBUG_ENTER("make_global_read_lock_block_commit");
1431
1536
If we didn't succeed lock_global_read_lock(), or if we already suceeded
1432
1537
make_global_read_lock_block_commit(), do nothing.
1434
if (session->global_read_lock != GOT_GLOBAL_READ_LOCK)
1539
if (thd->global_read_lock != GOT_GLOBAL_READ_LOCK)
1436
1541
pthread_mutex_lock(&LOCK_global_read_lock);
1437
1542
/* increment this BEFORE waiting on cond (otherwise race cond) */
1438
1543
global_read_lock_blocks_commit++;
1439
old_message= session->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
1544
/* For testing we set up some blocking, to see if we can be killed */
1545
DBUG_EXECUTE_IF("make_global_read_lock_block_commit_loop",
1546
protect_against_global_read_lock++;);
1547
old_message= thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
1440
1548
"Waiting for all running commits to finish");
1441
while (protect_against_global_read_lock && !session->killed)
1549
while (protect_against_global_read_lock && !thd->killed)
1442
1550
pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock);
1443
if ((error= test(session->killed)))
1551
DBUG_EXECUTE_IF("make_global_read_lock_block_commit_loop",
1552
protect_against_global_read_lock--;);
1553
if ((error= test(thd->killed)))
1444
1554
global_read_lock_blocks_commit--; // undo what we did
1446
session->global_read_lock= MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT;
1447
session->exit_cond(old_message); // this unlocks LOCK_global_read_lock
1556
thd->global_read_lock= MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT;
1557
thd->exit_cond(old_message); // this unlocks LOCK_global_read_lock
1493
1603
-1 Error: no recovery possible.
1496
int try_transactional_lock(Session *session, TableList *table_list)
1606
int try_transactional_lock(THD *thd, TABLE_LIST *table_list)
1498
uint32_t dummy_counter;
1611
DBUG_ENTER("try_transactional_lock");
1502
1613
/* Need to open the tables to be able to access engine methods. */
1503
if (open_tables(session, &table_list, &dummy_counter, 0))
1614
if (open_tables(thd, &table_list, &dummy_counter, 0))
1505
1616
/* purecov: begin tested */
1617
DBUG_PRINT("lock_info", ("aborting, open_tables failed"));
1507
1619
/* purecov: end */
1510
1622
/* Required by InnoDB. */
1511
session->in_lock_tables= true;
1623
thd->in_lock_tables= TRUE;
1513
if ((error= set_handler_table_locks(session, table_list, true)))
1625
if ((error= set_handler_table_locks(thd, table_list, TRUE)))
1516
1628
Not all transactional locks could be taken. If the error was
1528
1641
successfully taken transactional locks. They go away at end of
1529
1642
transaction anyway.
1644
DBUG_PRINT("lock_info", ("fall back to non-trans lock: no SE support"));
1535
1649
/* We need to explicitly commit if autocommit mode is active. */
1536
(void) ha_autocommit_or_rollback(session, 0);
1650
(void) ha_autocommit_or_rollback(thd, 0);
1537
1651
/* Close the tables. The locks (if taken) persist in the storage engines. */
1538
close_tables_for_reopen(session, &table_list);
1539
session->in_lock_tables= false;
1652
close_tables_for_reopen(thd, &table_list);
1653
thd->in_lock_tables= FALSE;
1654
DBUG_PRINT("lock_info", ("result: %d", result));
1655
DBUG_RETURN(result);
1566
1681
-1 Error: Lock conversion is prohibited.
1569
int check_transactional_lock(Session *, TableList *table_list)
1684
int check_transactional_lock(THD *thd, TABLE_LIST *table_list)
1688
char warn_buff[MYSQL_ERRMSG_SIZE];
1689
DBUG_ENTER("check_transactional_lock");
1574
1691
for (tlist= table_list; tlist; tlist= tlist->next_global)
1693
DBUG_PRINT("lock_info", ("checking table: '%s'", tlist->table_name));
1578
1696
Unfortunately we cannot use tlist->placeholder() here. This method
1579
1697
returns TRUE if the table is not open, which is always the case
1580
here. Whenever the definition of TableList::placeholder() is
1698
here. Whenever the definition of TABLE_LIST::placeholder() is
1581
1699
changed, probably this condition needs to be changed too.
1583
1701
if (tlist->derived || tlist->schema_table || !tlist->lock_transactional)
1703
DBUG_PRINT("lock_info", ("skipping placeholder: %d transactional: %d",
1704
tlist->placeholder(),
1705
tlist->lock_transactional));
1717
/* We must not convert the lock method within an active transaction. */
1718
if (thd->active_transaction())
1720
my_error(ER_NO_AUTO_CONVERT_LOCK_TRANSACTION, MYF(0),
1721
tlist->alias ? tlist->alias : tlist->table_name);
1726
/* Warn about the conversion. */
1727
my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_WARN_AUTO_CONVERT_LOCK),
1728
tlist->alias ? tlist->alias : tlist->table_name);
1729
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1730
ER_WARN_AUTO_CONVERT_LOCK, warn_buff);
1733
DBUG_PRINT("lock_info", ("result: %d", result));
1734
DBUG_RETURN(result);
1650
1788
Non-transactional locks do not support a lock_timeout.
1652
1790
lock_timeout= tlist->top_table()->lock_timeout;
1791
DBUG_PRINT("lock_info",
1792
("table: '%s' tlist==top_table: %d lock_timeout: %d",
1793
tlist->table_name, tlist==tlist->top_table(), lock_timeout));
1655
1796
For warning/error reporting we need to set the intended lock
1656
method in the TableList object. It will be used later by
1797
method in the TABLE_LIST object. It will be used later by
1657
1798
check_transactional_lock(). The lock method is not set if this
1658
1799
table belongs to a view. We can safely set it to transactional
1659
1800
locking here. Even for non-view tables. This function is not
1660
1801
called if non-transactional locking was requested for any
1663
tlist->lock_transactional= true;
1804
tlist->lock_transactional= TRUE;