530
190
/* Increase id and count all other statements. */
532
statistic_increment(thd->status_var.questions, &LOCK_status);
192
statistic_increment(session->status_var.questions, &LOCK_status);
537
/* TODO: set thd->lex->sql_command to SQLCOM_END here */
538
VOID(pthread_mutex_unlock(&LOCK_thread_count));
196
/* TODO: set session->lex->sql_command to SQLCOM_END here */
198
plugin::Logging::preDo(session);
200
session->server_status&=
541
201
~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
542
202
switch (command) {
543
203
case COM_INIT_DB:
546
status_var_increment(thd->status_var.com_stat[SQLCOM_CHANGE_DB]);
547
thd->convert_string(&tmp, system_charset_info,
548
packet, packet_length, thd->charset());
549
if (!mysql_change_db(thd, &tmp, false))
551
general_log_write(thd, command, thd->db, thd->db_length);
556
case COM_REGISTER_SLAVE:
558
if (!register_slave(thd, (uchar*)packet, packet_length))
562
case COM_CHANGE_USER:
564
status_var_increment(thd->status_var.com_other);
565
char *user= (char*) packet, *packet_end= packet + packet_length;
566
/* Safe because there is always a trailing \0 at the end of the packet */
567
char *passwd= strend(user)+1;
570
thd->clear_error(); // if errors from rollback
573
Old clients send null-terminated string ('\0' for empty string) for
574
password. New clients send the size (1 byte) + string (not null
575
terminated, so also '\0' for empty string).
577
Cast *passwd to an unsigned char, so that it doesn't extend the sign
578
for *passwd > 127 and become 2**32-127 after casting to uint.
580
char db_buff[NAME_LEN+1]; // buffer to store db in utf8
584
If there is no password supplied, the packet must contain '\0',
585
in any type of handshake (4.1 or pre-4.1).
587
if (passwd >= packet_end)
589
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
592
uint passwd_len= (thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
593
(uchar)(*passwd++) : strlen(passwd));
594
uint dummy_errors, save_db_length, db_length;
596
Security_context save_security_ctx= *thd->security_ctx;
597
USER_CONN *save_user_connect;
601
Database name is always NUL-terminated, so in case of empty database
602
the packet must contain at least the trailing '\0'.
604
if (db >= packet_end)
606
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
609
db_length= strlen(db);
611
char *ptr= db + db_length + 1;
614
if (ptr < packet_end)
616
if (ptr + 2 > packet_end)
618
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
622
cs_number= uint2korr(ptr);
625
/* Convert database name to utf8 */
626
db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
627
system_charset_info, db, db_length,
628
thd->charset(), &dummy_errors)]= 0;
631
/* Save user and privileges */
632
save_db_length= thd->db_length;
634
save_user_connect= thd->user_connect;
636
if (!(thd->security_ctx->user= my_strdup(user, MYF(0))))
638
thd->security_ctx->user= save_security_ctx.user;
639
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
643
/* Clear variables that are allocated */
644
thd->user_connect= 0;
645
res= check_user(thd, COM_CHANGE_USER, passwd, passwd_len, db, false);
649
x_free(thd->security_ctx->user);
650
*thd->security_ctx= save_security_ctx;
651
thd->user_connect= save_user_connect;
653
thd->db_length= save_db_length;
658
x_free(save_security_ctx.user);
662
thd_init_client_charset(thd, cs_number);
663
thd->update_charset();
206
status_var_increment(session->status_var.com_stat[SQLCOM_CHANGE_DB]);
208
tmp.length= packet_length;
209
if (!mysql_change_db(session, &tmp, false))
670
if (alloc_query(thd, packet, packet_length))
217
if (! session->readAndStoreQuery(packet, packet_length))
671
218
break; // fatal error is set
672
char *packet_end= thd->query + thd->query_length;
219
DRIZZLE_QUERY_START(session->query,
221
const_cast<const char *>(session->db.empty() ? "" : session->db.c_str()));
673
222
const char* end_of_stmt= NULL;
675
general_log_write(thd, command, thd->query, thd->query_length);
677
mysql_parse(thd, thd->query, thd->query_length, &end_of_stmt);
679
while (!thd->killed && (end_of_stmt != NULL) && ! thd->is_error())
681
char *beginning_of_next_stmt= (char*) end_of_stmt;
683
net_end_statement(thd);
685
Multiple queries exits, execute them individually
687
close_thread_tables(thd);
688
ulong length= (ulong)(packet_end - beginning_of_next_stmt);
690
log_slow_statement(thd);
692
/* Remove garbage at start of query */
693
while (length > 0 && my_isspace(thd->charset(), *beginning_of_next_stmt))
695
beginning_of_next_stmt++;
699
VOID(pthread_mutex_lock(&LOCK_thread_count));
700
thd->query_length= length;
701
thd->query= beginning_of_next_stmt;
703
Count each statement from the client.
705
statistic_increment(thd->status_var.questions, &LOCK_status);
706
thd->query_id= next_query_id();
707
thd->set_time(); /* Reset the query start time. */
708
/* TODO: set thd->lex->sql_command to SQLCOM_END here */
709
VOID(pthread_mutex_unlock(&LOCK_thread_count));
711
mysql_parse(thd, beginning_of_next_stmt, length, &end_of_stmt);
715
case COM_FIELD_LIST: // This isn't actually needed
717
char *fields, *packet_end= packet + packet_length, *arg_end;
718
/* Locked closure of all tables */
719
TABLE_LIST table_list;
720
LEX_STRING conv_name;
722
/* used as fields initializator */
725
status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_FIELDS]);
726
memset(&table_list, 0, sizeof(table_list));
727
if (thd->copy_db_to(&table_list.db, &table_list.db_length))
730
We have name + wildcard in packet, separated by endzero
732
arg_end= strend(packet);
733
thd->convert_string(&conv_name, system_charset_info,
734
packet, (uint) (arg_end - packet), thd->charset());
735
table_list.alias= table_list.table_name= conv_name.str;
738
if (!my_strcasecmp(system_charset_info, table_list.db,
739
INFORMATION_SCHEMA_NAME.str))
741
ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, table_list.alias);
743
table_list.schema_table= schema_table;
746
thd->query_length= (uint) (packet_end - packet); // Don't count end \0
747
if (!(thd->query=fields= (char*) thd->memdup(packet,thd->query_length+1)))
749
general_log_print(thd, command, "%s %s", table_list.table_name, fields);
750
if (lower_case_table_names)
751
my_casedn_str(files_charset_info, table_list.table_name);
753
/* init structures for VIEW processing */
754
table_list.select_lex= &(thd->lex->select_lex);
757
mysql_reset_thd_for_next_command(thd);
760
select_lex.table_list.link_in_list((uchar*) &table_list,
761
(uchar**) &table_list.next_local);
762
thd->lex->add_to_query_tables(&table_list);
764
/* switch on VIEW optimisation: do not fill temporary tables */
765
thd->lex->sql_command= SQLCOM_SHOW_FIELDS;
766
mysqld_list_fields(thd,&table_list,fields);
767
thd->lex->unit.cleanup();
768
thd->cleanup_after_query();
224
mysql_parse(session, session->query, session->query_length, &end_of_stmt);
772
229
/* We don't calculate statistics for this command */
773
general_log_print(thd, command, NullS);
774
net->error=0; // Don't give 'abort' message
775
thd->main_da.disable_status(); // Don't send anything back
230
session->main_da.disable_status(); // Don't send anything back
776
231
error=true; // End server
778
case COM_BINLOG_DUMP:
782
uint32_t slave_server_id;
784
status_var_increment(thd->status_var.com_other);
785
thd->enable_slow_log= opt_log_slow_admin_statements;
786
/* TODO: The following has to be changed to an 8 byte integer */
787
pos = uint4korr(packet);
788
flags = uint2korr(packet + 4);
789
thd->server_id=0; /* avoid suicide */
790
if ((slave_server_id= uint4korr(packet+6))) // mysqlbinlog.server_id==0
791
kill_zombie_dump_threads(slave_server_id);
792
thd->server_id = slave_server_id;
794
general_log_print(thd, command, "Log: '%s' Pos: %ld", packet+10,
796
mysql_binlog_send(thd, thd->strdup(packet + 10), (my_off_t) pos, flags);
797
unregister_slave(thd,1,1);
798
/* fake COM_QUIT -- if we get here, the thread needs to terminate */
802
233
case COM_SHUTDOWN:
804
status_var_increment(thd->status_var.com_other);
806
If the client is < 4.1.3, it is going to send us no argument; then
807
packet_length is 0, packet[0] is the end 0 of the packet. Note that
808
SHUTDOWN_DEFAULT is 0. If client is >= 4.1.3, the shutdown level is in
811
enum drizzle_enum_shutdown_level level=
812
(enum drizzle_enum_shutdown_level) (uchar) packet[0];
813
if (level == SHUTDOWN_DEFAULT)
814
level= SHUTDOWN_WAIT_ALL_BUFFERS; // soon default will be configurable
815
else if (level != SHUTDOWN_WAIT_ALL_BUFFERS)
817
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "this shutdown level");
820
general_log_print(thd, command, NullS);
822
close_thread_tables(thd); // Free before kill
235
status_var_increment(session->status_var.com_other);
237
session->close_thread_tables(); // Free before kill
828
status_var_increment(thd->status_var.com_other);
829
my_ok(thd); // Tell client we are alive
831
case COM_PROCESS_INFO:
832
status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_PROCESSLIST]);
833
general_log_print(thd, command, NullS);
834
mysqld_list_processes(thd, NullS, 0);
836
case COM_PROCESS_KILL:
838
status_var_increment(thd->status_var.com_stat[SQLCOM_KILL]);
839
ulong id=(ulong) uint4korr(packet);
840
sql_kill(thd,id,false);
845
status_var_increment(thd->status_var.com_stat[SQLCOM_SET_OPTION]);
846
uint opt_command= uint2korr(packet);
848
switch (opt_command) {
849
case (int) DRIZZLE_OPTION_MULTI_STATEMENTS_ON:
850
thd->client_capabilities|= CLIENT_MULTI_STATEMENTS;
853
case (int) DRIZZLE_OPTION_MULTI_STATEMENTS_OFF:
854
thd->client_capabilities&= ~CLIENT_MULTI_STATEMENTS;
858
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
243
status_var_increment(session->status_var.com_other);
244
session->my_ok(); // Tell client we are alive
864
247
case COM_CONNECT: // Impossible here
865
case COM_TIME: // Impossible from client
868
250
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
1183
488
variables, but for now this is probably good enough.
1184
489
Don't reset warnings when executing a stored routine.
1186
if (all_tables || !lex->is_single_level_stmt())
1187
drizzle_reset_errors(thd, 0);
1189
if (unlikely(thd->slave_thread))
1192
Check if statment should be skipped because of slave filtering
1196
- UPDATE MULTI: For this statement, we want to check the filtering
1197
rules later in the code
1198
- SET: we always execute it (Not that many SET commands exists in
1199
the binary log anyway -- only 4.1 masters write SET statements,
1200
in 5.0 there are no SET statements in the binary log)
1201
- DROP TEMPORARY TABLE IF EXISTS: we always execute it (otherwise we
1202
have stale files on slave caused by exclusion of one tmp table).
1204
if (!(lex->sql_command == SQLCOM_UPDATE_MULTI) &&
1205
!(lex->sql_command == SQLCOM_SET_OPTION) &&
1206
!(lex->sql_command == SQLCOM_DROP_TABLE &&
1207
lex->drop_temporary && lex->drop_if_exists) &&
1208
all_tables_not_ok(thd, all_tables))
1210
/* we warn the slave SQL thread */
1211
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
1212
if (thd->one_shot_set)
1215
It's ok to check thd->one_shot_set here:
1217
The charsets in a MySQL 5.0 slave can change by both a binlogged
1218
SET ONE_SHOT statement and the event-internal charset setting,
1219
and these two ways to change charsets do not seems to work
1222
At least there seems to be problems in the rli cache for
1223
charsets if we are using ONE_SHOT. Note that this is normally no
1224
problem because either the >= 5.0 slave reads a 4.1 binlog (with
1225
ONE_SHOT) *or* or 5.0 binlog (without ONE_SHOT) but never both."
1227
reset_one_shot_variables(thd);
1235
When option readonly is set deny operations which change non-temporary
1236
tables. Except for the replication thread and the 'super' users.
1238
if (deny_updates_if_read_only_option(thd, all_tables))
1240
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
1243
} /* endif unlikely slave */
1244
status_var_increment(thd->status_var.com_stat[lex->sql_command]);
1246
assert(thd->transaction.stmt.modified_non_trans_table == false);
1248
switch (lex->sql_command) {
1249
case SQLCOM_SHOW_STATUS:
1251
system_status_var old_status_var= thd->status_var;
1252
thd->initial_status_var= &old_status_var;
1253
res= execute_sqlcom_select(thd, all_tables);
1254
/* Don't log SHOW STATUS commands to slow query log */
1255
thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED |
1256
SERVER_QUERY_NO_GOOD_INDEX_USED);
1258
restore status variables, as we don't want 'show status' to cause
1261
pthread_mutex_lock(&LOCK_status);
1262
add_diff_to_status(&global_status_var, &thd->status_var,
1264
thd->status_var= old_status_var;
1265
pthread_mutex_unlock(&LOCK_status);
1268
case SQLCOM_SHOW_DATABASES:
1269
case SQLCOM_SHOW_TABLES:
1270
case SQLCOM_SHOW_TABLE_STATUS:
1271
case SQLCOM_SHOW_OPEN_TABLES:
1272
case SQLCOM_SHOW_FIELDS:
1273
case SQLCOM_SHOW_KEYS:
1274
case SQLCOM_SHOW_VARIABLES:
1275
case SQLCOM_SHOW_CHARSETS:
1276
case SQLCOM_SHOW_COLLATIONS:
1279
thd->status_var.last_query_cost= 0.0;
1280
res= execute_sqlcom_select(thd, all_tables);
1283
case SQLCOM_EMPTY_QUERY:
1289
res = purge_master_logs(thd, lex->to_log);
1292
case SQLCOM_PURGE_BEFORE:
1296
/* PURGE MASTER LOGS BEFORE 'data' */
1297
it= (Item *)lex->value_list.head();
1298
if ((!it->fixed && it->fix_fields(lex->thd, &it)) ||
1301
my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE LOGS BEFORE");
1304
it= new Item_func_unix_timestamp(it);
1306
it is OK only emulate fix_fieds, because we need only
1309
it->quick_fix_field();
1310
res = purge_master_logs_before_date(thd, (ulong)it->val_int());
1313
case SQLCOM_SHOW_WARNS:
1315
res= mysqld_show_warnings(thd, (ulong)
1316
((1L << (uint) DRIZZLE_ERROR::WARN_LEVEL_NOTE) |
1317
(1L << (uint) DRIZZLE_ERROR::WARN_LEVEL_WARN) |
1318
(1L << (uint) DRIZZLE_ERROR::WARN_LEVEL_ERROR)
1322
case SQLCOM_SHOW_ERRORS:
1324
res= mysqld_show_warnings(thd, (ulong)
1325
(1L << (uint) DRIZZLE_ERROR::WARN_LEVEL_ERROR));
1328
case SQLCOM_SHOW_SLAVE_HOSTS:
1330
res = show_slave_hosts(thd);
1333
case SQLCOM_SHOW_BINLOG_EVENTS:
1335
res = mysql_show_binlog_events(thd);
1339
case SQLCOM_ASSIGN_TO_KEYCACHE:
1341
assert(first_table == all_tables && first_table != 0);
1342
res= mysql_assign_to_keycache(thd, first_table, &lex->ident);
1345
case SQLCOM_CHANGE_MASTER:
1347
pthread_mutex_lock(&LOCK_active_mi);
1348
res = change_master(thd,active_mi);
1349
pthread_mutex_unlock(&LOCK_active_mi);
1352
case SQLCOM_SHOW_SLAVE_STAT:
1354
pthread_mutex_lock(&LOCK_active_mi);
1355
if (active_mi != NULL)
1357
res = show_master_info(thd, active_mi);
1361
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1362
"the master info structure does not exist");
1365
pthread_mutex_unlock(&LOCK_active_mi);
1368
case SQLCOM_SHOW_MASTER_STAT:
1370
res = show_binlog_info(thd);
1374
case SQLCOM_SHOW_ENGINE_STATUS:
1376
res = ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_STATUS);
1379
case SQLCOM_CREATE_TABLE:
1381
/* If CREATE TABLE of non-temporary table, do implicit commit */
1382
if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE))
1384
if (end_active_trans(thd))
1390
assert(first_table == all_tables && first_table != 0);
1392
// Skip first table, which is the table we are creating
1393
TABLE_LIST *create_table= lex->unlink_first_table(&link_to_local);
1394
TABLE_LIST *select_tables= lex->query_tables;
1396
Code below (especially in mysql_create_table() and select_create
1397
methods) may modify HA_CREATE_INFO structure in LEX, so we have to
1398
use a copy of this structure to make execution prepared statement-
1399
safe. A shallow copy is enough as this code won't modify any memory
1400
referenced from this structure.
1402
HA_CREATE_INFO create_info(lex->create_info);
1404
We need to copy alter_info for the same reasons of re-execution
1405
safety, only in case of Alter_info we have to do (almost) a deep
1408
Alter_info alter_info(lex->alter_info, thd->mem_root);
1410
if (thd->is_fatal_error)
1412
/* If out of memory when creating a copy of alter_info. */
1414
goto end_with_restore_list;
1417
if ((res= create_table_precheck(thd, select_tables, create_table)))
1418
goto end_with_restore_list;
1420
/* Might have been updated in create_table_precheck */
1421
create_info.alias= create_table->alias;
1423
#ifdef HAVE_READLINK
1424
/* Fix names if symlinked tables */
1425
if (append_file_to_dir(thd, &create_info.data_file_name,
1426
create_table->table_name) ||
1427
append_file_to_dir(thd, &create_info.index_file_name,
1428
create_table->table_name))
1429
goto end_with_restore_list;
1432
If we are using SET CHARSET without DEFAULT, add an implicit
1433
DEFAULT to not confuse old users. (This may change).
1435
if ((create_info.used_fields &
1436
(HA_CREATE_USED_DEFAULT_CHARSET | HA_CREATE_USED_CHARSET)) ==
1437
HA_CREATE_USED_CHARSET)
1439
create_info.used_fields&= ~HA_CREATE_USED_CHARSET;
1440
create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
1441
create_info.default_table_charset= create_info.table_charset;
1442
create_info.table_charset= 0;
1445
The create-select command will open and read-lock the select table
1446
and then create, open and write-lock the new table. If a global
1447
read lock steps in, we get a deadlock. The write lock waits for
1448
the global read lock, while the global read lock waits for the
1449
select table to be closed. So we wait until the global readlock is
1450
gone before starting both steps. Note that
1451
wait_if_global_read_lock() sets a protection against a new global
1452
read lock when it succeeds. This needs to be released by
1453
start_waiting_global_read_lock(). We protect the normal CREATE
1454
TABLE in the same way. That way we avoid that a new table is
1455
created during a gobal read lock.
1457
if (!thd->locked_tables &&
1458
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
1461
goto end_with_restore_list;
1463
if (select_lex->item_list.elements) // With select
1465
select_result *result;
1467
select_lex->options|= SELECT_NO_UNLOCK;
1468
unit->set_limit(select_lex);
1470
if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
1472
lex->link_first_table_back(create_table, link_to_local);
1473
create_table->create= true;
1476
if (!(res= open_and_lock_tables(thd, lex->query_tables)))
1479
Is table which we are changing used somewhere in other parts
1482
if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
1484
TABLE_LIST *duplicate;
1485
create_table= lex->unlink_first_table(&link_to_local);
1486
if ((duplicate= unique_table(thd, create_table, select_tables, 0)))
1488
update_non_unique_table_error(create_table, "CREATE", duplicate);
1490
goto end_with_restore_list;
1495
select_create is currently not re-execution friendly and
1496
needs to be created for every execution of a PS/SP.
1498
if ((result= new select_create(create_table,
1501
select_lex->item_list,
1507
CREATE from SELECT give its SELECT_LEX for SELECT,
1508
and item_list belong to SELECT
1510
res= handle_select(thd, lex, result, 0);
1514
else if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
1515
create_table= lex->unlink_first_table(&link_to_local);
1520
/* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
1521
if (create_info.options & HA_LEX_CREATE_TMP_TABLE)
1522
thd->options|= OPTION_KEEP_LOG;
1523
/* regular create */
1524
if (create_info.options & HA_LEX_CREATE_TABLE_LIKE)
1525
res= mysql_create_like_table(thd, create_table, select_tables,
1529
res= mysql_create_table(thd, create_table->db,
1530
create_table->table_name, &create_info,
1537
/* put tables back for PS rexecuting */
1538
end_with_restore_list:
1539
lex->link_first_table_back(create_table, link_to_local);
1542
case SQLCOM_CREATE_INDEX:
1544
case SQLCOM_DROP_INDEX:
1546
CREATE INDEX and DROP INDEX are implemented by calling ALTER
1547
TABLE with proper arguments.
1549
In the future ALTER TABLE will notice that the request is to
1550
only add indexes and create these one by one for the existing
1551
table without having to do a full rebuild.
1554
/* Prepare stack copies to be re-execution safe */
1555
HA_CREATE_INFO create_info;
1556
Alter_info alter_info(lex->alter_info, thd->mem_root);
1558
if (thd->is_fatal_error) /* out of memory creating a copy of alter_info */
1561
assert(first_table == all_tables && first_table != 0);
1562
if (end_active_trans(thd))
1565
Currently CREATE INDEX or DROP INDEX cause a full table rebuild
1566
and thus classify as slow administrative statements just like
1569
thd->enable_slow_log= opt_log_slow_admin_statements;
1571
memset(&create_info, 0, sizeof(create_info));
1572
create_info.db_type= 0;
1573
create_info.row_type= ROW_TYPE_NOT_USED;
1574
create_info.default_table_charset= thd->variables.collation_database;
1576
res= mysql_alter_table(thd, first_table->db, first_table->table_name,
1577
&create_info, first_table, &alter_info,
1581
case SQLCOM_SLAVE_START:
1583
pthread_mutex_lock(&LOCK_active_mi);
1584
start_slave(thd,active_mi,1 /* net report*/);
1585
pthread_mutex_unlock(&LOCK_active_mi);
1588
case SQLCOM_SLAVE_STOP:
1590
If the client thread has locked tables, a deadlock is possible.
1592
- the client thread does LOCK TABLE t READ.
1593
- then the master updates t.
1594
- then the SQL slave thread wants to update t,
1595
so it waits for the client thread because t is locked by it.
1596
- then the client thread does SLAVE STOP.
1597
SLAVE STOP waits for the SQL slave thread to terminate its
1598
update t, which waits for the client thread because t is locked by it.
1599
To prevent that, refuse SLAVE STOP if the
1600
client thread has locked tables
1602
if (thd->locked_tables || thd->active_transaction() || thd->global_read_lock)
1604
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
1605
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
1609
pthread_mutex_lock(&LOCK_active_mi);
1610
stop_slave(thd,active_mi,1/* net report*/);
1611
pthread_mutex_unlock(&LOCK_active_mi);
1615
case SQLCOM_ALTER_TABLE:
1616
assert(first_table == all_tables && first_table != 0);
1619
Code in mysql_alter_table() may modify its HA_CREATE_INFO argument,
1620
so we have to use a copy of this structure to make execution
1621
prepared statement- safe. A shallow copy is enough as no memory
1622
referenced from this structure will be modified.
1624
HA_CREATE_INFO create_info(lex->create_info);
1625
Alter_info alter_info(lex->alter_info, thd->mem_root);
1627
if (thd->is_fatal_error) /* out of memory creating a copy of alter_info */
1632
/* Must be set in the parser */
1633
assert(select_lex->db);
1635
{ // Rename of table
1636
TABLE_LIST tmp_table;
1637
memset(&tmp_table, 0, sizeof(tmp_table));
1638
tmp_table.table_name= lex->name.str;
1639
tmp_table.db=select_lex->db;
1642
/* Don't yet allow changing of symlinks with ALTER TABLE */
1643
if (create_info.data_file_name)
1644
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1645
"DATA DIRECTORY option ignored");
1646
if (create_info.index_file_name)
1647
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1648
"INDEX DIRECTORY option ignored");
1649
create_info.data_file_name= create_info.index_file_name= NULL;
1650
/* ALTER TABLE ends previous transaction */
1651
if (end_active_trans(thd))
1654
if (!thd->locked_tables &&
1655
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
1661
thd->enable_slow_log= opt_log_slow_admin_statements;
1662
res= mysql_alter_table(thd, select_lex->db, lex->name.str,
1666
select_lex->order_list.elements,
1667
(ORDER *) select_lex->order_list.first,
1671
case SQLCOM_RENAME_TABLE:
1673
assert(first_table == all_tables && first_table != 0);
1675
for (table= first_table; table; table= table->next_local->next_local)
1677
TABLE_LIST old_list, new_list;
1679
we do not need initialize old_list and new_list because we will
1680
come table[0] and table->next[0] there
1683
new_list= table->next_local[0];
1686
if (end_active_trans(thd) || mysql_rename_tables(thd, first_table, 0))
1692
case SQLCOM_SHOW_BINLOGS:
1694
res = show_binlogs(thd);
1697
case SQLCOM_SHOW_CREATE:
1698
assert(first_table == all_tables && first_table != 0);
1700
res= mysqld_show_create(thd, first_table);
1703
case SQLCOM_CHECKSUM:
1705
assert(first_table == all_tables && first_table != 0);
1706
res = mysql_checksum_table(thd, first_table, &lex->check_opt);
1711
assert(first_table == all_tables && first_table != 0);
1712
thd->enable_slow_log= opt_log_slow_admin_statements;
1713
res= mysql_repair_table(thd, first_table, &lex->check_opt);
1714
/* ! we write after unlocking the table */
1715
if (!res && !lex->no_write_to_binlog)
1718
Presumably, REPAIR and binlog writing doesn't require synchronization
1720
write_bin_log(thd, true, thd->query, thd->query_length);
1722
select_lex->table_list.first= (uchar*) first_table;
1723
lex->query_tables=all_tables;
1728
assert(first_table == all_tables && first_table != 0);
1729
thd->enable_slow_log= opt_log_slow_admin_statements;
1730
res = mysql_check_table(thd, first_table, &lex->check_opt);
1731
select_lex->table_list.first= (uchar*) first_table;
1732
lex->query_tables=all_tables;
1735
case SQLCOM_ANALYZE:
1737
assert(first_table == all_tables && first_table != 0);
1738
thd->enable_slow_log= opt_log_slow_admin_statements;
1739
res= mysql_analyze_table(thd, first_table, &lex->check_opt);
1740
/* ! we write after unlocking the table */
1741
if (!res && !lex->no_write_to_binlog)
1744
Presumably, ANALYZE and binlog writing doesn't require synchronization
1746
write_bin_log(thd, true, thd->query, thd->query_length);
1748
select_lex->table_list.first= (uchar*) first_table;
1749
lex->query_tables=all_tables;
1753
case SQLCOM_OPTIMIZE:
1755
assert(first_table == all_tables && first_table != 0);
1756
thd->enable_slow_log= opt_log_slow_admin_statements;
1757
res= (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) ?
1758
mysql_recreate_table(thd, first_table) :
1759
mysql_optimize_table(thd, first_table, &lex->check_opt);
1760
/* ! we write after unlocking the table */
1761
if (!res && !lex->no_write_to_binlog)
1764
Presumably, OPTIMIZE and binlog writing doesn't require synchronization
1766
write_bin_log(thd, true, thd->query, thd->query_length);
1768
select_lex->table_list.first= (uchar*) first_table;
1769
lex->query_tables=all_tables;
1773
assert(first_table == all_tables && first_table != 0);
1774
if (update_precheck(thd, all_tables))
1776
assert(select_lex->offset_limit == 0);
1777
unit->set_limit(select_lex);
1778
res= (up_result= mysql_update(thd, all_tables,
1779
select_lex->item_list,
1782
select_lex->order_list.elements,
1783
(ORDER *) select_lex->order_list.first,
1784
unit->select_limit_cnt,
1785
lex->duplicates, lex->ignore));
1786
/* mysql_update return 2 if we need to switch to multi-update */
1790
case SQLCOM_UPDATE_MULTI:
1792
assert(first_table == all_tables && first_table != 0);
1793
/* if we switched from normal update, rights are checked */
1796
if ((res= multi_update_precheck(thd, all_tables)))
1802
res= mysql_multi_update_prepare(thd);
1804
/* Check slave filtering rules */
1805
if (unlikely(thd->slave_thread))
1807
if (all_tables_not_ok(thd, all_tables))
1811
res= 0; /* don't care of prev failure */
1812
thd->clear_error(); /* filters are of highest prior */
1814
/* we warn the slave SQL thread */
1815
my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
1826
some_non_temp_table_to_be_updated(thd, all_tables))
1828
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
1833
res= mysql_multi_update(thd, all_tables,
1834
&select_lex->item_list,
1837
select_lex->options,
1838
lex->duplicates, lex->ignore, unit, select_lex);
1841
case SQLCOM_REPLACE:
1844
assert(first_table == all_tables && first_table != 0);
1845
if ((res= insert_precheck(thd, all_tables)))
1848
if (!thd->locked_tables &&
1849
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
1855
res= mysql_insert(thd, all_tables, lex->field_list, lex->many_values,
1856
lex->update_list, lex->value_list,
1857
lex->duplicates, lex->ignore);
1861
case SQLCOM_REPLACE_SELECT:
1862
case SQLCOM_INSERT_SELECT:
1864
select_result *sel_result;
1865
assert(first_table == all_tables && first_table != 0);
1866
if ((res= insert_precheck(thd, all_tables)))
1869
/* Fix lock for first table */
1870
if (first_table->lock_type == TL_WRITE_DELAYED)
1871
first_table->lock_type= TL_WRITE;
1873
/* Don't unlock tables until command is written to binary log */
1874
select_lex->options|= SELECT_NO_UNLOCK;
1876
unit->set_limit(select_lex);
1878
if (! thd->locked_tables &&
1879
! (need_start_waiting= ! wait_if_global_read_lock(thd, 0, 1)))
1885
if (!(res= open_and_lock_tables(thd, all_tables)))
1887
/* Skip first table, which is the table we are inserting in */
1888
TABLE_LIST *second_table= first_table->next_local;
1889
select_lex->table_list.first= (uchar*) second_table;
1890
select_lex->context.table_list=
1891
select_lex->context.first_name_resolution_table= second_table;
1892
res= mysql_insert_select_prepare(thd);
1893
if (!res && (sel_result= new select_insert(first_table,
1901
res= handle_select(thd, lex, sel_result, OPTION_SETUP_TABLES_DONE);
1903
Invalidate the table in the query cache if something changed
1904
after unlocking when changes become visible.
1905
TODO: this is workaround. right way will be move invalidating in
1906
the unlock procedure.
1908
if (first_table->lock_type == TL_WRITE_CONCURRENT_INSERT &&
1911
/* INSERT ... SELECT should invalidate only the very first table */
1912
TABLE_LIST *save_table= first_table->next_local;
1913
first_table->next_local= 0;
1914
first_table->next_local= save_table;
1918
/* revert changes for SP */
1919
select_lex->table_list.first= (uchar*) first_table;
1924
case SQLCOM_TRUNCATE:
1925
if (end_active_trans(thd))
1930
assert(first_table == all_tables && first_table != 0);
1932
Don't allow this within a transaction because we want to use
1935
if (thd->locked_tables || thd->active_transaction())
1937
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
1938
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
1942
res= mysql_truncate(thd, first_table, 0);
1947
assert(first_table == all_tables && first_table != 0);
1948
assert(select_lex->offset_limit == 0);
1949
unit->set_limit(select_lex);
1951
if (!thd->locked_tables &&
1952
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
1958
res = mysql_delete(thd, all_tables, select_lex->where,
1959
&select_lex->order_list,
1960
unit->select_limit_cnt, select_lex->options,
1964
case SQLCOM_DELETE_MULTI:
1966
assert(first_table == all_tables && first_table != 0);
1967
TABLE_LIST *aux_tables=
1968
(TABLE_LIST *)thd->lex->auxiliary_table_list.first;
1969
multi_delete *del_result;
1971
if (!thd->locked_tables &&
1972
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
1978
if ((res= multi_delete_precheck(thd, all_tables)))
1981
/* condition will be true on SP re-excuting */
1982
if (select_lex->item_list.elements != 0)
1983
select_lex->item_list.empty();
1984
if (add_item_to_list(thd, new Item_null()))
1987
thd_proc_info(thd, "init");
1988
if ((res= open_and_lock_tables(thd, all_tables)))
1991
if ((res= mysql_multi_delete_prepare(thd)))
1994
if (!thd->is_fatal_error &&
1995
(del_result= new multi_delete(aux_tables, lex->table_count)))
1997
res= mysql_select(thd, &select_lex->ref_pointer_array,
1998
select_lex->get_table_list(),
1999
select_lex->with_wild,
2000
select_lex->item_list,
2002
0, (ORDER *)NULL, (ORDER *)NULL, (Item *)NULL,
2004
select_lex->options | thd->options |
2005
SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
2006
OPTION_SETUP_TABLES_DONE,
2007
del_result, unit, select_lex);
2008
res|= thd->is_error();
2010
del_result->abort();
2017
case SQLCOM_DROP_TABLE:
2019
assert(first_table == all_tables && first_table != 0);
2020
if (!lex->drop_temporary)
2022
if (end_active_trans(thd))
2028
If this is a slave thread, we may sometimes execute some
2029
DROP / * 40005 TEMPORARY * / TABLE
2030
that come from parts of binlogs (likely if we use RESET SLAVE or CHANGE
2031
MASTER TO), while the temporary table has already been dropped.
2032
To not generate such irrelevant "table does not exist errors",
2033
we silently add IF EXISTS if TEMPORARY was used.
2035
if (thd->slave_thread)
2036
lex->drop_if_exists= 1;
2038
/* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
2039
thd->options|= OPTION_KEEP_LOG;
2041
/* DDL and binlog write order protected by LOCK_open */
2042
res= mysql_rm_table(thd, first_table, lex->drop_if_exists, lex->drop_temporary);
2045
case SQLCOM_SHOW_PROCESSLIST:
2046
mysqld_list_processes(thd, NullS, lex->verbose);
2048
case SQLCOM_SHOW_ENGINE_LOGS:
2050
res= ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_LOGS);
2053
case SQLCOM_CHANGE_DB:
2055
LEX_STRING db_str= { (char *) select_lex->db, strlen(select_lex->db) };
2057
if (!mysql_change_db(thd, &db_str, false))
2065
assert(first_table == all_tables && first_table != 0);
2066
if (lex->local_file)
2068
if (!(thd->client_capabilities & CLIENT_LOCAL_FILES) ||
2071
my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), MYF(0));
2076
res= mysql_load(thd, lex->exchange, first_table, lex->field_list,
2077
lex->update_list, lex->value_list, lex->duplicates,
2078
lex->ignore, (bool) lex->local_file);
2082
case SQLCOM_SET_OPTION:
2084
List<set_var_base> *lex_var_list= &lex->var_list;
2086
if (lex->autocommit && end_active_trans(thd))
2089
if (open_and_lock_tables(thd, all_tables))
2091
if (lex->one_shot_set && not_all_support_one_shot(lex_var_list))
2093
my_error(ER_RESERVED_SYNTAX, MYF(0), "SET ONE_SHOT");
2096
if (!(res= sql_set_variables(thd, lex_var_list)))
2099
If the previous command was a SET ONE_SHOT, we don't want to forget
2100
about the ONE_SHOT property of that SET. So we use a |= instead of = .
2102
thd->one_shot_set|= lex->one_shot_set;
2108
We encountered some sort of error, but no message was sent.
2109
Send something semi-generic here since we don't know which
2110
assignment in the list caused the error.
2112
if (!thd->is_error())
2113
my_error(ER_WRONG_ARGUMENTS,MYF(0),"SET");
2120
case SQLCOM_UNLOCK_TABLES:
2122
It is critical for mysqldump --single-transaction --master-data that
2123
UNLOCK TABLES does not implicitely commit a connection which has only
2124
done FLUSH TABLES WITH READ LOCK + BEGIN. If this assumption becomes
2125
false, mysqldump will not work.
2127
unlock_locked_tables(thd);
2128
if (thd->options & OPTION_TABLE_LOCK)
2130
end_active_trans(thd);
2131
thd->options&= ~(OPTION_TABLE_LOCK);
2133
if (thd->global_read_lock)
2134
unlock_global_read_lock(thd);
2137
case SQLCOM_LOCK_TABLES:
2139
We try to take transactional locks if
2140
- only transactional locks are requested (lex->lock_transactional) and
2141
- no non-transactional locks exist (!thd->locked_tables).
2143
if (lex->lock_transactional && !thd->locked_tables)
2147
All requested locks are transactional and no non-transactional
2150
if ((rc= try_transactional_lock(thd, all_tables)) == -1)
2158
Non-transactional locking has been requested or
2159
non-transactional locks exist already or transactional locks are
2160
not supported by all storage engines. Take non-transactional
2165
One or more requested locks are non-transactional and/or
2166
non-transactional locks exist or a storage engine does not support
2167
transactional locks. Check if at least one transactional lock is
2168
requested. If yes, warn about the conversion to non-transactional
2169
locks or abort in strict mode.
2171
if (check_transactional_lock(thd, all_tables))
2173
unlock_locked_tables(thd);
2174
/* we must end the trasaction first, regardless of anything */
2175
if (end_active_trans(thd))
2177
thd->in_lock_tables=1;
2178
thd->options|= OPTION_TABLE_LOCK;
2180
if (!(res= simple_open_n_lock_tables(thd, all_tables)))
2182
thd->locked_tables=thd->lock;
2184
(void) set_handler_table_locks(thd, all_tables, false);
2190
Need to end the current transaction, so the storage engine (InnoDB)
2191
can free its locks if LOCK TABLES locked some tables before finding
2192
that it can't lock a table in its list
2194
ha_autocommit_or_rollback(thd, 1);
2195
end_active_trans(thd);
2196
thd->options&= ~(OPTION_TABLE_LOCK);
2198
thd->in_lock_tables=0;
2200
case SQLCOM_CREATE_DB:
2203
As mysql_create_db() may modify HA_CREATE_INFO structure passed to
2204
it, we need to use a copy of LEX::create_info to make execution
2205
prepared statement- safe.
2207
HA_CREATE_INFO create_info(lex->create_info);
2208
if (end_active_trans(thd))
2214
if (!(alias=thd->strmake(lex->name.str, lex->name.length)) ||
2215
check_db_name(&lex->name))
2217
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
2221
If in a slave thread :
2222
CREATE DATABASE DB was certainly not preceded by USE DB.
2223
For that reason, db_ok() in sql/slave.cc did not check the
2224
do_db/ignore_db. And as this query involves no tables, tables_ok()
2225
above was not called. So we have to check rules again here.
2227
if (thd->slave_thread &&
2228
(!rpl_filter->db_ok(lex->name.str) ||
2229
!rpl_filter->db_ok_with_wild_table(lex->name.str)))
2231
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
2234
res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias :
2235
lex->name.str), &create_info, 0);
2238
case SQLCOM_DROP_DB:
2240
if (end_active_trans(thd))
2245
if (check_db_name(&lex->name))
2247
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
2251
If in a slave thread :
2252
DROP DATABASE DB may not be preceded by USE DB.
2253
For that reason, maybe db_ok() in sql/slave.cc did not check the
2254
do_db/ignore_db. And as this query involves no tables, tables_ok()
2255
above was not called. So we have to check rules again here.
2257
if (thd->slave_thread &&
2258
(!rpl_filter->db_ok(lex->name.str) ||
2259
!rpl_filter->db_ok_with_wild_table(lex->name.str)))
2261
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
2264
if (thd->locked_tables || thd->active_transaction())
2266
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
2267
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
2270
res= mysql_rm_db(thd, lex->name.str, lex->drop_if_exists, 0);
2273
case SQLCOM_ALTER_DB:
2275
LEX_STRING *db= &lex->name;
2276
HA_CREATE_INFO create_info(lex->create_info);
2277
if (check_db_name(db))
2279
my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
2283
If in a slave thread :
2284
ALTER DATABASE DB may not be preceded by USE DB.
2285
For that reason, maybe db_ok() in sql/slave.cc did not check the
2286
do_db/ignore_db. And as this query involves no tables, tables_ok()
2287
above was not called. So we have to check rules again here.
2289
if (thd->slave_thread &&
2290
(!rpl_filter->db_ok(db->str) ||
2291
!rpl_filter->db_ok_with_wild_table(db->str)))
2293
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
2296
if (thd->locked_tables || thd->active_transaction())
2298
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
2299
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
2302
res= mysql_alter_db(thd, db->str, &create_info);
2305
case SQLCOM_SHOW_CREATE_DB:
2307
if (check_db_name(&lex->name))
2309
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
2312
res= mysqld_show_create_db(thd, lex->name.str, &lex->create_info);
2317
RESET commands are never written to the binary log, so we have to
2318
initialize this variable because RESET shares the same code as FLUSH
2320
lex->no_write_to_binlog= 1;
2323
bool write_to_binlog;
2326
reload_cache() will tell us if we are allowed to write to the
2329
if (!reload_cache(thd, lex->type, first_table, &write_to_binlog))
2332
We WANT to write and we CAN write.
2333
! we write after unlocking the table.
2336
Presumably, RESET and binlog writing doesn't require synchronization
2338
if (!lex->no_write_to_binlog && write_to_binlog)
2340
write_bin_log(thd, false, thd->query, thd->query_length);
2349
Item *it= (Item *)lex->value_list.head();
2351
if (lex->table_or_sp_used())
2353
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "Usage of subqueries or stored "
2354
"function calls as part of this statement");
2358
if ((!it->fixed && it->fix_fields(lex->thd, &it)) || it->check_cols(1))
2360
my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
2364
sql_kill(thd, (ulong)it->val_int(), lex->type & ONLY_KILL_QUERY);
2368
if (thd->transaction.xid_state.xa_state != XA_NOTR)
2370
my_error(ER_XAER_RMFAIL, MYF(0),
2371
xa_state_names[thd->transaction.xid_state.xa_state]);
2375
Breakpoints for backup testing.
2377
if (begin_trans(thd))
2382
if (end_trans(thd, lex->tx_release ? COMMIT_RELEASE :
2383
lex->tx_chain ? COMMIT_AND_CHAIN : COMMIT))
2387
case SQLCOM_ROLLBACK:
2388
if (end_trans(thd, lex->tx_release ? ROLLBACK_RELEASE :
2389
lex->tx_chain ? ROLLBACK_AND_CHAIN : ROLLBACK))
2393
case SQLCOM_RELEASE_SAVEPOINT:
2396
for (sv=thd->transaction.savepoints; sv; sv=sv->prev)
2398
if (my_strnncoll(system_charset_info,
2399
(uchar *)lex->ident.str, lex->ident.length,
2400
(uchar *)sv->name, sv->length) == 0)
2405
if (ha_release_savepoint(thd, sv))
2406
res= true; // cannot happen
2409
thd->transaction.savepoints=sv->prev;
2412
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
2415
case SQLCOM_ROLLBACK_TO_SAVEPOINT:
2418
for (sv=thd->transaction.savepoints; sv; sv=sv->prev)
2420
if (my_strnncoll(system_charset_info,
2421
(uchar *)lex->ident.str, lex->ident.length,
2422
(uchar *)sv->name, sv->length) == 0)
2427
if (ha_rollback_to_savepoint(thd, sv))
2428
res= true; // cannot happen
2431
if (((thd->options & OPTION_KEEP_LOG) ||
2432
thd->transaction.all.modified_non_trans_table) &&
2434
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2435
ER_WARNING_NOT_COMPLETE_ROLLBACK,
2436
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
2439
thd->transaction.savepoints=sv;
2442
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
2445
case SQLCOM_SAVEPOINT:
2446
if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) ||
2447
thd->in_sub_stmt) || !opt_using_transactions)
2451
SAVEPOINT **sv, *newsv;
2452
for (sv=&thd->transaction.savepoints; *sv; sv=&(*sv)->prev)
2454
if (my_strnncoll(system_charset_info,
2455
(uchar *)lex->ident.str, lex->ident.length,
2456
(uchar *)(*sv)->name, (*sv)->length) == 0)
2459
if (*sv) /* old savepoint of the same name exists */
2462
ha_release_savepoint(thd, *sv); // it cannot fail
2465
else if ((newsv=(SAVEPOINT *) alloc_root(&thd->transaction.mem_root,
2466
savepoint_alloc_size)) == 0)
2468
my_error(ER_OUT_OF_RESOURCES, MYF(0));
2471
newsv->name=strmake_root(&thd->transaction.mem_root,
2472
lex->ident.str, lex->ident.length);
2473
newsv->length=lex->ident.length;
2475
if we'll get an error here, don't add new savepoint to the list.
2476
we'll lose a little bit of memory in transaction mem_root, but it'll
2477
be free'd when transaction ends anyway
2479
if (ha_savepoint(thd, newsv))
2483
newsv->prev=thd->transaction.savepoints;
2484
thd->transaction.savepoints=newsv;
2489
case SQLCOM_BINLOG_BASE64_EVENT:
2491
mysql_client_binlog_statement(thd);
2495
assert(0); /* Impossible */
2499
thd_proc_info(thd, "query end");
2502
Binlog-related cleanup:
2503
Reset system variables temporarily modified by SET ONE SHOT.
2505
Exception: If this is a SET, do nothing. This is to allow
2506
mysqlbinlog to print many SET commands (in this case we want the
2507
charset temp setting to live until the real query). This is also
2508
needed so that SET CHARACTER_SET_CLIENT... does not cancel itself
2511
if (thd->one_shot_set && lex->sql_command != SQLCOM_SET_OPTION)
2512
reset_one_shot_variables(thd);
491
if (all_tables || ! lex->is_single_level_stmt())
493
drizzle_reset_errors(session, 0);
496
status_var_increment(session->status_var.com_stat[lex->sql_command]);
498
assert(session->transaction.stmt.modified_non_trans_table == false);
500
/* now we are ready to execute the statement */
501
res= lex->statement->execute();
503
session->set_proc_info("query end");
2515
506
The return value for ROW_COUNT() is "implementation dependent" if the