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(thd, F_UNLOCK) on these.
46
and we never call external_lock(session, 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(thd,locktype) for each table.
52
table_handler->external_lock(session,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(THD)
55
- For each statement, we will call table_handler->start_stmt(Session)
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(thd);
61
- When statement is done, we will call ha_commit_stmt(session);
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(thd, locktype) fails, we call
67
table_handler->external_lock(thd, F_UNLCK) for each table that was locked,
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,
68
68
excluding one that caused failure. That means handler must cleanup itself
69
69
in case external_lock() fails.
72
Change to use my_malloc() ONLY when using LOCK TABLES command or when
72
Change to use malloc() ONLY when using LOCK TABLES command or when
73
73
we are forced to use mysql_lock_merge.
75
75
#include <drizzled/server_includes.h>
76
#include <drizzled/drizzled_error_messages.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>
79
84
@defgroup Locking Locking
199
if (!(flags & DRIZZLE_LOCK_IGNORE_GLOBAL_READ_ONLY) &&
205
Someone has issued SET GLOBAL READ_ONLY=1 and we want a write lock.
206
We do not wait for READ_ONLY=0, and fail.
208
reset_lock_data_and_free(&sql_lock);
209
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
213
thd_proc_info(thd, "System lock");
214
if (sql_lock->table_count && lock_external(thd, sql_lock->table,
200
session->set_proc_info("System lock");
201
if (sql_lock->table_count && lock_external(session, sql_lock->table,
215
202
sql_lock->table_count))
217
204
/* Clear the lock type of all lock data to avoid reusage. */
218
205
reset_lock_data_and_free(&sql_lock);
221
thd_proc_info(thd, "Table lock");
208
session->set_proc_info("Table lock");
222
209
/* Copy the lock data array. thr_multi_lock() reorders its contens. */
223
210
memcpy(sql_lock->locks + sql_lock->lock_count, sql_lock->locks,
224
211
sql_lock->lock_count * sizeof(*sql_lock->locks));
428
415
unlock_external() we call handler::external_lock(F_UNLCK) only
429
416
if table->current_lock is not F_UNLCK.
431
@param thd thread context
418
@param session thread context
432
419
@param locked list of locked tables
433
420
@param table the table to unlock
434
421
@param always_unlock specify explicitly if the legacy side
435
422
effect is desired.
438
void mysql_lock_remove(THD *thd, DRIZZLE_LOCK *locked,TABLE *table,
441
if (always_unlock == true)
442
mysql_unlock_some_tables(thd, &table, /* table count */ 1);
446
for (i=0; i < locked->table_count; i++)
448
if (locked->table[i] == table)
450
uint j, removed_locks, old_tables;
454
assert(table->lock_position == i);
456
/* Unlock if not yet unlocked */
457
if (always_unlock == false)
458
mysql_unlock_some_tables(thd, &table, /* table count */ 1);
460
/* Decrement table_count in advance, making below expressions easier */
461
old_tables= --locked->table_count;
463
/* The table has 'removed_locks' lock data elements in locked->locks */
464
removed_locks= table->lock_count;
466
/* Move down all table pointers above 'i'. */
467
memcpy((locked->table+i), (locked->table+i+1),
468
(old_tables - i) * sizeof(TABLE*));
470
lock_data_end= table->lock_data_start + table->lock_count;
471
/* Move down all lock data pointers above 'table->lock_data_end-1' */
472
memcpy((locked->locks + table->lock_data_start),
473
(locked->locks + lock_data_end),
474
(locked->lock_count - lock_data_end) *
475
sizeof(THR_LOCK_DATA*));
478
Fix moved table elements.
479
lock_position is the index in the 'locked->table' array,
480
it must be fixed by one.
481
table->lock_data_start is pointer to the lock data for this table
482
in the 'locked->locks' array, they must be fixed by 'removed_locks',
483
the lock data count of the removed table.
485
for (j= i ; j < old_tables; j++)
487
tbl= locked->table[j];
488
tbl->lock_position--;
489
assert(tbl->lock_position == j);
490
tbl->lock_data_start-= removed_locks;
493
/* Finally adjust lock_count. */
494
locked->lock_count-= removed_locks;
501
/* Downgrade all locks on a table to new WRITE level from WRITE_ONLY */
503
void mysql_lock_downgrade_write(THD *thd, TABLE *table,
504
thr_lock_type new_lock_type)
506
DRIZZLE_LOCK *locked;
507
TABLE *write_lock_used;
508
if ((locked = get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK,
511
for (uint i=0; i < locked->lock_count; i++)
512
thr_downgrade_write_lock(locked->locks[i], new_lock_type);
513
my_free((uchar*) locked,MYF(0));
425
void mysql_lock_remove(Session *session, Table *table)
427
mysql_unlock_some_tables(session, &table, /* table count */ 1);
518
431
/** Abort all other threads waiting to get lock in table. */
520
void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock)
433
void mysql_lock_abort(Session *session, Table *table)
522
435
DRIZZLE_LOCK *locked;
523
TABLE *write_lock_used;
436
Table *write_lock_used;
525
if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK,
438
if ((locked= get_lock_data(session, &table, 1, false,
526
439
&write_lock_used)))
528
for (uint i=0; i < locked->lock_count; i++)
529
thr_abort_locks(locked->locks[i]->lock, upgrade_lock);
530
my_free((uchar*) locked,MYF(0));
441
for (uint32_t x= 0; x < locked->lock_count; x++)
442
thr_abort_locks(locked->locks[x]->lock);
443
free((unsigned char*) locked);
537
449
Abort one thread / table combination.
539
@param thd Thread handler
451
@param session Thread handler
540
452
@param table Table that should be removed from lock queue
545
457
1 Table was locked by at least one other thread
548
bool mysql_lock_abort_for_thread(THD *thd, TABLE *table)
460
bool mysql_lock_abort_for_thread(Session *session, Table *table)
550
462
DRIZZLE_LOCK *locked;
551
TABLE *write_lock_used;
463
Table *write_lock_used;
552
464
bool result= false;
554
if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK,
466
if ((locked= get_lock_data(session, &table, 1, false,
555
467
&write_lock_used)))
557
for (uint i=0; i < locked->lock_count; i++)
469
for (uint32_t i=0; i < locked->lock_count; i++)
559
471
if (thr_abort_locks_for_thread(locked->locks[i]->lock,
560
472
table->in_use->thread_id))
563
my_free((uchar*) locked,MYF(0));
569
DRIZZLE_LOCK *mysql_lock_merge(DRIZZLE_LOCK *a,DRIZZLE_LOCK *b)
571
DRIZZLE_LOCK *sql_lock;
572
TABLE **table, **end_table;
574
if (!(sql_lock= (DRIZZLE_LOCK*)
575
my_malloc(sizeof(*sql_lock)+
576
sizeof(THR_LOCK_DATA*)*(a->lock_count+b->lock_count)+
577
sizeof(TABLE*)*(a->table_count+b->table_count),MYF(MY_WME))))
578
return(0); // Fatal error
579
sql_lock->lock_count=a->lock_count+b->lock_count;
580
sql_lock->table_count=a->table_count+b->table_count;
581
sql_lock->locks=(THR_LOCK_DATA**) (sql_lock+1);
582
sql_lock->table=(TABLE**) (sql_lock->locks+sql_lock->lock_count);
583
memcpy(sql_lock->locks,a->locks,a->lock_count*sizeof(*a->locks));
584
memcpy(sql_lock->locks+a->lock_count,b->locks,
585
b->lock_count*sizeof(*b->locks));
586
memcpy(sql_lock->table,a->table,a->table_count*sizeof(*a->table));
587
memcpy(sql_lock->table+a->table_count,b->table,
588
b->table_count*sizeof(*b->table));
591
Now adjust lock_position and lock_data_start for all objects that was
592
moved in 'b' (as there is now all objects in 'a' before these).
594
for (table= sql_lock->table + a->table_count,
595
end_table= table + b->table_count;
599
(*table)->lock_position+= a->table_count;
600
(*table)->lock_data_start+= a->lock_count;
603
/* Delete old, not needed locks */
604
my_free((uchar*) a,MYF(0));
605
my_free((uchar*) b,MYF(0));
475
free((unsigned char*) locked);
720
589
if ((*table)->current_lock != F_UNLCK)
722
591
(*table)->current_lock = F_UNLCK;
723
if ((error=(*table)->file->ha_external_lock(thd, F_UNLCK)))
592
if ((error=(*table)->cursor->ha_external_lock(session, F_UNLCK)))
725
594
error_code=error;
726
print_lock_error(error_code, (*table)->file->table_type());
595
print_lock_error(error_code, (*table)->cursor->engine->getName().c_str());
730
599
} while (--count);
736
605
Get lock structures from table structs and initialize locks.
738
@param thd Thread handler
607
@param session Thread handler
739
608
@param table_ptr Pointer to tables that should be locks
741
- GET_LOCK_UNLOCK : If we should send TL_IGNORE to store lock
742
- GET_LOCK_STORE_LOCKS : Store lock info in TABLE
609
@param should_lock One of:
610
- false : If we should send TL_IGNORE to store lock
611
- true : Store lock info in Table
743
612
@param write_lock_used Store pointer to last table with WRITE_ALLOW_WRITE
746
static DRIZZLE_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
747
uint flags, TABLE **write_lock_used)
615
static DRIZZLE_LOCK *get_lock_data(Session *session, Table **table_ptr, uint32_t count,
616
bool should_lock, Table **write_lock_used)
749
uint i,tables,lock_count;
618
uint32_t i,tables,lock_count;
750
619
DRIZZLE_LOCK *sql_lock;
751
620
THR_LOCK_DATA **locks, **locks_buf, **locks_start;
752
TABLE **to, **table_buf;
754
assert((flags == GET_LOCK_UNLOCK) || (flags == GET_LOCK_STORE_LOCKS));
621
Table **to, **table_buf;
756
623
*write_lock_used=0;
757
for (i=tables=lock_count=0 ; i < count ; i++)
624
for (i= tables= lock_count= 0 ; i < count ; i++)
759
TABLE *t= table_ptr[i];
626
Table *t= table_ptr[i];
761
628
if (t->s->tmp_table != NON_TRANSACTIONAL_TMP_TABLE)
763
tables+= t->file->lock_count();
829
695
And in the FLUSH case, the memory is released quickly anyway.
831
697
sql_lock->lock_count= locks - locks_buf;
836
/*****************************************************************************
837
Lock table based on the name.
838
This is used when we need total access to a closed, not open table
839
*****************************************************************************/
842
Lock and wait for the named lock.
844
@param thd Thread handler
845
@param table_list Lock first table in this list
849
Works together with global read lock.
857
int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list)
862
if (wait_if_global_read_lock(thd, 0, 1))
864
VOID(pthread_mutex_lock(&LOCK_open));
865
if ((lock_retcode = lock_table_name(thd, table_list, true)) < 0)
867
if (lock_retcode && wait_for_locked_table_names(thd, table_list))
869
unlock_table_name(thd, table_list);
875
pthread_mutex_unlock(&LOCK_open);
876
start_waiting_global_read_lock(thd);
882
704
Put a not open table with an old refresh version in the table cache.
884
@param thd Thread handler
706
@param session Thread handler
885
707
@param table_list Lock first table in this list
886
708
@param check_in_use Do we need to check if table already in use by us
905
727
> 0 table locked, but someone is using it
908
int lock_table_name(THD *thd, TABLE_LIST *table_list, bool check_in_use)
730
int lock_table_name(Session *session, TableList *table_list, bool check_in_use)
911
733
char key[MAX_DBKEY_LENGTH];
912
734
char *db= table_list->db;
914
736
bool found_locked_table= false;
915
737
HASH_SEARCH_STATE state;
917
key_length= create_table_def_key(thd, key, table_list, 0);
739
key_length= table_list->create_table_def_key(key);
919
741
if (check_in_use)
921
743
/* Only insert the table if we haven't insert it already */
922
for (table=(TABLE*) hash_first(&open_cache, (uchar*)key,
744
for (table=(Table*) hash_first(&open_cache, (unsigned char*)key,
923
745
key_length, &state);
925
table = (TABLE*) hash_next(&open_cache,(uchar*) key,
747
table = (Table*) hash_next(&open_cache,(unsigned char*) key,
926
748
key_length, &state))
928
750
if (table->reginfo.lock_type < TL_WRITE)
930
if (table->in_use == thd)
752
if (table->in_use == session)
931
753
found_locked_table= true;
935
if (table->in_use == thd)
757
if (table->in_use == session)
937
759
table->s->version= 0; // Ensure no one can use this
938
760
table->locked_by_name= 1;
944
if (thd->locked_tables && thd->locked_tables->table_count &&
945
! find_temporary_table(thd, table_list->db, table_list->table_name))
947
if (found_locked_table)
948
my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), table_list->alias);
950
my_error(ER_TABLE_NOT_LOCKED, MYF(0), table_list->alias);
955
if (!(table= table_cache_insert_placeholder(thd, key, key_length)))
766
if (!(table= session->table_cache_insert_placeholder(key, key_length)))
958
769
table_list->table=table;
960
771
/* Return 1 if table is in use */
961
return(test(remove_table_from_cache(thd, db, table_list->table_name,
772
return(test(remove_table_from_cache(session, db, table_list->table_name,
962
773
check_in_use ? RTFC_NO_FLAG : RTFC_WAIT_OTHER_THREAD_FLAG)));
966
void unlock_table_name(THD *thd __attribute__((unused)),
967
TABLE_LIST *table_list)
777
void unlock_table_name(TableList *table_list)
969
779
if (table_list->table)
971
hash_delete(&open_cache, (uchar*) table_list->table);
781
hash_delete(&open_cache, (unsigned char*) table_list->table);
972
782
broadcast_refresh();
977
static bool locked_named_table(THD *thd __attribute__((unused)),
978
TABLE_LIST *table_list)
787
static bool locked_named_table(TableList *table_list)
980
789
for (; table_list ; table_list=table_list->next_local)
982
TABLE *table= table_list->table;
791
Table *table= table_list->table;
985
TABLE *save_next= table->next;
794
Table *save_next= table->next;
988
797
result= table_is_used(table_list->table, 0);
1022
831
- One must have a lock on LOCK_open when calling this
1024
@param thd Thread handle
1025
833
@param table_list Names of tables to lock
1028
If you are just locking one table, you should use
1029
lock_and_wait_for_table_name().
1034
838
1 Fatal error (end of memory ?)
1037
bool lock_table_names(THD *thd, TABLE_LIST *table_list)
841
bool lock_table_names(Session *session, TableList *table_list)
1039
843
bool got_all_locks=1;
1040
TABLE_LIST *lock_table;
844
TableList *lock_table;
1042
846
for (lock_table= table_list; lock_table; lock_table= lock_table->next_local)
1045
if ((got_lock=lock_table_name(thd,lock_table, true)) < 0)
849
if ((got_lock= lock_table_name(session,lock_table, true)) < 0)
1046
850
goto end; // Fatal error
1048
852
got_all_locks=0; // Someone is using table
1051
855
/* If some table was in use, wait until we got the lock */
1052
if (!got_all_locks && wait_for_locked_table_names(thd, table_list))
856
if (!got_all_locks && wait_for_locked_table_names(session, table_list))
1057
unlock_table_names(thd, table_list, lock_table);
861
unlock_table_names(table_list, lock_table);
1063
868
Unlock all tables in list with a name lock.
1065
@param thd Thread handle.
870
@param session Thread handle.
1066
871
@param table_list Names of tables to lock.
1069
This function needs to be protected by LOCK_open. If we're
874
This function needs to be protected by LOCK_open. If we're
1070
875
under LOCK TABLES, this function does not work as advertised. Namely,
1071
876
it does not exclude other threads from using this table and does not
1072
877
put an exclusive name lock on this table into the table cache.
1099
Test is 'table' is protected by an exclusive name lock.
1101
@param[in] thd The current thread handler
1102
@param[in] table_list Table container containing the single table to be
1105
@note Needs to be protected by LOCK_open mutex.
1107
@return Error status code
1108
@retval TRUE Table is protected
1109
@retval FALSE Table is not protected
1113
is_table_name_exclusively_locked_by_this_thread(THD *thd,
1114
TABLE_LIST *table_list)
1116
char key[MAX_DBKEY_LENGTH];
1119
key_length= create_table_def_key(thd, key, table_list, 0);
1121
return is_table_name_exclusively_locked_by_this_thread(thd, (uchar *)key,
1127
Test is 'table key' is protected by an exclusive name lock.
1129
@param[in] thd The current thread handler.
1131
@param[in] key_length
1133
@note Needs to be protected by LOCK_open mutex
1135
@retval TRUE Table is protected
1136
@retval FALSE Table is not protected
1140
is_table_name_exclusively_locked_by_this_thread(THD *thd, uchar *key,
1143
HASH_SEARCH_STATE state;
1146
for (table= (TABLE*) hash_first(&open_cache, key,
1147
key_length, &state);
1149
table= (TABLE*) hash_next(&open_cache, key,
1150
key_length, &state))
1152
if (table->in_use == thd &&
1153
table->open_placeholder == 1 &&
1154
table->s->version == 0)
1162
904
Unlock all tables in list with a name lock.
1167
907
table_list Names of tables to unlock
1169
909
last_table Don't unlock any tables after this one.
1301
1037
****************************************************************************/
1303
volatile uint global_read_lock=0;
1304
volatile uint global_read_lock_blocks_commit=0;
1305
static volatile uint protect_against_global_read_lock=0;
1306
static volatile uint waiting_for_read_lock=0;
1039
volatile uint32_t global_read_lock=0;
1040
volatile uint32_t global_read_lock_blocks_commit=0;
1041
static volatile uint32_t protect_against_global_read_lock=0;
1042
static volatile uint32_t waiting_for_read_lock=0;
1308
1044
#define GOT_GLOBAL_READ_LOCK 1
1309
1045
#define MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT 2
1311
bool lock_global_read_lock(THD *thd)
1047
bool lock_global_read_lock(Session *session)
1313
if (!thd->global_read_lock)
1049
if (!session->global_read_lock)
1315
1051
const char *old_message;
1316
1052
(void) pthread_mutex_lock(&LOCK_global_read_lock);
1317
old_message=thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
1053
old_message=session->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
1318
1054
"Waiting to get readlock");
1320
1056
waiting_for_read_lock++;
1321
while (protect_against_global_read_lock && !thd->killed)
1057
while (protect_against_global_read_lock && !session->killed)
1322
1058
pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock);
1323
1059
waiting_for_read_lock--;
1060
if (session->killed)
1326
thd->exit_cond(old_message);
1062
session->exit_cond(old_message);
1329
thd->global_read_lock= GOT_GLOBAL_READ_LOCK;
1065
session->global_read_lock= GOT_GLOBAL_READ_LOCK;
1330
1066
global_read_lock++;
1331
thd->exit_cond(old_message); // this unlocks LOCK_global_read_lock
1067
session->exit_cond(old_message); // this unlocks LOCK_global_read_lock
1334
1070
We DON'T set global_read_lock_blocks_commit now, it will be set after
1441
1175
If we didn't succeed lock_global_read_lock(), or if we already suceeded
1442
1176
make_global_read_lock_block_commit(), do nothing.
1444
if (thd->global_read_lock != GOT_GLOBAL_READ_LOCK)
1178
if (session->global_read_lock != GOT_GLOBAL_READ_LOCK)
1446
1180
pthread_mutex_lock(&LOCK_global_read_lock);
1447
1181
/* increment this BEFORE waiting on cond (otherwise race cond) */
1448
1182
global_read_lock_blocks_commit++;
1449
/* For testing we set up some blocking, to see if we can be killed */
1450
protect_against_global_read_lock++;
1451
old_message= thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
1183
old_message= session->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
1452
1184
"Waiting for all running commits to finish");
1453
while (protect_against_global_read_lock && !thd->killed)
1185
while (protect_against_global_read_lock && !session->killed)
1454
1186
pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock);
1455
protect_against_global_read_lock--;
1456
if ((error= test(thd->killed)))
1187
if ((error= test(session->killed)))
1457
1188
global_read_lock_blocks_commit--; // undo what we did
1459
thd->global_read_lock= MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT;
1460
thd->exit_cond(old_message); // this unlocks LOCK_global_read_lock
1190
session->global_read_lock= MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT;
1191
session->exit_cond(old_message); // this unlocks LOCK_global_read_lock
1484
1215
void broadcast_refresh(void)
1486
VOID(pthread_cond_broadcast(&COND_refresh));
1487
VOID(pthread_cond_broadcast(&COND_global_read_lock));
1492
Try to get transactional table locks for the tables in the list.
1495
try_transactional_lock()
1497
table_list List of tables to lock
1500
This is called if transactional table locks are requested for all
1501
tables in table_list and no non-transactional locks pre-exist.
1504
0 OK. All tables are transactional locked.
1505
1 Error: must fall back to non-transactional locks.
1506
-1 Error: no recovery possible.
1509
int try_transactional_lock(THD *thd, TABLE_LIST *table_list)
1515
/* Need to open the tables to be able to access engine methods. */
1516
if (open_tables(thd, &table_list, &dummy_counter, 0))
1518
/* purecov: begin tested */
1523
/* Required by InnoDB. */
1524
thd->in_lock_tables= true;
1526
if ((error= set_handler_table_locks(thd, table_list, true)))
1529
Not all transactional locks could be taken. If the error was
1530
something else but "unsupported by storage engine", abort the
1531
execution of this statement.
1533
if (error != HA_ERR_WRONG_COMMAND)
1539
Fall back to non-transactional locks because transactional locks
1540
are unsupported by a storage engine. No need to unlock the
1541
successfully taken transactional locks. They go away at end of
1548
/* We need to explicitly commit if autocommit mode is active. */
1549
(void) ha_autocommit_or_rollback(thd, 0);
1550
/* Close the tables. The locks (if taken) persist in the storage engines. */
1551
close_tables_for_reopen(thd, &table_list);
1552
thd->in_lock_tables= false;
1558
Check if lock method conversion was done and was allowed.
1561
check_transactional_lock()
1563
table_list List of tables to lock
1567
Lock method conversion can be done during parsing if one of the
1568
locks is non-transactional. It can also happen if non-transactional
1569
table locks exist when the statement is executed or if a storage
1570
engine does not support transactional table locks.
1572
Check if transactional table locks have been converted to
1573
non-transactional and if this was allowed. In a running transaction
1574
or in strict mode lock method conversion is not allowed - report an
1575
error. Otherwise it is allowed - issue a warning.
1578
0 OK. Proceed with non-transactional locks.
1579
-1 Error: Lock conversion is prohibited.
1582
int check_transactional_lock(THD *thd, TABLE_LIST *table_list)
1586
char warn_buff[DRIZZLE_ERRMSG_SIZE];
1588
for (tlist= table_list; tlist; tlist= tlist->next_global)
1592
Unfortunately we cannot use tlist->placeholder() here. This method
1593
returns TRUE if the table is not open, which is always the case
1594
here. Whenever the definition of TABLE_LIST::placeholder() is
1595
changed, probably this condition needs to be changed too.
1597
if (tlist->derived || tlist->schema_table || !tlist->lock_transactional)
1602
/* We must not convert the lock method in strict mode. */
1604
my_error(ER_NO_AUTO_CONVERT_LOCK_STRICT, MYF(0),
1605
tlist->alias ? tlist->alias : tlist->table_name);
1610
/* We must not convert the lock method within an active transaction. */
1611
if (thd->active_transaction())
1613
my_error(ER_NO_AUTO_CONVERT_LOCK_TRANSACTION, MYF(0),
1614
tlist->alias ? tlist->alias : tlist->table_name);
1619
/* Warn about the conversion. */
1620
snprintf(warn_buff, sizeof(warn_buff), ER(ER_WARN_AUTO_CONVERT_LOCK),
1621
tlist->alias ? tlist->alias : tlist->table_name);
1622
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1623
ER_WARN_AUTO_CONVERT_LOCK, warn_buff);
1631
Set table locks in the table handler.
1634
set_handler_table_locks()
1636
table_list List of tables to lock
1637
transactional If to lock transactional or non-transactional
1641
!= 0 Error code from handler::lock_table().
1644
int set_handler_table_locks(THD *thd, TABLE_LIST *table_list,
1650
for (tlist= table_list; tlist; tlist= tlist->next_global)
1653
int lock_timeout= -1; /* Use default for non-transactional locks. */
1655
if (tlist->placeholder())
1658
assert((tlist->lock_type == TL_READ) ||
1659
(tlist->lock_type == TL_READ_NO_INSERT) ||
1660
(tlist->lock_type == TL_WRITE_DEFAULT) ||
1661
(tlist->lock_type == TL_WRITE) ||
1662
(tlist->lock_type == TL_WRITE_LOW_PRIORITY));
1665
Every tlist object has a proper lock_type set. Even if it came in
1666
the list as a base table from a view only.
1668
lock_type= ((tlist->lock_type <= TL_READ_NO_INSERT) ?
1669
HA_LOCK_IN_SHARE_MODE : HA_LOCK_IN_EXCLUSIVE_MODE);
1674
The lock timeout is not set if this table belongs to a view. We
1675
need to take it from the top-level view. After this loop
1676
iteration, lock_timeout is not needed any more. Not even if the
1677
locks are converted to non-transactional locks later.
1678
Non-transactional locks do not support a lock_timeout.
1680
lock_timeout= tlist->top_table()->lock_timeout;
1683
For warning/error reporting we need to set the intended lock
1684
method in the TABLE_LIST object. It will be used later by
1685
check_transactional_lock(). The lock method is not set if this
1686
table belongs to a view. We can safely set it to transactional
1687
locking here. Even for non-view tables. This function is not
1688
called if non-transactional locking was requested for any
1691
tlist->lock_transactional= true;
1695
Because we need to set the lock method (see above) for all
1696
involved tables, we cannot break the loop on an error.
1697
But we do not try more locks after the first error.
1698
However, for non-transactional locking handler::lock_table() is
1699
a hint only. So we continue to call it for other tables.
1701
if (!error || !transactional)
1703
error= tlist->table->file->lock_table(thd, lock_type, lock_timeout);
1704
if (error && transactional && (error != HA_ERR_WRONG_COMMAND))
1705
tlist->table->file->print_error(error, MYF(0));
1217
pthread_cond_broadcast(&COND_refresh);
1218
pthread_cond_broadcast(&COND_global_read_lock);