125
179
sql_command_flags[SQLCOM_DROP_INDEX]= CF_CHANGES_DATA;
127
181
sql_command_flags[SQLCOM_UPDATE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
182
sql_command_flags[SQLCOM_UPDATE_MULTI]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
128
183
sql_command_flags[SQLCOM_INSERT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
129
184
sql_command_flags[SQLCOM_INSERT_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
130
185
sql_command_flags[SQLCOM_DELETE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
186
sql_command_flags[SQLCOM_DELETE_MULTI]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
131
187
sql_command_flags[SQLCOM_REPLACE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
132
188
sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
190
sql_command_flags[SQLCOM_SHOW_STATUS]= CF_STATUS_COMMAND;
191
sql_command_flags[SQLCOM_SHOW_DATABASES]= CF_STATUS_COMMAND;
192
sql_command_flags[SQLCOM_SHOW_OPEN_TABLES]= CF_STATUS_COMMAND;
193
sql_command_flags[SQLCOM_SHOW_FIELDS]= CF_STATUS_COMMAND;
194
sql_command_flags[SQLCOM_SHOW_KEYS]= CF_STATUS_COMMAND;
195
sql_command_flags[SQLCOM_SHOW_VARIABLES]= CF_STATUS_COMMAND;
196
sql_command_flags[SQLCOM_SHOW_BINLOGS]= CF_STATUS_COMMAND;
134
197
sql_command_flags[SQLCOM_SHOW_WARNS]= CF_STATUS_COMMAND;
135
198
sql_command_flags[SQLCOM_SHOW_ERRORS]= CF_STATUS_COMMAND;
199
sql_command_flags[SQLCOM_SHOW_ENGINE_STATUS]= CF_STATUS_COMMAND;
200
sql_command_flags[SQLCOM_SHOW_PROCESSLIST]= CF_STATUS_COMMAND;
136
201
sql_command_flags[SQLCOM_SHOW_CREATE_DB]= CF_STATUS_COMMAND;
137
202
sql_command_flags[SQLCOM_SHOW_CREATE]= CF_STATUS_COMMAND;
203
sql_command_flags[SQLCOM_SHOW_MASTER_STAT]= CF_STATUS_COMMAND;
204
sql_command_flags[SQLCOM_SHOW_SLAVE_STAT]= CF_STATUS_COMMAND;
206
sql_command_flags[SQLCOM_SHOW_TABLES]= (CF_STATUS_COMMAND |
207
CF_SHOW_TABLE_COMMAND);
208
sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]= (CF_STATUS_COMMAND |
209
CF_SHOW_TABLE_COMMAND);
140
211
The following admin table operations are allowed
214
sql_command_flags[SQLCOM_REPAIR]= CF_WRITE_LOGS_COMMAND;
215
sql_command_flags[SQLCOM_OPTIMIZE]= CF_WRITE_LOGS_COMMAND;
143
216
sql_command_flags[SQLCOM_ANALYZE]= CF_WRITE_LOGS_COMMAND;
220
bool is_update_query(enum enum_sql_command command)
222
assert(command >= 0 && command <= SQLCOM_END);
223
return (sql_command_flags[command].test(CF_BIT_CHANGES_DATA));
226
void execute_init_command(Session *session, sys_var_str *init_command_var,
227
pthread_rwlock_t *var_mutex)
230
ulong save_client_capabilities;
232
session->set_proc_info("Execution of init_command");
234
We need to lock init_command_var because
235
during execution of init_command_var query
236
values of init_command_var can't be changed
238
pthread_rwlock_rdlock(var_mutex);
239
save_client_capabilities= session->client_capabilities;
240
session->client_capabilities|= CLIENT_MULTI_STATEMENTS;
242
We don't need return result of execution to client side.
243
To forbid this we should set session->net.vio to 0.
245
save_vio= session->net.vio;
247
dispatch_command(COM_QUERY, session,
248
init_command_var->value,
249
init_command_var->value_length);
250
pthread_rwlock_unlock(var_mutex);
251
session->client_capabilities= save_client_capabilities;
252
session->net.vio= save_vio;
256
Ends the current transaction and (maybe) begin the next.
258
@param session Current thread
259
@param completion Completion type
265
int end_trans(Session *session, enum enum_mysql_completiontype completion)
270
if (session->transaction.xid_state.xa_state != XA_NOTR)
272
my_error(ER_XAER_RMFAIL, MYF(0),
273
xa_state_names[session->transaction.xid_state.xa_state]);
276
switch (completion) {
279
We don't use end_active_trans() here to ensure that this works
280
even if there is a problem with the OPTION_AUTO_COMMIT flag
281
(Which of course should never happen...)
283
session->server_status&= ~SERVER_STATUS_IN_TRANS;
284
res= ha_commit(session);
285
session->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
286
session->transaction.all.modified_non_trans_table= false;
289
do_release= 1; /* fall through */
290
case COMMIT_AND_CHAIN:
291
res= end_active_trans(session);
292
if (!res && completion == COMMIT_AND_CHAIN)
293
res= begin_trans(session);
295
case ROLLBACK_RELEASE:
296
do_release= 1; /* fall through */
298
case ROLLBACK_AND_CHAIN:
300
session->server_status&= ~SERVER_STATUS_IN_TRANS;
301
if (ha_rollback(session))
303
session->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
304
session->transaction.all.modified_non_trans_table= false;
305
if (!res && (completion == ROLLBACK_AND_CHAIN))
306
res= begin_trans(session);
311
my_error(ER_UNKNOWN_COM_ERROR, MYF(0));
316
my_error(session->killed_errno(), MYF(0));
317
else if ((res == 0) && do_release)
318
session->killed= Session::KILL_CONNECTION;
325
Read one command from connection and execute it (query or simple command).
326
This function is called in loop from thread function.
328
For profiling to work, it must never be called recursively.
333
1 request of thread shutdown (see dispatch_command() description)
336
bool do_command(Session *session)
341
NET *net= &session->net;
342
enum enum_server_command command;
345
indicator of uninitialized lex => normal flow of errors handling
348
session->lex->current_select= 0;
351
This thread will do a blocking read from the client which
352
will be interrupted when the next command is received from
353
the client, the connection is closed or "net_wait_timeout"
354
number of seconds has passed
356
my_net_set_read_timeout(net, session->variables.net_wait_timeout);
359
XXX: this code is here only to clear possible errors of init_connect.
360
Consider moving to init_connect() instead.
362
session->clear_error(); // Clear error message
363
session->main_da.reset_diagnostics_area();
365
net_new_transaction(net);
367
packet_length= my_net_read(net);
368
if (packet_length == packet_error)
370
/* Check if we can continue without closing the connection */
372
/* The error must be set. */
373
/* This assert is killing me - and tracking down why the error isn't
374
* set here is a waste since the protocol lib is being replaced. */
375
//assert(session->is_error());
376
net_end_statement(session);
380
return_value= true; // We have to close it.
389
packet= (char*) net->read_pos;
391
'packet_length' contains length of data, as it was stored in packet
392
header. In case of malformed header, my_net_read returns zero.
393
If packet_length is not zero, my_net_read ensures that the returned
394
number of bytes was actually read from network.
395
There is also an extra safety measure in my_net_read:
396
it sets packet[packet_length]= 0, but only for non-zero packets.
398
if (packet_length == 0) /* safety */
400
/* Initialize with COM_SLEEP packet */
401
packet[0]= (unsigned char) COM_SLEEP;
404
/* Do not rely on my_net_read, extra safety against programming errors. */
405
packet[packet_length]= '\0'; /* safety */
407
command= (enum enum_server_command) (unsigned char) packet[0];
409
if (command >= COM_END)
410
command= COM_END; // Wrong command
412
/* Restore read timeout value */
413
my_net_set_read_timeout(net, session->variables.net_read_timeout);
415
assert(packet_length);
416
return_value= dispatch_command(command, session, packet+1, (uint32_t) (packet_length-1));
419
return(return_value);
147
423
Perform one connection-level (COM_XXXX) command.
184
460
/* Increase id and count all other statements. */
186
session->status_var.questions++;
462
statistic_increment(session->status_var.questions, &LOCK_status);
190
467
/* TODO: set session->lex->sql_command to SQLCOM_END here */
468
pthread_mutex_unlock(&LOCK_thread_count);
192
plugin::Logging::preDo(session);
193
if (unlikely(plugin::EventObserver::beforeStatement(*session)))
195
// We should do something about an error...
470
logging_pre_do(session);
198
472
session->server_status&=
199
473
~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
200
474
switch (command) {
201
475
case COM_INIT_DB:
203
if (packet_length == 0)
205
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
209
string tmp(packet, packet_length);
211
SchemaIdentifier identifier(tmp);
213
if (not mysql_change_db(session, identifier))
478
status_var_increment(session->status_var.com_stat[SQLCOM_CHANGE_DB]);
479
session->convert_string(&tmp, system_charset_info,
480
packet, packet_length, session->charset());
481
if (!mysql_change_db(session, &tmp, false))
487
case COM_CHANGE_USER:
489
status_var_increment(session->status_var.com_other);
490
char *user= (char*) packet, *packet_end= packet + packet_length;
491
/* Safe because there is always a trailing \0 at the end of the packet */
492
char *passwd= strchr(user, '\0')+1;
495
session->clear_error(); // if errors from rollback
498
Old clients send null-terminated string ('\0' for empty string) for
499
password. New clients send the size (1 byte) + string (not null
500
terminated, so also '\0' for empty string).
502
Cast *passwd to an unsigned char, so that it doesn't extend the sign
503
for *passwd > 127 and become 2**32-127 after casting to uint32_t.
505
char db_buff[NAME_LEN+1]; // buffer to store db in utf8
509
If there is no password supplied, the packet must contain '\0',
510
in any type of handshake (4.1 or pre-4.1).
512
if (passwd >= packet_end)
514
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
517
uint32_t passwd_len= (session->client_capabilities & CLIENT_SECURE_CONNECTION ?
518
(unsigned char)(*passwd++) : strlen(passwd));
519
uint32_t dummy_errors, save_db_length, db_length;
521
USER_CONN *save_user_connect;
526
Database name is always NUL-terminated, so in case of empty database
527
the packet must contain at least the trailing '\0'.
529
if (db >= packet_end)
531
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
534
db_length= strlen(db);
536
char *ptr= db + db_length + 1;
537
uint32_t cs_number= 0;
539
if (ptr < packet_end)
541
if (ptr + 2 > packet_end)
543
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
547
cs_number= uint2korr(ptr);
550
/* Convert database name to utf8 */
551
db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
552
system_charset_info, db, db_length,
553
session->charset(), &dummy_errors)]= 0;
556
/* Save user and privileges */
557
save_db_length= session->db_length;
558
save_db= session->db;
559
save_user_connect= session->user_connect;
561
old_username= session->security_ctx.user;
562
session->security_ctx.user.assign(user);
564
/* Clear variables that are allocated */
565
session->user_connect= 0;
566
res= check_user(session, passwd, passwd_len, db, false);
570
session->security_ctx.user= old_username;
571
session->user_connect= save_user_connect;
572
session->db= save_db;
573
session->db_length= save_db_length;
582
session->update_charset();
221
if (not session->readAndStoreQuery(packet, packet_length))
589
if (alloc_query(session, packet, packet_length))
222
590
break; // fatal error is set
223
DRIZZLE_QUERY_START(session->getQueryString()->c_str(),
225
const_cast<const char *>(session->schema()->c_str()));
227
mysql_parse(session, session->getQueryString()->c_str(), session->getQueryString()->length());
591
char *packet_end= session->query + session->query_length;
592
const char* end_of_stmt= NULL;
594
mysql_parse(session, session->query, session->query_length, &end_of_stmt);
596
while (!session->killed && (end_of_stmt != NULL) && ! session->is_error())
598
char *beginning_of_next_stmt= (char*) end_of_stmt;
600
net_end_statement(session);
602
Multiple queries exits, execute them individually
604
close_thread_tables(session);
605
ulong length= (ulong)(packet_end - beginning_of_next_stmt);
607
log_slow_statement(session);
609
/* Remove garbage at start of query */
610
while (length > 0 && my_isspace(session->charset(), *beginning_of_next_stmt))
612
beginning_of_next_stmt++;
616
pthread_mutex_lock(&LOCK_thread_count);
617
session->query_length= length;
618
session->query= beginning_of_next_stmt;
620
Count each statement from the client.
622
statistic_increment(session->status_var.questions, &LOCK_status);
623
session->query_id= query_id.next();
624
session->set_time(); /* Reset the query start time. */
625
/* TODO: set session->lex->sql_command to SQLCOM_END here */
626
pthread_mutex_unlock(&LOCK_thread_count);
628
mysql_parse(session, beginning_of_next_stmt, length, &end_of_stmt);
632
case COM_FIELD_LIST: // This isn't actually needed
634
char *fields, *packet_end= packet + packet_length, *arg_end;
635
/* Locked closure of all tables */
636
TableList table_list;
637
LEX_STRING conv_name;
639
/* used as fields initializator */
642
status_var_increment(session->status_var.com_stat[SQLCOM_SHOW_FIELDS]);
643
memset(&table_list, 0, sizeof(table_list));
644
if (session->copy_db_to(&table_list.db, &table_list.db_length))
647
We have name + wildcard in packet, separated by endzero
649
arg_end= strchr(packet, '\0');
650
session->convert_string(&conv_name, system_charset_info,
651
packet, (uint32_t) (arg_end - packet), session->charset());
652
table_list.alias= table_list.table_name= conv_name.str;
655
if (!my_strcasecmp(system_charset_info, table_list.db,
656
INFORMATION_SCHEMA_NAME.c_str()))
658
ST_SCHEMA_TABLE *schema_table= find_schema_table(session, table_list.alias);
660
table_list.schema_table= schema_table;
663
session->query_length= (uint32_t) (packet_end - packet); // Don't count end \0
664
if (!(session->query=fields= (char*) session->memdup(packet,session->query_length+1)))
666
if (lower_case_table_names)
667
my_casedn_str(files_charset_info, table_list.table_name);
669
/* init structures for VIEW processing */
670
table_list.select_lex= &(session->lex->select_lex);
673
session->reset_for_next_command();
676
select_lex.table_list.link_in_list((unsigned char*) &table_list,
677
(unsigned char**) &table_list.next_local);
678
session->lex->add_to_query_tables(&table_list);
680
/* switch on VIEW optimisation: do not fill temporary tables */
681
session->lex->sql_command= SQLCOM_SHOW_FIELDS;
682
mysqld_list_fields(session,&table_list,fields);
683
session->lex->unit.cleanup();
684
session->cleanup_after_query();
232
688
/* We don't calculate statistics for this command */
689
net->error=0; // Don't give 'abort' message
233
690
session->main_da.disable_status(); // Don't send anything back
234
691
error=true; // End server
693
case COM_BINLOG_DUMP:
697
uint32_t slave_server_id;
699
status_var_increment(session->status_var.com_other);
700
/* TODO: The following has to be changed to an 8 byte integer */
701
pos = uint4korr(packet);
702
flags = uint2korr(packet + 4);
703
session->server_id=0; /* avoid suicide */
704
if ((slave_server_id= uint4korr(packet+6))) // mysqlbinlog.server_id==0
705
kill_zombie_dump_threads(slave_server_id);
706
session->server_id = slave_server_id;
708
mysql_binlog_send(session, session->strdup(packet + 10), (my_off_t) pos, flags);
709
/* fake COM_QUIT -- if we get here, the thread needs to terminate */
236
713
case COM_SHUTDOWN:
238
session->status_var.com_other++;
240
session->close_thread_tables(); // Free before kill
715
status_var_increment(session->status_var.com_other);
717
close_thread_tables(session); // Free before kill
246
session->status_var.com_other++;
247
session->my_ok(); // Tell client we are alive
723
status_var_increment(session->status_var.com_other);
724
my_ok(session); // Tell client we are alive
726
case COM_PROCESS_INFO:
727
status_var_increment(session->status_var.com_stat[SQLCOM_SHOW_PROCESSLIST]);
728
mysqld_list_processes(session, NULL, 0);
730
case COM_PROCESS_KILL:
732
status_var_increment(session->status_var.com_stat[SQLCOM_KILL]);
733
ulong id=(ulong) uint4korr(packet);
734
sql_kill(session,id,false);
739
status_var_increment(session->status_var.com_stat[SQLCOM_SET_OPTION]);
740
uint32_t opt_command= uint2korr(packet);
742
switch (opt_command) {
743
case (int) DRIZZLE_OPTION_MULTI_STATEMENTS_ON:
744
session->client_capabilities|= CLIENT_MULTI_STATEMENTS;
747
case (int) DRIZZLE_OPTION_MULTI_STATEMENTS_OFF:
748
session->client_capabilities&= ~CLIENT_MULTI_STATEMENTS;
752
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
250
758
case COM_CONNECT: // Impossible here
759
case COM_TIME: // Impossible from client
253
762
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
468
1031
variables, but for now this is probably good enough.
469
1032
Don't reset warnings when executing a stored routine.
471
if (all_tables || ! lex->is_single_level_stmt())
1034
if (all_tables || !lex->is_single_level_stmt())
473
1035
drizzle_reset_errors(session, 0);
476
assert(session->transaction.stmt.hasModifiedNonTransData() == false);
478
/* now we are ready to execute the statement */
479
res= lex->statement->execute();
1037
if (unlikely(session->slave_thread))
1040
Check if statment should be skipped because of slave filtering
1044
- UPDATE MULTI: For this statement, we want to check the filtering
1045
rules later in the code
1046
- SET: we always execute it (Not that many SET commands exists in
1047
the binary log anyway -- only 4.1 masters write SET statements,
1048
in 5.0 there are no SET statements in the binary log)
1049
- DROP TEMPORARY TABLE IF EXISTS: we always execute it (otherwise we
1050
have stale files on slave caused by exclusion of one tmp table).
1052
if (!(lex->sql_command == SQLCOM_UPDATE_MULTI) &&
1053
!(lex->sql_command == SQLCOM_SET_OPTION) &&
1054
!(lex->sql_command == SQLCOM_DROP_TABLE &&
1055
lex->drop_temporary && lex->drop_if_exists) &&
1056
all_tables_not_ok(session, all_tables))
1058
/* we warn the slave SQL thread */
1059
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
1064
status_var_increment(session->status_var.com_stat[lex->sql_command]);
1066
assert(session->transaction.stmt.modified_non_trans_table == false);
1068
switch (lex->sql_command) {
1069
case SQLCOM_SHOW_STATUS:
1071
system_status_var old_status_var= session->status_var;
1072
session->initial_status_var= &old_status_var;
1073
res= execute_sqlcom_select(session, all_tables);
1074
/* Don't log SHOW STATUS commands to slow query log */
1075
session->server_status&= ~(SERVER_QUERY_NO_INDEX_USED |
1076
SERVER_QUERY_NO_GOOD_INDEX_USED);
1078
restore status variables, as we don't want 'show status' to cause
1081
pthread_mutex_lock(&LOCK_status);
1082
add_diff_to_status(&global_status_var, &session->status_var,
1084
session->status_var= old_status_var;
1085
pthread_mutex_unlock(&LOCK_status);
1088
case SQLCOM_SHOW_DATABASES:
1089
case SQLCOM_SHOW_TABLES:
1090
case SQLCOM_SHOW_TABLE_STATUS:
1091
case SQLCOM_SHOW_OPEN_TABLES:
1092
case SQLCOM_SHOW_FIELDS:
1093
case SQLCOM_SHOW_KEYS:
1094
case SQLCOM_SHOW_VARIABLES:
1097
session->status_var.last_query_cost= 0.0;
1098
res= execute_sqlcom_select(session, all_tables);
1101
case SQLCOM_EMPTY_QUERY:
1107
res = purge_master_logs(session, lex->to_log);
1110
case SQLCOM_PURGE_BEFORE:
1114
/* PURGE MASTER LOGS BEFORE 'data' */
1115
it= (Item *)lex->value_list.head();
1116
if ((!it->fixed && it->fix_fields(lex->session, &it)) ||
1119
my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE LOGS BEFORE");
1122
it= new Item_func_unix_timestamp(it);
1124
it is OK only emulate fix_fieds, because we need only
1127
it->quick_fix_field();
1128
res = purge_master_logs_before_date(session, (ulong)it->val_int());
1131
case SQLCOM_SHOW_WARNS:
1133
res= mysqld_show_warnings(session, (uint32_t)
1134
((1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_NOTE) |
1135
(1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_WARN) |
1136
(1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR)
1140
case SQLCOM_SHOW_ERRORS:
1142
res= mysqld_show_warnings(session, (uint32_t)
1143
(1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR));
1146
case SQLCOM_ASSIGN_TO_KEYCACHE:
1148
assert(first_table == all_tables && first_table != 0);
1149
res= mysql_assign_to_keycache(session, first_table, &lex->ident);
1152
case SQLCOM_CHANGE_MASTER:
1154
pthread_mutex_lock(&LOCK_active_mi);
1155
res = change_master(session,active_mi);
1156
pthread_mutex_unlock(&LOCK_active_mi);
1159
case SQLCOM_SHOW_SLAVE_STAT:
1161
pthread_mutex_lock(&LOCK_active_mi);
1162
if (active_mi != NULL)
1164
res = show_master_info(session, active_mi);
1168
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1169
"the master info structure does not exist");
1172
pthread_mutex_unlock(&LOCK_active_mi);
1175
case SQLCOM_SHOW_MASTER_STAT:
1177
res = show_binlog_info(session);
1181
case SQLCOM_SHOW_ENGINE_STATUS:
1183
res = ha_show_status(session, lex->create_info.db_type, HA_ENGINE_STATUS);
1186
case SQLCOM_CREATE_TABLE:
1188
/* If CREATE TABLE of non-temporary table, do implicit commit */
1189
if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE))
1191
if (end_active_trans(session))
1197
assert(first_table == all_tables && first_table != 0);
1199
// Skip first table, which is the table we are creating
1200
TableList *create_table= lex->unlink_first_table(&link_to_local);
1201
TableList *select_tables= lex->query_tables;
1203
Code below (especially in mysql_create_table() and select_create
1204
methods) may modify HA_CREATE_INFO structure in LEX, so we have to
1205
use a copy of this structure to make execution prepared statement-
1206
safe. A shallow copy is enough as this code won't modify any memory
1207
referenced from this structure.
1209
HA_CREATE_INFO create_info(lex->create_info);
1211
We need to copy alter_info for the same reasons of re-execution
1212
safety, only in case of Alter_info we have to do (almost) a deep
1215
Alter_info alter_info(lex->alter_info, session->mem_root);
1217
if (session->is_fatal_error)
1219
/* If out of memory when creating a copy of alter_info. */
1221
goto end_with_restore_list;
1224
if ((res= create_table_precheck(session, select_tables, create_table)))
1225
goto end_with_restore_list;
1227
/* Might have been updated in create_table_precheck */
1228
create_info.alias= create_table->alias;
1230
#ifdef HAVE_READLINK
1231
/* Fix names if symlinked tables */
1232
if (append_file_to_dir(session, &create_info.data_file_name,
1233
create_table->table_name) ||
1234
append_file_to_dir(session, &create_info.index_file_name,
1235
create_table->table_name))
1236
goto end_with_restore_list;
1239
If we are using SET CHARSET without DEFAULT, add an implicit
1240
DEFAULT to not confuse old users. (This may change).
1242
if ((create_info.used_fields &
1243
(HA_CREATE_USED_DEFAULT_CHARSET | HA_CREATE_USED_CHARSET)) ==
1244
HA_CREATE_USED_CHARSET)
1246
create_info.used_fields&= ~HA_CREATE_USED_CHARSET;
1247
create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
1248
create_info.default_table_charset= create_info.table_charset;
1249
create_info.table_charset= 0;
1252
The create-select command will open and read-lock the select table
1253
and then create, open and write-lock the new table. If a global
1254
read lock steps in, we get a deadlock. The write lock waits for
1255
the global read lock, while the global read lock waits for the
1256
select table to be closed. So we wait until the global readlock is
1257
gone before starting both steps. Note that
1258
wait_if_global_read_lock() sets a protection against a new global
1259
read lock when it succeeds. This needs to be released by
1260
start_waiting_global_read_lock(). We protect the normal CREATE
1261
TABLE in the same way. That way we avoid that a new table is
1262
created during a gobal read lock.
1264
if (!session->locked_tables &&
1265
!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
1268
goto end_with_restore_list;
1270
if (select_lex->item_list.elements) // With select
1272
select_result *result;
1274
select_lex->options|= SELECT_NO_UNLOCK;
1275
unit->set_limit(select_lex);
1277
if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
1279
lex->link_first_table_back(create_table, link_to_local);
1280
create_table->create= true;
1283
if (!(res= open_and_lock_tables(session, lex->query_tables)))
1286
Is table which we are changing used somewhere in other parts
1289
if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
1291
TableList *duplicate;
1292
create_table= lex->unlink_first_table(&link_to_local);
1293
if ((duplicate= unique_table(session, create_table, select_tables, 0)))
1295
update_non_unique_table_error(create_table, "CREATE", duplicate);
1297
goto end_with_restore_list;
1302
select_create is currently not re-execution friendly and
1303
needs to be created for every execution of a PS/SP.
1305
if ((result= new select_create(create_table,
1308
select_lex->item_list,
1314
CREATE from SELECT give its SELECT_LEX for SELECT,
1315
and item_list belong to SELECT
1317
res= handle_select(session, lex, result, 0);
1321
else if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
1322
create_table= lex->unlink_first_table(&link_to_local);
1327
/* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
1328
if (create_info.options & HA_LEX_CREATE_TMP_TABLE)
1329
session->options|= OPTION_KEEP_LOG;
1330
/* regular create */
1331
if (create_info.options & HA_LEX_CREATE_TABLE_LIKE)
1332
res= mysql_create_like_table(session, create_table, select_tables,
1336
res= mysql_create_table(session, create_table->db,
1337
create_table->table_name, &create_info,
1344
/* put tables back for PS rexecuting */
1345
end_with_restore_list:
1346
lex->link_first_table_back(create_table, link_to_local);
1349
case SQLCOM_CREATE_INDEX:
1351
case SQLCOM_DROP_INDEX:
1353
CREATE INDEX and DROP INDEX are implemented by calling ALTER
1354
TABLE with proper arguments.
1356
In the future ALTER TABLE will notice that the request is to
1357
only add indexes and create these one by one for the existing
1358
table without having to do a full rebuild.
1361
/* Prepare stack copies to be re-execution safe */
1362
HA_CREATE_INFO create_info;
1363
Alter_info alter_info(lex->alter_info, session->mem_root);
1365
if (session->is_fatal_error) /* out of memory creating a copy of alter_info */
1368
assert(first_table == all_tables && first_table != 0);
1369
if (end_active_trans(session))
1372
memset(&create_info, 0, sizeof(create_info));
1373
create_info.db_type= 0;
1374
create_info.row_type= ROW_TYPE_NOT_USED;
1375
create_info.default_table_charset= session->variables.collation_database;
1377
res= mysql_alter_table(session, first_table->db, first_table->table_name,
1378
&create_info, first_table, &alter_info,
1379
0, (order_st*) 0, 0);
1382
case SQLCOM_SLAVE_START:
1384
pthread_mutex_lock(&LOCK_active_mi);
1385
start_slave(session,active_mi,1 /* net report*/);
1386
pthread_mutex_unlock(&LOCK_active_mi);
1389
case SQLCOM_SLAVE_STOP:
1391
If the client thread has locked tables, a deadlock is possible.
1393
- the client thread does LOCK TABLE t READ.
1394
- then the master updates t.
1395
- then the SQL slave thread wants to update t,
1396
so it waits for the client thread because t is locked by it.
1397
- then the client thread does SLAVE STOP.
1398
SLAVE STOP waits for the SQL slave thread to terminate its
1399
update t, which waits for the client thread because t is locked by it.
1400
To prevent that, refuse SLAVE STOP if the
1401
client thread has locked tables
1403
if (session->locked_tables || session->active_transaction() || session->global_read_lock)
1405
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
1406
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
1410
pthread_mutex_lock(&LOCK_active_mi);
1411
stop_slave(session,active_mi,1/* net report*/);
1412
pthread_mutex_unlock(&LOCK_active_mi);
1416
case SQLCOM_ALTER_TABLE:
1417
assert(first_table == all_tables && first_table != 0);
1420
Code in mysql_alter_table() may modify its HA_CREATE_INFO argument,
1421
so we have to use a copy of this structure to make execution
1422
prepared statement- safe. A shallow copy is enough as no memory
1423
referenced from this structure will be modified.
1425
HA_CREATE_INFO create_info(lex->create_info);
1426
Alter_info alter_info(lex->alter_info, session->mem_root);
1428
if (session->is_fatal_error) /* out of memory creating a copy of alter_info */
1433
/* Must be set in the parser */
1434
assert(select_lex->db);
1436
{ // Rename of table
1437
TableList tmp_table;
1438
memset(&tmp_table, 0, sizeof(tmp_table));
1439
tmp_table.table_name= lex->name.str;
1440
tmp_table.db=select_lex->db;
1443
/* Don't yet allow changing of symlinks with ALTER TABLE */
1444
if (create_info.data_file_name)
1445
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1446
"DATA DIRECTORY option ignored");
1447
if (create_info.index_file_name)
1448
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1449
"INDEX DIRECTORY option ignored");
1450
create_info.data_file_name= create_info.index_file_name= NULL;
1451
/* ALTER TABLE ends previous transaction */
1452
if (end_active_trans(session))
1455
if (!session->locked_tables &&
1456
!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
1462
res= mysql_alter_table(session, select_lex->db, lex->name.str,
1466
select_lex->order_list.elements,
1467
(order_st *) select_lex->order_list.first,
1471
case SQLCOM_RENAME_TABLE:
1473
assert(first_table == all_tables && first_table != 0);
1475
for (table= first_table; table; table= table->next_local->next_local)
1477
TableList old_list, new_list;
1479
we do not need initialize old_list and new_list because we will
1480
come table[0] and table->next[0] there
1483
new_list= table->next_local[0];
1486
if (end_active_trans(session) || drizzle_rename_tables(session, first_table, 0))
1492
case SQLCOM_SHOW_BINLOGS:
1494
res = show_binlogs(session);
1497
case SQLCOM_SHOW_CREATE:
1498
assert(first_table == all_tables && first_table != 0);
1500
res= mysqld_show_create(session, first_table);
1503
case SQLCOM_CHECKSUM:
1505
assert(first_table == all_tables && first_table != 0);
1506
res = mysql_checksum_table(session, first_table, &lex->check_opt);
1511
assert(first_table == all_tables && first_table != 0);
1512
res= mysql_repair_table(session, first_table, &lex->check_opt);
1513
/* ! we write after unlocking the table */
1515
Presumably, REPAIR and binlog writing doesn't require synchronization
1517
write_bin_log(session, true, session->query, session->query_length);
1518
select_lex->table_list.first= (unsigned char*) first_table;
1519
lex->query_tables=all_tables;
1524
assert(first_table == all_tables && first_table != 0);
1525
res = mysql_check_table(session, first_table, &lex->check_opt);
1526
select_lex->table_list.first= (unsigned char*) first_table;
1527
lex->query_tables=all_tables;
1530
case SQLCOM_ANALYZE:
1532
assert(first_table == all_tables && first_table != 0);
1533
res= mysql_analyze_table(session, first_table, &lex->check_opt);
1534
/* ! we write after unlocking the table */
1535
write_bin_log(session, true, session->query, session->query_length);
1536
select_lex->table_list.first= (unsigned char*) first_table;
1537
lex->query_tables=all_tables;
1541
case SQLCOM_OPTIMIZE:
1543
assert(first_table == all_tables && first_table != 0);
1544
res= mysql_optimize_table(session, first_table, &lex->check_opt);
1545
/* ! we write after unlocking the table */
1546
write_bin_log(session, true, session->query, session->query_length);
1547
select_lex->table_list.first= (unsigned char*) first_table;
1548
lex->query_tables=all_tables;
1552
assert(first_table == all_tables && first_table != 0);
1553
if (update_precheck(session, all_tables))
1555
assert(select_lex->offset_limit == 0);
1556
unit->set_limit(select_lex);
1557
res= (up_result= mysql_update(session, all_tables,
1558
select_lex->item_list,
1561
select_lex->order_list.elements,
1562
(order_st *) select_lex->order_list.first,
1563
unit->select_limit_cnt,
1564
lex->duplicates, lex->ignore));
1565
/* mysql_update return 2 if we need to switch to multi-update */
1569
case SQLCOM_UPDATE_MULTI:
1571
assert(first_table == all_tables && first_table != 0);
1572
/* if we switched from normal update, rights are checked */
1575
if ((res= multi_update_precheck(session, all_tables)))
1581
res= mysql_multi_update_prepare(session);
1583
/* Check slave filtering rules */
1584
if (unlikely(session->slave_thread))
1586
if (all_tables_not_ok(session, all_tables))
1590
res= 0; /* don't care of prev failure */
1591
session->clear_error(); /* filters are of highest prior */
1593
/* we warn the slave SQL thread */
1594
my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
1607
res= mysql_multi_update(session, all_tables,
1608
&select_lex->item_list,
1611
select_lex->options,
1612
lex->duplicates, lex->ignore, unit, select_lex);
1615
case SQLCOM_REPLACE:
1618
assert(first_table == all_tables && first_table != 0);
1619
if ((res= insert_precheck(session, all_tables)))
1622
if (!session->locked_tables &&
1623
!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
1629
res= mysql_insert(session, all_tables, lex->field_list, lex->many_values,
1630
lex->update_list, lex->value_list,
1631
lex->duplicates, lex->ignore);
1635
case SQLCOM_REPLACE_SELECT:
1636
case SQLCOM_INSERT_SELECT:
1638
select_result *sel_result;
1639
assert(first_table == all_tables && first_table != 0);
1640
if ((res= insert_precheck(session, all_tables)))
1643
/* Fix lock for first table */
1644
if (first_table->lock_type == TL_WRITE_DELAYED)
1645
first_table->lock_type= TL_WRITE;
1647
/* Don't unlock tables until command is written to binary log */
1648
select_lex->options|= SELECT_NO_UNLOCK;
1650
unit->set_limit(select_lex);
1652
if (! session->locked_tables &&
1653
! (need_start_waiting= ! wait_if_global_read_lock(session, 0, 1)))
1659
if (!(res= open_and_lock_tables(session, all_tables)))
1661
/* Skip first table, which is the table we are inserting in */
1662
TableList *second_table= first_table->next_local;
1663
select_lex->table_list.first= (unsigned char*) second_table;
1664
select_lex->context.table_list=
1665
select_lex->context.first_name_resolution_table= second_table;
1666
res= mysql_insert_select_prepare(session);
1667
if (!res && (sel_result= new select_insert(first_table,
1675
res= handle_select(session, lex, sel_result, OPTION_SETUP_TABLES_DONE);
1677
Invalidate the table in the query cache if something changed
1678
after unlocking when changes become visible.
1679
TODO: this is workaround. right way will be move invalidating in
1680
the unlock procedure.
1682
if (first_table->lock_type == TL_WRITE_CONCURRENT_INSERT &&
1685
/* INSERT ... SELECT should invalidate only the very first table */
1686
TableList *save_table= first_table->next_local;
1687
first_table->next_local= 0;
1688
first_table->next_local= save_table;
1692
/* revert changes for SP */
1693
select_lex->table_list.first= (unsigned char*) first_table;
1698
case SQLCOM_TRUNCATE:
1699
if (end_active_trans(session))
1704
assert(first_table == all_tables && first_table != 0);
1706
Don't allow this within a transaction because we want to use
1709
if (session->locked_tables || session->active_transaction())
1711
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
1712
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
1716
res= mysql_truncate(session, first_table, 0);
1721
assert(first_table == all_tables && first_table != 0);
1722
assert(select_lex->offset_limit == 0);
1723
unit->set_limit(select_lex);
1725
if (!session->locked_tables &&
1726
!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
1732
res = mysql_delete(session, all_tables, select_lex->where,
1733
&select_lex->order_list,
1734
unit->select_limit_cnt, select_lex->options,
1738
case SQLCOM_DELETE_MULTI:
1740
assert(first_table == all_tables && first_table != 0);
1741
TableList *aux_tables=
1742
(TableList *)session->lex->auxiliary_table_list.first;
1743
multi_delete *del_result;
1745
if (!session->locked_tables &&
1746
!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
1752
if ((res= multi_delete_precheck(session, all_tables)))
1755
/* condition will be true on SP re-excuting */
1756
if (select_lex->item_list.elements != 0)
1757
select_lex->item_list.empty();
1758
if (add_item_to_list(session, new Item_null()))
1761
session->set_proc_info("init");
1762
if ((res= open_and_lock_tables(session, all_tables)))
1765
if ((res= mysql_multi_delete_prepare(session)))
1768
if (!session->is_fatal_error &&
1769
(del_result= new multi_delete(aux_tables, lex->table_count)))
1771
res= mysql_select(session, &select_lex->ref_pointer_array,
1772
select_lex->get_table_list(),
1773
select_lex->with_wild,
1774
select_lex->item_list,
1776
0, (order_st *)NULL, (order_st *)NULL, (Item *)NULL,
1778
select_lex->options | session->options |
1779
SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
1780
OPTION_SETUP_TABLES_DONE,
1781
del_result, unit, select_lex);
1782
res|= session->is_error();
1784
del_result->abort();
1791
case SQLCOM_DROP_TABLE:
1793
assert(first_table == all_tables && first_table != 0);
1794
if (!lex->drop_temporary)
1796
if (end_active_trans(session))
1802
If this is a slave thread, we may sometimes execute some
1803
DROP / * 40005 TEMPORARY * / TABLE
1804
that come from parts of binlogs (likely if we use RESET SLAVE or CHANGE
1805
MASTER TO), while the temporary table has already been dropped.
1806
To not generate such irrelevant "table does not exist errors",
1807
we silently add IF EXISTS if TEMPORARY was used.
1809
if (session->slave_thread)
1810
lex->drop_if_exists= 1;
1812
/* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
1813
session->options|= OPTION_KEEP_LOG;
1815
/* DDL and binlog write order protected by LOCK_open */
1816
res= mysql_rm_table(session, first_table, lex->drop_if_exists, lex->drop_temporary);
1819
case SQLCOM_SHOW_PROCESSLIST:
1820
mysqld_list_processes(session, NULL, lex->verbose);
1822
case SQLCOM_SHOW_ENGINE_LOGS:
1824
res= ha_show_status(session, lex->create_info.db_type, HA_ENGINE_LOGS);
1827
case SQLCOM_CHANGE_DB:
1829
LEX_STRING db_str= { (char *) select_lex->db, strlen(select_lex->db) };
1831
if (!mysql_change_db(session, &db_str, false))
1839
assert(first_table == all_tables && first_table != 0);
1840
if (lex->local_file)
1842
if (!(session->client_capabilities & CLIENT_LOCAL_FILES) ||
1845
my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), MYF(0));
1850
res= mysql_load(session, lex->exchange, first_table, lex->field_list,
1851
lex->update_list, lex->value_list, lex->duplicates,
1852
lex->ignore, (bool) lex->local_file);
1856
case SQLCOM_SET_OPTION:
1858
List<set_var_base> *lex_var_list= &lex->var_list;
1860
if (lex->autocommit && end_active_trans(session))
1863
if (open_and_lock_tables(session, all_tables))
1865
if (!(res= sql_set_variables(session, lex_var_list)))
1872
We encountered some sort of error, but no message was sent.
1873
Send something semi-generic here since we don't know which
1874
assignment in the list caused the error.
1876
if (!session->is_error())
1877
my_error(ER_WRONG_ARGUMENTS,MYF(0),"SET");
1884
case SQLCOM_UNLOCK_TABLES:
1886
It is critical for mysqldump --single-transaction --master-data that
1887
UNLOCK TABLES does not implicitely commit a connection which has only
1888
done FLUSH TABLES WITH READ LOCK + BEGIN. If this assumption becomes
1889
false, mysqldump will not work.
1891
unlock_locked_tables(session);
1892
if (session->options & OPTION_TABLE_LOCK)
1894
end_active_trans(session);
1895
session->options&= ~(OPTION_TABLE_LOCK);
1897
if (session->global_read_lock)
1898
unlock_global_read_lock(session);
1901
case SQLCOM_LOCK_TABLES:
1903
We try to take transactional locks if
1904
- only transactional locks are requested (lex->lock_transactional) and
1905
- no non-transactional locks exist (!session->locked_tables).
1907
if (lex->lock_transactional && !session->locked_tables)
1911
All requested locks are transactional and no non-transactional
1914
if ((rc= try_transactional_lock(session, all_tables)) == -1)
1922
Non-transactional locking has been requested or
1923
non-transactional locks exist already or transactional locks are
1924
not supported by all storage engines. Take non-transactional
1929
One or more requested locks are non-transactional and/or
1930
non-transactional locks exist or a storage engine does not support
1931
transactional locks. Check if at least one transactional lock is
1932
requested. If yes, warn about the conversion to non-transactional
1933
locks or abort in strict mode.
1935
if (check_transactional_lock(session, all_tables))
1937
unlock_locked_tables(session);
1938
/* we must end the trasaction first, regardless of anything */
1939
if (end_active_trans(session))
1941
session->in_lock_tables=1;
1942
session->options|= OPTION_TABLE_LOCK;
1944
if (!(res= simple_open_n_lock_tables(session, all_tables)))
1946
session->locked_tables=session->lock;
1948
(void) set_handler_table_locks(session, all_tables, false);
1954
Need to end the current transaction, so the storage engine (InnoDB)
1955
can free its locks if LOCK TABLES locked some tables before finding
1956
that it can't lock a table in its list
1958
ha_autocommit_or_rollback(session, 1);
1959
end_active_trans(session);
1960
session->options&= ~(OPTION_TABLE_LOCK);
1962
session->in_lock_tables=0;
1964
case SQLCOM_CREATE_DB:
1967
As mysql_create_db() may modify HA_CREATE_INFO structure passed to
1968
it, we need to use a copy of LEX::create_info to make execution
1969
prepared statement- safe.
1971
HA_CREATE_INFO create_info(lex->create_info);
1972
if (end_active_trans(session))
1978
if (!(alias=session->strmake(lex->name.str, lex->name.length)) ||
1979
check_db_name(&lex->name))
1981
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
1984
res= mysql_create_db(session,(lower_case_table_names == 2 ? alias :
1985
lex->name.str), &create_info, 0);
1988
case SQLCOM_DROP_DB:
1990
if (end_active_trans(session))
1995
if (check_db_name(&lex->name))
1997
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
2000
if (session->locked_tables || session->active_transaction())
2002
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
2003
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
2006
res= mysql_rm_db(session, lex->name.str, lex->drop_if_exists, 0);
2009
case SQLCOM_ALTER_DB:
2011
LEX_STRING *db= &lex->name;
2012
HA_CREATE_INFO create_info(lex->create_info);
2013
if (check_db_name(db))
2015
my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
2018
if (session->locked_tables || session->active_transaction())
2020
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
2021
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
2024
res= mysql_alter_db(session, db->str, &create_info);
2027
case SQLCOM_SHOW_CREATE_DB:
2029
if (check_db_name(&lex->name))
2031
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
2034
res= mysqld_show_create_db(session, lex->name.str, &lex->create_info);
2040
bool write_to_binlog;
2043
reload_cache() will tell us if we are allowed to write to the
2046
if (!reload_cache(session, lex->type, first_table, &write_to_binlog))
2049
We WANT to write and we CAN write.
2050
! we write after unlocking the table.
2053
Presumably, RESET and binlog writing doesn't require synchronization
2055
write_bin_log(session, false, session->query, session->query_length);
2063
Item *it= (Item *)lex->value_list.head();
2065
if ((!it->fixed && it->fix_fields(lex->session, &it)) || it->check_cols(1))
2067
my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
2071
sql_kill(session, (ulong)it->val_int(), lex->type & ONLY_KILL_QUERY);
2075
if (session->transaction.xid_state.xa_state != XA_NOTR)
2077
my_error(ER_XAER_RMFAIL, MYF(0),
2078
xa_state_names[session->transaction.xid_state.xa_state]);
2082
Breakpoints for backup testing.
2084
if (begin_trans(session))
2089
if (end_trans(session, lex->tx_release ? COMMIT_RELEASE :
2090
lex->tx_chain ? COMMIT_AND_CHAIN : COMMIT))
2094
case SQLCOM_ROLLBACK:
2095
if (end_trans(session, lex->tx_release ? ROLLBACK_RELEASE :
2096
lex->tx_chain ? ROLLBACK_AND_CHAIN : ROLLBACK))
2100
case SQLCOM_RELEASE_SAVEPOINT:
2103
for (sv=session->transaction.savepoints; sv; sv=sv->prev)
2105
if (my_strnncoll(system_charset_info,
2106
(unsigned char *)lex->ident.str, lex->ident.length,
2107
(unsigned char *)sv->name, sv->length) == 0)
2112
if (ha_release_savepoint(session, sv))
2113
res= true; // cannot happen
2116
session->transaction.savepoints=sv->prev;
2119
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
2122
case SQLCOM_ROLLBACK_TO_SAVEPOINT:
2125
for (sv=session->transaction.savepoints; sv; sv=sv->prev)
2127
if (my_strnncoll(system_charset_info,
2128
(unsigned char *)lex->ident.str, lex->ident.length,
2129
(unsigned char *)sv->name, sv->length) == 0)
2134
if (ha_rollback_to_savepoint(session, sv))
2135
res= true; // cannot happen
2138
if (((session->options & OPTION_KEEP_LOG) ||
2139
session->transaction.all.modified_non_trans_table) &&
2140
!session->slave_thread)
2141
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2142
ER_WARNING_NOT_COMPLETE_ROLLBACK,
2143
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
2146
session->transaction.savepoints=sv;
2149
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
2152
case SQLCOM_SAVEPOINT:
2153
if (!(session->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) || !opt_using_transactions)
2157
SAVEPOINT **sv, *newsv;
2158
for (sv=&session->transaction.savepoints; *sv; sv=&(*sv)->prev)
2160
if (my_strnncoll(system_charset_info,
2161
(unsigned char *)lex->ident.str, lex->ident.length,
2162
(unsigned char *)(*sv)->name, (*sv)->length) == 0)
2165
if (*sv) /* old savepoint of the same name exists */
2168
ha_release_savepoint(session, *sv); // it cannot fail
2171
else if ((newsv=(SAVEPOINT *) alloc_root(&session->transaction.mem_root,
2172
savepoint_alloc_size)) == 0)
2174
my_error(ER_OUT_OF_RESOURCES, MYF(0));
2177
newsv->name=strmake_root(&session->transaction.mem_root,
2178
lex->ident.str, lex->ident.length);
2179
newsv->length=lex->ident.length;
2181
if we'll get an error here, don't add new savepoint to the list.
2182
we'll lose a little bit of memory in transaction mem_root, but it'll
2183
be free'd when transaction ends anyway
2185
if (ha_savepoint(session, newsv))
2189
newsv->prev=session->transaction.savepoints;
2190
session->transaction.savepoints=newsv;
2195
case SQLCOM_BINLOG_BASE64_EVENT:
2197
mysql_client_binlog_statement(session);
2201
assert(0); /* Impossible */
480
2205
session->set_proc_info("query end");
482
2208
The return value for ROW_COUNT() is "implementation dependent" if the
483
2209
statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC
484
2210
wants. We also keep the last value in case of SQLCOM_CALL or
487
if (! (sql_command_flags[lex->sql_command].test(CF_BIT_HAS_ROW_COUNT)))
2213
if (!(sql_command_flags[lex->sql_command].test(CF_BIT_HAS_ROW_COUNT)))
489
2214
session->row_count_func= -1;
2222
if (need_start_waiting)
2225
Release the protection against the global read lock and wake
2226
everyone, who might want to set a global read lock.
2228
start_waiting_global_read_lock(session);
492
return (res || session->is_error());
2230
return(res || session->is_error());
494
2233
bool execute_sqlcom_select(Session *session, TableList *all_tables)
496
2235
LEX *lex= session->lex;
497
2236
select_result *result=lex->result;
499
2238
/* assign global limit variable if limit is not given */
501
Select_Lex *param= lex->unit.global_parameters;
2240
SELECT_LEX *param= lex->unit.global_parameters;
502
2241
if (!param->explicit_limit)
503
2242
param->select_limit=
504
2243
new Item_int((uint64_t) session->variables.select_limit);
506
if (not (res= session->openTablesLock(all_tables)))
2245
if (!(res= open_and_lock_tables(session, all_tables)))
508
2247
if (lex->describe)