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
assert(session->is_error());
374
net_end_statement(session);
378
return_value= true; // We have to close it.
387
packet= (char*) net->read_pos;
389
'packet_length' contains length of data, as it was stored in packet
390
header. In case of malformed header, my_net_read returns zero.
391
If packet_length is not zero, my_net_read ensures that the returned
392
number of bytes was actually read from network.
393
There is also an extra safety measure in my_net_read:
394
it sets packet[packet_length]= 0, but only for non-zero packets.
396
if (packet_length == 0) /* safety */
398
/* Initialize with COM_SLEEP packet */
399
packet[0]= (unsigned char) COM_SLEEP;
402
/* Do not rely on my_net_read, extra safety against programming errors. */
403
packet[packet_length]= '\0'; /* safety */
405
command= (enum enum_server_command) (unsigned char) packet[0];
407
if (command >= COM_END)
408
command= COM_END; // Wrong command
410
/* Restore read timeout value */
411
my_net_set_read_timeout(net, session->variables.net_read_timeout);
413
assert(packet_length);
414
return_value= dispatch_command(command, session, packet+1, (uint32_t) (packet_length-1));
417
return(return_value);
147
421
Perform one connection-level (COM_XXXX) command.
184
458
/* Increase id and count all other statements. */
186
session->status_var.questions++;
460
statistic_increment(session->status_var.questions, &LOCK_status);
190
465
/* TODO: set session->lex->sql_command to SQLCOM_END here */
466
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...
468
logging_pre_do(session);
198
470
session->server_status&=
199
471
~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
200
472
switch (command) {
201
473
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))
476
status_var_increment(session->status_var.com_stat[SQLCOM_CHANGE_DB]);
477
session->convert_string(&tmp, system_charset_info,
478
packet, packet_length, session->charset());
479
if (!mysql_change_db(session, &tmp, false))
485
case COM_CHANGE_USER:
487
status_var_increment(session->status_var.com_other);
488
char *user= (char*) packet, *packet_end= packet + packet_length;
489
/* Safe because there is always a trailing \0 at the end of the packet */
490
char *passwd= strchr(user, '\0')+1;
493
session->clear_error(); // if errors from rollback
496
Old clients send null-terminated string ('\0' for empty string) for
497
password. New clients send the size (1 byte) + string (not null
498
terminated, so also '\0' for empty string).
500
Cast *passwd to an unsigned char, so that it doesn't extend the sign
501
for *passwd > 127 and become 2**32-127 after casting to uint32_t.
503
char db_buff[NAME_LEN+1]; // buffer to store db in utf8
507
If there is no password supplied, the packet must contain '\0',
508
in any type of handshake (4.1 or pre-4.1).
510
if (passwd >= packet_end)
512
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
515
uint32_t passwd_len= (session->client_capabilities & CLIENT_SECURE_CONNECTION ?
516
(unsigned char)(*passwd++) : strlen(passwd));
517
uint32_t dummy_errors, save_db_length, db_length;
519
USER_CONN *save_user_connect;
524
Database name is always NUL-terminated, so in case of empty database
525
the packet must contain at least the trailing '\0'.
527
if (db >= packet_end)
529
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
532
db_length= strlen(db);
534
char *ptr= db + db_length + 1;
535
uint32_t cs_number= 0;
537
if (ptr < packet_end)
539
if (ptr + 2 > packet_end)
541
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
545
cs_number= uint2korr(ptr);
548
/* Convert database name to utf8 */
549
db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
550
system_charset_info, db, db_length,
551
session->charset(), &dummy_errors)]= 0;
554
/* Save user and privileges */
555
save_db_length= session->db_length;
556
save_db= session->db;
557
save_user_connect= session->user_connect;
559
old_username= session->security_ctx.user;
560
session->security_ctx.user.assign(user);
562
/* Clear variables that are allocated */
563
session->user_connect= 0;
564
res= check_user(session, passwd, passwd_len, db, false);
568
session->security_ctx.user= old_username;
569
session->user_connect= save_user_connect;
570
session->db= save_db;
571
session->db_length= save_db_length;
580
session->update_charset();
221
if (not session->readAndStoreQuery(packet, packet_length))
587
if (alloc_query(session, packet, packet_length))
222
588
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());
589
char *packet_end= session->query + session->query_length;
590
const char* end_of_stmt= NULL;
592
mysql_parse(session, session->query, session->query_length, &end_of_stmt);
594
while (!session->killed && (end_of_stmt != NULL) && ! session->is_error())
596
char *beginning_of_next_stmt= (char*) end_of_stmt;
598
net_end_statement(session);
600
Multiple queries exits, execute them individually
602
close_thread_tables(session);
603
ulong length= (ulong)(packet_end - beginning_of_next_stmt);
605
log_slow_statement(session);
607
/* Remove garbage at start of query */
608
while (length > 0 && my_isspace(session->charset(), *beginning_of_next_stmt))
610
beginning_of_next_stmt++;
614
pthread_mutex_lock(&LOCK_thread_count);
615
session->query_length= length;
616
session->query= beginning_of_next_stmt;
618
Count each statement from the client.
620
statistic_increment(session->status_var.questions, &LOCK_status);
621
session->query_id= query_id.next();
622
session->set_time(); /* Reset the query start time. */
623
/* TODO: set session->lex->sql_command to SQLCOM_END here */
624
pthread_mutex_unlock(&LOCK_thread_count);
626
mysql_parse(session, beginning_of_next_stmt, length, &end_of_stmt);
630
case COM_FIELD_LIST: // This isn't actually needed
632
char *fields, *packet_end= packet + packet_length, *arg_end;
633
/* Locked closure of all tables */
634
TableList table_list;
635
LEX_STRING conv_name;
637
/* used as fields initializator */
640
status_var_increment(session->status_var.com_stat[SQLCOM_SHOW_FIELDS]);
641
memset(&table_list, 0, sizeof(table_list));
642
if (session->copy_db_to(&table_list.db, &table_list.db_length))
645
We have name + wildcard in packet, separated by endzero
647
arg_end= strchr(packet, '\0');
648
session->convert_string(&conv_name, system_charset_info,
649
packet, (uint32_t) (arg_end - packet), session->charset());
650
table_list.alias= table_list.table_name= conv_name.str;
653
if (!my_strcasecmp(system_charset_info, table_list.db,
654
INFORMATION_SCHEMA_NAME.c_str()))
656
ST_SCHEMA_TABLE *schema_table= find_schema_table(session, table_list.alias);
658
table_list.schema_table= schema_table;
661
session->query_length= (uint32_t) (packet_end - packet); // Don't count end \0
662
if (!(session->query=fields= (char*) session->memdup(packet,session->query_length+1)))
664
if (lower_case_table_names)
665
my_casedn_str(files_charset_info, table_list.table_name);
667
/* init structures for VIEW processing */
668
table_list.select_lex= &(session->lex->select_lex);
671
session->reset_for_next_command();
674
select_lex.table_list.link_in_list((unsigned char*) &table_list,
675
(unsigned char**) &table_list.next_local);
676
session->lex->add_to_query_tables(&table_list);
678
/* switch on VIEW optimisation: do not fill temporary tables */
679
session->lex->sql_command= SQLCOM_SHOW_FIELDS;
680
mysqld_list_fields(session,&table_list,fields);
681
session->lex->unit.cleanup();
682
session->cleanup_after_query();
232
686
/* We don't calculate statistics for this command */
687
net->error=0; // Don't give 'abort' message
233
688
session->main_da.disable_status(); // Don't send anything back
234
689
error=true; // End server
691
case COM_BINLOG_DUMP:
695
uint32_t slave_server_id;
697
status_var_increment(session->status_var.com_other);
698
/* TODO: The following has to be changed to an 8 byte integer */
699
pos = uint4korr(packet);
700
flags = uint2korr(packet + 4);
701
session->server_id=0; /* avoid suicide */
702
if ((slave_server_id= uint4korr(packet+6))) // mysqlbinlog.server_id==0
703
kill_zombie_dump_threads(slave_server_id);
704
session->server_id = slave_server_id;
706
mysql_binlog_send(session, session->strdup(packet + 10), (my_off_t) pos, flags);
707
/* fake COM_QUIT -- if we get here, the thread needs to terminate */
236
711
case COM_SHUTDOWN:
238
session->status_var.com_other++;
240
session->close_thread_tables(); // Free before kill
713
status_var_increment(session->status_var.com_other);
715
close_thread_tables(session); // Free before kill
246
session->status_var.com_other++;
247
session->my_ok(); // Tell client we are alive
721
status_var_increment(session->status_var.com_other);
722
my_ok(session); // Tell client we are alive
724
case COM_PROCESS_INFO:
725
status_var_increment(session->status_var.com_stat[SQLCOM_SHOW_PROCESSLIST]);
726
mysqld_list_processes(session, NULL, 0);
728
case COM_PROCESS_KILL:
730
status_var_increment(session->status_var.com_stat[SQLCOM_KILL]);
731
ulong id=(ulong) uint4korr(packet);
732
sql_kill(session,id,false);
737
status_var_increment(session->status_var.com_stat[SQLCOM_SET_OPTION]);
738
uint32_t opt_command= uint2korr(packet);
740
switch (opt_command) {
741
case (int) DRIZZLE_OPTION_MULTI_STATEMENTS_ON:
742
session->client_capabilities|= CLIENT_MULTI_STATEMENTS;
745
case (int) DRIZZLE_OPTION_MULTI_STATEMENTS_OFF:
746
session->client_capabilities&= ~CLIENT_MULTI_STATEMENTS;
750
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
250
756
case COM_CONNECT: // Impossible here
757
case COM_TIME: // Impossible from client
253
760
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
468
1029
variables, but for now this is probably good enough.
469
1030
Don't reset warnings when executing a stored routine.
471
if (all_tables || ! lex->is_single_level_stmt())
1032
if (all_tables || !lex->is_single_level_stmt())
473
1033
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();
1035
if (unlikely(session->slave_thread))
1038
Check if statment should be skipped because of slave filtering
1042
- UPDATE MULTI: For this statement, we want to check the filtering
1043
rules later in the code
1044
- SET: we always execute it (Not that many SET commands exists in
1045
the binary log anyway -- only 4.1 masters write SET statements,
1046
in 5.0 there are no SET statements in the binary log)
1047
- DROP TEMPORARY TABLE IF EXISTS: we always execute it (otherwise we
1048
have stale files on slave caused by exclusion of one tmp table).
1050
if (!(lex->sql_command == SQLCOM_UPDATE_MULTI) &&
1051
!(lex->sql_command == SQLCOM_SET_OPTION) &&
1052
!(lex->sql_command == SQLCOM_DROP_TABLE &&
1053
lex->drop_temporary && lex->drop_if_exists) &&
1054
all_tables_not_ok(session, all_tables))
1056
/* we warn the slave SQL thread */
1057
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
1062
status_var_increment(session->status_var.com_stat[lex->sql_command]);
1064
assert(session->transaction.stmt.modified_non_trans_table == false);
1066
switch (lex->sql_command) {
1067
case SQLCOM_SHOW_STATUS:
1069
system_status_var old_status_var= session->status_var;
1070
session->initial_status_var= &old_status_var;
1071
res= execute_sqlcom_select(session, all_tables);
1072
/* Don't log SHOW STATUS commands to slow query log */
1073
session->server_status&= ~(SERVER_QUERY_NO_INDEX_USED |
1074
SERVER_QUERY_NO_GOOD_INDEX_USED);
1076
restore status variables, as we don't want 'show status' to cause
1079
pthread_mutex_lock(&LOCK_status);
1080
add_diff_to_status(&global_status_var, &session->status_var,
1082
session->status_var= old_status_var;
1083
pthread_mutex_unlock(&LOCK_status);
1086
case SQLCOM_SHOW_DATABASES:
1087
case SQLCOM_SHOW_TABLES:
1088
case SQLCOM_SHOW_TABLE_STATUS:
1089
case SQLCOM_SHOW_OPEN_TABLES:
1090
case SQLCOM_SHOW_FIELDS:
1091
case SQLCOM_SHOW_KEYS:
1092
case SQLCOM_SHOW_VARIABLES:
1095
session->status_var.last_query_cost= 0.0;
1096
res= execute_sqlcom_select(session, all_tables);
1099
case SQLCOM_EMPTY_QUERY:
1105
res = purge_master_logs(session, lex->to_log);
1108
case SQLCOM_PURGE_BEFORE:
1112
/* PURGE MASTER LOGS BEFORE 'data' */
1113
it= (Item *)lex->value_list.head();
1114
if ((!it->fixed && it->fix_fields(lex->session, &it)) ||
1117
my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE LOGS BEFORE");
1120
it= new Item_func_unix_timestamp(it);
1122
it is OK only emulate fix_fieds, because we need only
1125
it->quick_fix_field();
1126
res = purge_master_logs_before_date(session, (ulong)it->val_int());
1129
case SQLCOM_SHOW_WARNS:
1131
res= mysqld_show_warnings(session, (uint32_t)
1132
((1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_NOTE) |
1133
(1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_WARN) |
1134
(1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR)
1138
case SQLCOM_SHOW_ERRORS:
1140
res= mysqld_show_warnings(session, (uint32_t)
1141
(1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR));
1144
case SQLCOM_ASSIGN_TO_KEYCACHE:
1146
assert(first_table == all_tables && first_table != 0);
1147
res= mysql_assign_to_keycache(session, first_table, &lex->ident);
1150
case SQLCOM_CHANGE_MASTER:
1152
pthread_mutex_lock(&LOCK_active_mi);
1153
res = change_master(session,active_mi);
1154
pthread_mutex_unlock(&LOCK_active_mi);
1157
case SQLCOM_SHOW_SLAVE_STAT:
1159
pthread_mutex_lock(&LOCK_active_mi);
1160
if (active_mi != NULL)
1162
res = show_master_info(session, active_mi);
1166
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1167
"the master info structure does not exist");
1170
pthread_mutex_unlock(&LOCK_active_mi);
1173
case SQLCOM_SHOW_MASTER_STAT:
1175
res = show_binlog_info(session);
1179
case SQLCOM_SHOW_ENGINE_STATUS:
1181
res = ha_show_status(session, lex->create_info.db_type, HA_ENGINE_STATUS);
1184
case SQLCOM_CREATE_TABLE:
1186
/* If CREATE TABLE of non-temporary table, do implicit commit */
1187
if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE))
1189
if (end_active_trans(session))
1195
assert(first_table == all_tables && first_table != 0);
1197
// Skip first table, which is the table we are creating
1198
TableList *create_table= lex->unlink_first_table(&link_to_local);
1199
TableList *select_tables= lex->query_tables;
1201
Code below (especially in mysql_create_table() and select_create
1202
methods) may modify HA_CREATE_INFO structure in LEX, so we have to
1203
use a copy of this structure to make execution prepared statement-
1204
safe. A shallow copy is enough as this code won't modify any memory
1205
referenced from this structure.
1207
HA_CREATE_INFO create_info(lex->create_info);
1209
We need to copy alter_info for the same reasons of re-execution
1210
safety, only in case of Alter_info we have to do (almost) a deep
1213
Alter_info alter_info(lex->alter_info, session->mem_root);
1215
if (session->is_fatal_error)
1217
/* If out of memory when creating a copy of alter_info. */
1219
goto end_with_restore_list;
1222
if ((res= create_table_precheck(session, select_tables, create_table)))
1223
goto end_with_restore_list;
1225
/* Might have been updated in create_table_precheck */
1226
create_info.alias= create_table->alias;
1228
#ifdef HAVE_READLINK
1229
/* Fix names if symlinked tables */
1230
if (append_file_to_dir(session, &create_info.data_file_name,
1231
create_table->table_name) ||
1232
append_file_to_dir(session, &create_info.index_file_name,
1233
create_table->table_name))
1234
goto end_with_restore_list;
1237
If we are using SET CHARSET without DEFAULT, add an implicit
1238
DEFAULT to not confuse old users. (This may change).
1240
if ((create_info.used_fields &
1241
(HA_CREATE_USED_DEFAULT_CHARSET | HA_CREATE_USED_CHARSET)) ==
1242
HA_CREATE_USED_CHARSET)
1244
create_info.used_fields&= ~HA_CREATE_USED_CHARSET;
1245
create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
1246
create_info.default_table_charset= create_info.table_charset;
1247
create_info.table_charset= 0;
1250
The create-select command will open and read-lock the select table
1251
and then create, open and write-lock the new table. If a global
1252
read lock steps in, we get a deadlock. The write lock waits for
1253
the global read lock, while the global read lock waits for the
1254
select table to be closed. So we wait until the global readlock is
1255
gone before starting both steps. Note that
1256
wait_if_global_read_lock() sets a protection against a new global
1257
read lock when it succeeds. This needs to be released by
1258
start_waiting_global_read_lock(). We protect the normal CREATE
1259
TABLE in the same way. That way we avoid that a new table is
1260
created during a gobal read lock.
1262
if (!session->locked_tables &&
1263
!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
1266
goto end_with_restore_list;
1268
if (select_lex->item_list.elements) // With select
1270
select_result *result;
1272
select_lex->options|= SELECT_NO_UNLOCK;
1273
unit->set_limit(select_lex);
1275
if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
1277
lex->link_first_table_back(create_table, link_to_local);
1278
create_table->create= true;
1281
if (!(res= open_and_lock_tables(session, lex->query_tables)))
1284
Is table which we are changing used somewhere in other parts
1287
if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
1289
TableList *duplicate;
1290
create_table= lex->unlink_first_table(&link_to_local);
1291
if ((duplicate= unique_table(session, create_table, select_tables, 0)))
1293
update_non_unique_table_error(create_table, "CREATE", duplicate);
1295
goto end_with_restore_list;
1300
select_create is currently not re-execution friendly and
1301
needs to be created for every execution of a PS/SP.
1303
if ((result= new select_create(create_table,
1306
select_lex->item_list,
1312
CREATE from SELECT give its SELECT_LEX for SELECT,
1313
and item_list belong to SELECT
1315
res= handle_select(session, lex, result, 0);
1319
else if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
1320
create_table= lex->unlink_first_table(&link_to_local);
1325
/* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
1326
if (create_info.options & HA_LEX_CREATE_TMP_TABLE)
1327
session->options|= OPTION_KEEP_LOG;
1328
/* regular create */
1329
if (create_info.options & HA_LEX_CREATE_TABLE_LIKE)
1330
res= mysql_create_like_table(session, create_table, select_tables,
1334
res= mysql_create_table(session, create_table->db,
1335
create_table->table_name, &create_info,
1342
/* put tables back for PS rexecuting */
1343
end_with_restore_list:
1344
lex->link_first_table_back(create_table, link_to_local);
1347
case SQLCOM_CREATE_INDEX:
1349
case SQLCOM_DROP_INDEX:
1351
CREATE INDEX and DROP INDEX are implemented by calling ALTER
1352
TABLE with proper arguments.
1354
In the future ALTER TABLE will notice that the request is to
1355
only add indexes and create these one by one for the existing
1356
table without having to do a full rebuild.
1359
/* Prepare stack copies to be re-execution safe */
1360
HA_CREATE_INFO create_info;
1361
Alter_info alter_info(lex->alter_info, session->mem_root);
1363
if (session->is_fatal_error) /* out of memory creating a copy of alter_info */
1366
assert(first_table == all_tables && first_table != 0);
1367
if (end_active_trans(session))
1370
memset(&create_info, 0, sizeof(create_info));
1371
create_info.db_type= 0;
1372
create_info.row_type= ROW_TYPE_NOT_USED;
1373
create_info.default_table_charset= session->variables.collation_database;
1375
res= mysql_alter_table(session, first_table->db, first_table->table_name,
1376
&create_info, first_table, &alter_info,
1377
0, (order_st*) 0, 0);
1380
case SQLCOM_SLAVE_START:
1382
pthread_mutex_lock(&LOCK_active_mi);
1383
start_slave(session,active_mi,1 /* net report*/);
1384
pthread_mutex_unlock(&LOCK_active_mi);
1387
case SQLCOM_SLAVE_STOP:
1389
If the client thread has locked tables, a deadlock is possible.
1391
- the client thread does LOCK TABLE t READ.
1392
- then the master updates t.
1393
- then the SQL slave thread wants to update t,
1394
so it waits for the client thread because t is locked by it.
1395
- then the client thread does SLAVE STOP.
1396
SLAVE STOP waits for the SQL slave thread to terminate its
1397
update t, which waits for the client thread because t is locked by it.
1398
To prevent that, refuse SLAVE STOP if the
1399
client thread has locked tables
1401
if (session->locked_tables || session->active_transaction() || session->global_read_lock)
1403
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
1404
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
1408
pthread_mutex_lock(&LOCK_active_mi);
1409
stop_slave(session,active_mi,1/* net report*/);
1410
pthread_mutex_unlock(&LOCK_active_mi);
1414
case SQLCOM_ALTER_TABLE:
1415
assert(first_table == all_tables && first_table != 0);
1418
Code in mysql_alter_table() may modify its HA_CREATE_INFO argument,
1419
so we have to use a copy of this structure to make execution
1420
prepared statement- safe. A shallow copy is enough as no memory
1421
referenced from this structure will be modified.
1423
HA_CREATE_INFO create_info(lex->create_info);
1424
Alter_info alter_info(lex->alter_info, session->mem_root);
1426
if (session->is_fatal_error) /* out of memory creating a copy of alter_info */
1431
/* Must be set in the parser */
1432
assert(select_lex->db);
1434
{ // Rename of table
1435
TableList tmp_table;
1436
memset(&tmp_table, 0, sizeof(tmp_table));
1437
tmp_table.table_name= lex->name.str;
1438
tmp_table.db=select_lex->db;
1441
/* Don't yet allow changing of symlinks with ALTER TABLE */
1442
if (create_info.data_file_name)
1443
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1444
"DATA DIRECTORY option ignored");
1445
if (create_info.index_file_name)
1446
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1447
"INDEX DIRECTORY option ignored");
1448
create_info.data_file_name= create_info.index_file_name= NULL;
1449
/* ALTER TABLE ends previous transaction */
1450
if (end_active_trans(session))
1453
if (!session->locked_tables &&
1454
!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
1460
res= mysql_alter_table(session, select_lex->db, lex->name.str,
1464
select_lex->order_list.elements,
1465
(order_st *) select_lex->order_list.first,
1469
case SQLCOM_RENAME_TABLE:
1471
assert(first_table == all_tables && first_table != 0);
1473
for (table= first_table; table; table= table->next_local->next_local)
1475
TableList old_list, new_list;
1477
we do not need initialize old_list and new_list because we will
1478
come table[0] and table->next[0] there
1481
new_list= table->next_local[0];
1484
if (end_active_trans(session) || drizzle_rename_tables(session, first_table, 0))
1490
case SQLCOM_SHOW_BINLOGS:
1492
res = show_binlogs(session);
1495
case SQLCOM_SHOW_CREATE:
1496
assert(first_table == all_tables && first_table != 0);
1498
res= mysqld_show_create(session, first_table);
1501
case SQLCOM_CHECKSUM:
1503
assert(first_table == all_tables && first_table != 0);
1504
res = mysql_checksum_table(session, first_table, &lex->check_opt);
1509
assert(first_table == all_tables && first_table != 0);
1510
res= mysql_repair_table(session, first_table, &lex->check_opt);
1511
/* ! we write after unlocking the table */
1513
Presumably, REPAIR and binlog writing doesn't require synchronization
1515
write_bin_log(session, true, session->query, session->query_length);
1516
select_lex->table_list.first= (unsigned char*) first_table;
1517
lex->query_tables=all_tables;
1522
assert(first_table == all_tables && first_table != 0);
1523
res = mysql_check_table(session, first_table, &lex->check_opt);
1524
select_lex->table_list.first= (unsigned char*) first_table;
1525
lex->query_tables=all_tables;
1528
case SQLCOM_ANALYZE:
1530
assert(first_table == all_tables && first_table != 0);
1531
res= mysql_analyze_table(session, first_table, &lex->check_opt);
1532
/* ! we write after unlocking the table */
1533
write_bin_log(session, true, session->query, session->query_length);
1534
select_lex->table_list.first= (unsigned char*) first_table;
1535
lex->query_tables=all_tables;
1539
case SQLCOM_OPTIMIZE:
1541
assert(first_table == all_tables && first_table != 0);
1542
res= mysql_optimize_table(session, first_table, &lex->check_opt);
1543
/* ! we write after unlocking the table */
1544
write_bin_log(session, true, session->query, session->query_length);
1545
select_lex->table_list.first= (unsigned char*) first_table;
1546
lex->query_tables=all_tables;
1550
assert(first_table == all_tables && first_table != 0);
1551
if (update_precheck(session, all_tables))
1553
assert(select_lex->offset_limit == 0);
1554
unit->set_limit(select_lex);
1555
res= (up_result= mysql_update(session, all_tables,
1556
select_lex->item_list,
1559
select_lex->order_list.elements,
1560
(order_st *) select_lex->order_list.first,
1561
unit->select_limit_cnt,
1562
lex->duplicates, lex->ignore));
1563
/* mysql_update return 2 if we need to switch to multi-update */
1567
case SQLCOM_UPDATE_MULTI:
1569
assert(first_table == all_tables && first_table != 0);
1570
/* if we switched from normal update, rights are checked */
1573
if ((res= multi_update_precheck(session, all_tables)))
1579
res= mysql_multi_update_prepare(session);
1581
/* Check slave filtering rules */
1582
if (unlikely(session->slave_thread))
1584
if (all_tables_not_ok(session, all_tables))
1588
res= 0; /* don't care of prev failure */
1589
session->clear_error(); /* filters are of highest prior */
1591
/* we warn the slave SQL thread */
1592
my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
1605
res= mysql_multi_update(session, all_tables,
1606
&select_lex->item_list,
1609
select_lex->options,
1610
lex->duplicates, lex->ignore, unit, select_lex);
1613
case SQLCOM_REPLACE:
1616
assert(first_table == all_tables && first_table != 0);
1617
if ((res= insert_precheck(session, all_tables)))
1620
if (!session->locked_tables &&
1621
!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
1627
res= mysql_insert(session, all_tables, lex->field_list, lex->many_values,
1628
lex->update_list, lex->value_list,
1629
lex->duplicates, lex->ignore);
1633
case SQLCOM_REPLACE_SELECT:
1634
case SQLCOM_INSERT_SELECT:
1636
select_result *sel_result;
1637
assert(first_table == all_tables && first_table != 0);
1638
if ((res= insert_precheck(session, all_tables)))
1641
/* Fix lock for first table */
1642
if (first_table->lock_type == TL_WRITE_DELAYED)
1643
first_table->lock_type= TL_WRITE;
1645
/* Don't unlock tables until command is written to binary log */
1646
select_lex->options|= SELECT_NO_UNLOCK;
1648
unit->set_limit(select_lex);
1650
if (! session->locked_tables &&
1651
! (need_start_waiting= ! wait_if_global_read_lock(session, 0, 1)))
1657
if (!(res= open_and_lock_tables(session, all_tables)))
1659
/* Skip first table, which is the table we are inserting in */
1660
TableList *second_table= first_table->next_local;
1661
select_lex->table_list.first= (unsigned char*) second_table;
1662
select_lex->context.table_list=
1663
select_lex->context.first_name_resolution_table= second_table;
1664
res= mysql_insert_select_prepare(session);
1665
if (!res && (sel_result= new select_insert(first_table,
1673
res= handle_select(session, lex, sel_result, OPTION_SETUP_TABLES_DONE);
1675
Invalidate the table in the query cache if something changed
1676
after unlocking when changes become visible.
1677
TODO: this is workaround. right way will be move invalidating in
1678
the unlock procedure.
1680
if (first_table->lock_type == TL_WRITE_CONCURRENT_INSERT &&
1683
/* INSERT ... SELECT should invalidate only the very first table */
1684
TableList *save_table= first_table->next_local;
1685
first_table->next_local= 0;
1686
first_table->next_local= save_table;
1690
/* revert changes for SP */
1691
select_lex->table_list.first= (unsigned char*) first_table;
1696
case SQLCOM_TRUNCATE:
1697
if (end_active_trans(session))
1702
assert(first_table == all_tables && first_table != 0);
1704
Don't allow this within a transaction because we want to use
1707
if (session->locked_tables || session->active_transaction())
1709
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
1710
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
1714
res= mysql_truncate(session, first_table, 0);
1719
assert(first_table == all_tables && first_table != 0);
1720
assert(select_lex->offset_limit == 0);
1721
unit->set_limit(select_lex);
1723
if (!session->locked_tables &&
1724
!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
1730
res = mysql_delete(session, all_tables, select_lex->where,
1731
&select_lex->order_list,
1732
unit->select_limit_cnt, select_lex->options,
1736
case SQLCOM_DELETE_MULTI:
1738
assert(first_table == all_tables && first_table != 0);
1739
TableList *aux_tables=
1740
(TableList *)session->lex->auxiliary_table_list.first;
1741
multi_delete *del_result;
1743
if (!session->locked_tables &&
1744
!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
1750
if ((res= multi_delete_precheck(session, all_tables)))
1753
/* condition will be true on SP re-excuting */
1754
if (select_lex->item_list.elements != 0)
1755
select_lex->item_list.empty();
1756
if (add_item_to_list(session, new Item_null()))
1759
session->set_proc_info("init");
1760
if ((res= open_and_lock_tables(session, all_tables)))
1763
if ((res= mysql_multi_delete_prepare(session)))
1766
if (!session->is_fatal_error &&
1767
(del_result= new multi_delete(aux_tables, lex->table_count)))
1769
res= mysql_select(session, &select_lex->ref_pointer_array,
1770
select_lex->get_table_list(),
1771
select_lex->with_wild,
1772
select_lex->item_list,
1774
0, (order_st *)NULL, (order_st *)NULL, (Item *)NULL,
1776
select_lex->options | session->options |
1777
SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
1778
OPTION_SETUP_TABLES_DONE,
1779
del_result, unit, select_lex);
1780
res|= session->is_error();
1782
del_result->abort();
1789
case SQLCOM_DROP_TABLE:
1791
assert(first_table == all_tables && first_table != 0);
1792
if (!lex->drop_temporary)
1794
if (end_active_trans(session))
1800
If this is a slave thread, we may sometimes execute some
1801
DROP / * 40005 TEMPORARY * / TABLE
1802
that come from parts of binlogs (likely if we use RESET SLAVE or CHANGE
1803
MASTER TO), while the temporary table has already been dropped.
1804
To not generate such irrelevant "table does not exist errors",
1805
we silently add IF EXISTS if TEMPORARY was used.
1807
if (session->slave_thread)
1808
lex->drop_if_exists= 1;
1810
/* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
1811
session->options|= OPTION_KEEP_LOG;
1813
/* DDL and binlog write order protected by LOCK_open */
1814
res= mysql_rm_table(session, first_table, lex->drop_if_exists, lex->drop_temporary);
1817
case SQLCOM_SHOW_PROCESSLIST:
1818
mysqld_list_processes(session, NULL, lex->verbose);
1820
case SQLCOM_SHOW_ENGINE_LOGS:
1822
res= ha_show_status(session, lex->create_info.db_type, HA_ENGINE_LOGS);
1825
case SQLCOM_CHANGE_DB:
1827
LEX_STRING db_str= { (char *) select_lex->db, strlen(select_lex->db) };
1829
if (!mysql_change_db(session, &db_str, false))
1837
assert(first_table == all_tables && first_table != 0);
1838
if (lex->local_file)
1840
if (!(session->client_capabilities & CLIENT_LOCAL_FILES) ||
1843
my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), MYF(0));
1848
res= mysql_load(session, lex->exchange, first_table, lex->field_list,
1849
lex->update_list, lex->value_list, lex->duplicates,
1850
lex->ignore, (bool) lex->local_file);
1854
case SQLCOM_SET_OPTION:
1856
List<set_var_base> *lex_var_list= &lex->var_list;
1858
if (lex->autocommit && end_active_trans(session))
1861
if (open_and_lock_tables(session, all_tables))
1863
if (!(res= sql_set_variables(session, lex_var_list)))
1870
We encountered some sort of error, but no message was sent.
1871
Send something semi-generic here since we don't know which
1872
assignment in the list caused the error.
1874
if (!session->is_error())
1875
my_error(ER_WRONG_ARGUMENTS,MYF(0),"SET");
1882
case SQLCOM_UNLOCK_TABLES:
1884
It is critical for mysqldump --single-transaction --master-data that
1885
UNLOCK TABLES does not implicitely commit a connection which has only
1886
done FLUSH TABLES WITH READ LOCK + BEGIN. If this assumption becomes
1887
false, mysqldump will not work.
1889
unlock_locked_tables(session);
1890
if (session->options & OPTION_TABLE_LOCK)
1892
end_active_trans(session);
1893
session->options&= ~(OPTION_TABLE_LOCK);
1895
if (session->global_read_lock)
1896
unlock_global_read_lock(session);
1899
case SQLCOM_LOCK_TABLES:
1901
We try to take transactional locks if
1902
- only transactional locks are requested (lex->lock_transactional) and
1903
- no non-transactional locks exist (!session->locked_tables).
1905
if (lex->lock_transactional && !session->locked_tables)
1909
All requested locks are transactional and no non-transactional
1912
if ((rc= try_transactional_lock(session, all_tables)) == -1)
1920
Non-transactional locking has been requested or
1921
non-transactional locks exist already or transactional locks are
1922
not supported by all storage engines. Take non-transactional
1927
One or more requested locks are non-transactional and/or
1928
non-transactional locks exist or a storage engine does not support
1929
transactional locks. Check if at least one transactional lock is
1930
requested. If yes, warn about the conversion to non-transactional
1931
locks or abort in strict mode.
1933
if (check_transactional_lock(session, all_tables))
1935
unlock_locked_tables(session);
1936
/* we must end the trasaction first, regardless of anything */
1937
if (end_active_trans(session))
1939
session->in_lock_tables=1;
1940
session->options|= OPTION_TABLE_LOCK;
1942
if (!(res= simple_open_n_lock_tables(session, all_tables)))
1944
session->locked_tables=session->lock;
1946
(void) set_handler_table_locks(session, all_tables, false);
1952
Need to end the current transaction, so the storage engine (InnoDB)
1953
can free its locks if LOCK TABLES locked some tables before finding
1954
that it can't lock a table in its list
1956
ha_autocommit_or_rollback(session, 1);
1957
end_active_trans(session);
1958
session->options&= ~(OPTION_TABLE_LOCK);
1960
session->in_lock_tables=0;
1962
case SQLCOM_CREATE_DB:
1965
As mysql_create_db() may modify HA_CREATE_INFO structure passed to
1966
it, we need to use a copy of LEX::create_info to make execution
1967
prepared statement- safe.
1969
HA_CREATE_INFO create_info(lex->create_info);
1970
if (end_active_trans(session))
1976
if (!(alias=session->strmake(lex->name.str, lex->name.length)) ||
1977
check_db_name(&lex->name))
1979
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
1982
res= mysql_create_db(session,(lower_case_table_names == 2 ? alias :
1983
lex->name.str), &create_info, 0);
1986
case SQLCOM_DROP_DB:
1988
if (end_active_trans(session))
1993
if (check_db_name(&lex->name))
1995
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
1998
if (session->locked_tables || session->active_transaction())
2000
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
2001
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
2004
res= mysql_rm_db(session, lex->name.str, lex->drop_if_exists, 0);
2007
case SQLCOM_ALTER_DB:
2009
LEX_STRING *db= &lex->name;
2010
HA_CREATE_INFO create_info(lex->create_info);
2011
if (check_db_name(db))
2013
my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
2016
if (session->locked_tables || session->active_transaction())
2018
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
2019
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
2022
res= mysql_alter_db(session, db->str, &create_info);
2025
case SQLCOM_SHOW_CREATE_DB:
2027
if (check_db_name(&lex->name))
2029
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
2032
res= mysqld_show_create_db(session, lex->name.str, &lex->create_info);
2038
bool write_to_binlog;
2041
reload_cache() will tell us if we are allowed to write to the
2044
if (!reload_cache(session, lex->type, first_table, &write_to_binlog))
2047
We WANT to write and we CAN write.
2048
! we write after unlocking the table.
2051
Presumably, RESET and binlog writing doesn't require synchronization
2053
write_bin_log(session, false, session->query, session->query_length);
2061
Item *it= (Item *)lex->value_list.head();
2063
if ((!it->fixed && it->fix_fields(lex->session, &it)) || it->check_cols(1))
2065
my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
2069
sql_kill(session, (ulong)it->val_int(), lex->type & ONLY_KILL_QUERY);
2073
if (session->transaction.xid_state.xa_state != XA_NOTR)
2075
my_error(ER_XAER_RMFAIL, MYF(0),
2076
xa_state_names[session->transaction.xid_state.xa_state]);
2080
Breakpoints for backup testing.
2082
if (begin_trans(session))
2087
if (end_trans(session, lex->tx_release ? COMMIT_RELEASE :
2088
lex->tx_chain ? COMMIT_AND_CHAIN : COMMIT))
2092
case SQLCOM_ROLLBACK:
2093
if (end_trans(session, lex->tx_release ? ROLLBACK_RELEASE :
2094
lex->tx_chain ? ROLLBACK_AND_CHAIN : ROLLBACK))
2098
case SQLCOM_RELEASE_SAVEPOINT:
2101
for (sv=session->transaction.savepoints; sv; sv=sv->prev)
2103
if (my_strnncoll(system_charset_info,
2104
(unsigned char *)lex->ident.str, lex->ident.length,
2105
(unsigned char *)sv->name, sv->length) == 0)
2110
if (ha_release_savepoint(session, sv))
2111
res= true; // cannot happen
2114
session->transaction.savepoints=sv->prev;
2117
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
2120
case SQLCOM_ROLLBACK_TO_SAVEPOINT:
2123
for (sv=session->transaction.savepoints; sv; sv=sv->prev)
2125
if (my_strnncoll(system_charset_info,
2126
(unsigned char *)lex->ident.str, lex->ident.length,
2127
(unsigned char *)sv->name, sv->length) == 0)
2132
if (ha_rollback_to_savepoint(session, sv))
2133
res= true; // cannot happen
2136
if (((session->options & OPTION_KEEP_LOG) ||
2137
session->transaction.all.modified_non_trans_table) &&
2138
!session->slave_thread)
2139
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2140
ER_WARNING_NOT_COMPLETE_ROLLBACK,
2141
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
2144
session->transaction.savepoints=sv;
2147
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
2150
case SQLCOM_SAVEPOINT:
2151
if (!(session->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) || !opt_using_transactions)
2155
SAVEPOINT **sv, *newsv;
2156
for (sv=&session->transaction.savepoints; *sv; sv=&(*sv)->prev)
2158
if (my_strnncoll(system_charset_info,
2159
(unsigned char *)lex->ident.str, lex->ident.length,
2160
(unsigned char *)(*sv)->name, (*sv)->length) == 0)
2163
if (*sv) /* old savepoint of the same name exists */
2166
ha_release_savepoint(session, *sv); // it cannot fail
2169
else if ((newsv=(SAVEPOINT *) alloc_root(&session->transaction.mem_root,
2170
savepoint_alloc_size)) == 0)
2172
my_error(ER_OUT_OF_RESOURCES, MYF(0));
2175
newsv->name=strmake_root(&session->transaction.mem_root,
2176
lex->ident.str, lex->ident.length);
2177
newsv->length=lex->ident.length;
2179
if we'll get an error here, don't add new savepoint to the list.
2180
we'll lose a little bit of memory in transaction mem_root, but it'll
2181
be free'd when transaction ends anyway
2183
if (ha_savepoint(session, newsv))
2187
newsv->prev=session->transaction.savepoints;
2188
session->transaction.savepoints=newsv;
2193
case SQLCOM_BINLOG_BASE64_EVENT:
2195
mysql_client_binlog_statement(session);
2199
assert(0); /* Impossible */
480
2203
session->set_proc_info("query end");
482
2206
The return value for ROW_COUNT() is "implementation dependent" if the
483
2207
statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC
484
2208
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)))
2211
if (!(sql_command_flags[lex->sql_command].test(CF_BIT_HAS_ROW_COUNT)))
489
2212
session->row_count_func= -1;
2220
if (need_start_waiting)
2223
Release the protection against the global read lock and wake
2224
everyone, who might want to set a global read lock.
2226
start_waiting_global_read_lock(session);
492
return (res || session->is_error());
2228
return(res || session->is_error());
494
2231
bool execute_sqlcom_select(Session *session, TableList *all_tables)
496
2233
LEX *lex= session->lex;
497
2234
select_result *result=lex->result;
499
2236
/* assign global limit variable if limit is not given */
501
Select_Lex *param= lex->unit.global_parameters;
2238
SELECT_LEX *param= lex->unit.global_parameters;
502
2239
if (!param->explicit_limit)
503
2240
param->select_limit=
504
2241
new Item_int((uint64_t) session->variables.select_limit);
506
if (not (res= session->openTablesLock(all_tables)))
2243
if (!(res= open_and_lock_tables(session, all_tables)))
508
2245
if (lex->describe)