138
189
sql_command_flags[SQLCOM_DROP_INDEX]= CF_CHANGES_DATA;
140
191
sql_command_flags[SQLCOM_UPDATE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
192
sql_command_flags[SQLCOM_UPDATE_MULTI]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
141
193
sql_command_flags[SQLCOM_INSERT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
142
194
sql_command_flags[SQLCOM_INSERT_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
143
195
sql_command_flags[SQLCOM_DELETE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
196
sql_command_flags[SQLCOM_DELETE_MULTI]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
144
197
sql_command_flags[SQLCOM_REPLACE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
145
198
sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
200
sql_command_flags[SQLCOM_SHOW_STATUS]= CF_STATUS_COMMAND;
201
sql_command_flags[SQLCOM_SHOW_DATABASES]= CF_STATUS_COMMAND;
202
sql_command_flags[SQLCOM_SHOW_OPEN_TABLES]= CF_STATUS_COMMAND;
203
sql_command_flags[SQLCOM_SHOW_FIELDS]= CF_STATUS_COMMAND;
204
sql_command_flags[SQLCOM_SHOW_KEYS]= CF_STATUS_COMMAND;
205
sql_command_flags[SQLCOM_SHOW_VARIABLES]= CF_STATUS_COMMAND;
206
sql_command_flags[SQLCOM_SHOW_BINLOGS]= CF_STATUS_COMMAND;
147
207
sql_command_flags[SQLCOM_SHOW_WARNS]= CF_STATUS_COMMAND;
148
208
sql_command_flags[SQLCOM_SHOW_ERRORS]= CF_STATUS_COMMAND;
209
sql_command_flags[SQLCOM_SHOW_ENGINE_STATUS]= CF_STATUS_COMMAND;
210
sql_command_flags[SQLCOM_SHOW_PROCESSLIST]= CF_STATUS_COMMAND;
149
211
sql_command_flags[SQLCOM_SHOW_CREATE_DB]= CF_STATUS_COMMAND;
150
212
sql_command_flags[SQLCOM_SHOW_CREATE]= CF_STATUS_COMMAND;
213
sql_command_flags[SQLCOM_SHOW_MASTER_STAT]= CF_STATUS_COMMAND;
214
sql_command_flags[SQLCOM_SHOW_SLAVE_STAT]= CF_STATUS_COMMAND;
216
sql_command_flags[SQLCOM_SHOW_TABLES]= (CF_STATUS_COMMAND |
217
CF_SHOW_TABLE_COMMAND);
218
sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]= (CF_STATUS_COMMAND |
219
CF_SHOW_TABLE_COMMAND);
153
221
The following admin table operations are allowed
224
sql_command_flags[SQLCOM_REPAIR]= CF_WRITE_LOGS_COMMAND;
225
sql_command_flags[SQLCOM_OPTIMIZE]= CF_WRITE_LOGS_COMMAND;
156
226
sql_command_flags[SQLCOM_ANALYZE]= CF_WRITE_LOGS_COMMAND;
230
bool is_update_query(enum enum_sql_command command)
232
assert(command >= 0 && command <= SQLCOM_END);
233
return (sql_command_flags[command].test(CF_BIT_CHANGES_DATA));
236
void execute_init_command(Session *session, sys_var_str *init_command_var,
237
rw_lock_t *var_mutex)
240
ulong save_client_capabilities;
242
session->set_proc_info("Execution of init_command");
244
We need to lock init_command_var because
245
during execution of init_command_var query
246
values of init_command_var can't be changed
248
rw_rdlock(var_mutex);
249
save_client_capabilities= session->client_capabilities;
250
session->client_capabilities|= CLIENT_MULTI_STATEMENTS;
252
We don't need return result of execution to client side.
253
To forbid this we should set session->net.vio to 0.
255
save_vio= session->net.vio;
257
dispatch_command(COM_QUERY, session,
258
init_command_var->value,
259
init_command_var->value_length);
260
rw_unlock(var_mutex);
261
session->client_capabilities= save_client_capabilities;
262
session->net.vio= save_vio;
266
Ends the current transaction and (maybe) begin the next.
268
@param session Current thread
269
@param completion Completion type
275
int end_trans(Session *session, enum enum_mysql_completiontype completion)
280
if (session->transaction.xid_state.xa_state != XA_NOTR)
282
my_error(ER_XAER_RMFAIL, MYF(0),
283
xa_state_names[session->transaction.xid_state.xa_state]);
286
switch (completion) {
289
We don't use end_active_trans() here to ensure that this works
290
even if there is a problem with the OPTION_AUTO_COMMIT flag
291
(Which of course should never happen...)
293
session->server_status&= ~SERVER_STATUS_IN_TRANS;
294
res= ha_commit(session);
295
session->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
296
session->transaction.all.modified_non_trans_table= false;
299
do_release= 1; /* fall through */
300
case COMMIT_AND_CHAIN:
301
res= end_active_trans(session);
302
if (!res && completion == COMMIT_AND_CHAIN)
303
res= begin_trans(session);
305
case ROLLBACK_RELEASE:
306
do_release= 1; /* fall through */
308
case ROLLBACK_AND_CHAIN:
310
session->server_status&= ~SERVER_STATUS_IN_TRANS;
311
if (ha_rollback(session))
313
session->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
314
session->transaction.all.modified_non_trans_table= false;
315
if (!res && (completion == ROLLBACK_AND_CHAIN))
316
res= begin_trans(session);
321
my_error(ER_UNKNOWN_COM_ERROR, MYF(0));
326
my_error(session->killed_errno(), MYF(0));
327
else if ((res == 0) && do_release)
328
session->killed= Session::KILL_CONNECTION;
335
Read one command from connection and execute it (query or simple command).
336
This function is called in loop from thread function.
338
For profiling to work, it must never be called recursively.
343
1 request of thread shutdown (see dispatch_command() description)
346
bool do_command(Session *session)
351
NET *net= &session->net;
352
enum enum_server_command command;
355
indicator of uninitialized lex => normal flow of errors handling
358
session->lex->current_select= 0;
361
This thread will do a blocking read from the client which
362
will be interrupted when the next command is received from
363
the client, the connection is closed or "net_wait_timeout"
364
number of seconds has passed
366
my_net_set_read_timeout(net, session->variables.net_wait_timeout);
369
XXX: this code is here only to clear possible errors of init_connect.
370
Consider moving to init_connect() instead.
372
session->clear_error(); // Clear error message
373
session->main_da.reset_diagnostics_area();
375
net_new_transaction(net);
377
packet_length= my_net_read(net);
378
if (packet_length == packet_error)
380
/* Check if we can continue without closing the connection */
382
/* The error must be set. */
383
assert(session->is_error());
384
net_end_statement(session);
388
return_value= true; // We have to close it.
397
packet= (char*) net->read_pos;
399
'packet_length' contains length of data, as it was stored in packet
400
header. In case of malformed header, my_net_read returns zero.
401
If packet_length is not zero, my_net_read ensures that the returned
402
number of bytes was actually read from network.
403
There is also an extra safety measure in my_net_read:
404
it sets packet[packet_length]= 0, but only for non-zero packets.
406
if (packet_length == 0) /* safety */
408
/* Initialize with COM_SLEEP packet */
409
packet[0]= (unsigned char) COM_SLEEP;
412
/* Do not rely on my_net_read, extra safety against programming errors. */
413
packet[packet_length]= '\0'; /* safety */
415
command= (enum enum_server_command) (unsigned char) packet[0];
417
if (command >= COM_END)
418
command= COM_END; // Wrong command
420
/* Restore read timeout value */
421
my_net_set_read_timeout(net, session->variables.net_read_timeout);
423
assert(packet_length);
424
return_value= dispatch_command(command, session, packet+1, (uint32_t) (packet_length-1));
427
return(return_value);
431
Determine if an attempt to update a non-temporary table while the
432
read-only option was enabled has been made.
434
This is a helper function to mysql_execute_command.
436
@note SQLCOM_MULTI_UPDATE is an exception and dealt with elsewhere.
438
@see mysql_execute_command
441
@retval true The statement should be denied.
442
@retval false The statement isn't updating any relevant tables.
445
static bool deny_updates_if_read_only_option(Session *session,
446
TableList *all_tables)
451
LEX *lex= session->lex;
453
if (!(sql_command_flags[lex->sql_command].test(CF_BIT_CHANGES_DATA)))
456
/* Multi update is an exception and is dealt with later. */
457
if (lex->sql_command == SQLCOM_UPDATE_MULTI)
460
const bool create_temp_tables=
461
(lex->sql_command == SQLCOM_CREATE_TABLE) &&
462
(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE);
464
const bool drop_temp_tables=
465
(lex->sql_command == SQLCOM_DROP_TABLE) &&
468
const bool update_real_tables=
469
some_non_temp_table_to_be_updated(session, all_tables) &&
470
!(create_temp_tables || drop_temp_tables);
473
const bool create_or_drop_databases=
474
(lex->sql_command == SQLCOM_CREATE_DB) ||
475
(lex->sql_command == SQLCOM_DROP_DB);
477
if (update_real_tables || create_or_drop_databases)
480
An attempt was made to modify one or more non-temporary tables.
486
/* Assuming that only temporary tables are modified. */
160
491
Perform one connection-level (COM_XXXX) command.
197
528
/* Increase id and count all other statements. */
199
session->status_var.questions++;
530
statistic_increment(session->status_var.questions, &LOCK_status);
203
/* @todo set session->lex->sql_command to SQLCOM_END here */
535
/* TODO: set session->lex->sql_command to SQLCOM_END here */
536
pthread_mutex_unlock(&LOCK_thread_count);
205
plugin::Logging::preDo(session);
206
if (unlikely(plugin::EventObserver::beforeStatement(*session)))
208
// We should do something about an error...
538
logging_pre_do(session);
211
540
session->server_status&=
212
541
~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
213
542
switch (command) {
214
543
case COM_INIT_DB:
216
if (packet_length == 0)
218
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
222
string tmp(packet, packet_length);
224
identifier::Schema identifier(tmp);
226
if (not change_db(session, identifier))
546
status_var_increment(session->status_var.com_stat[SQLCOM_CHANGE_DB]);
547
session->convert_string(&tmp, system_charset_info,
548
packet, packet_length, session->charset());
549
if (!mysql_change_db(session, &tmp, false))
555
case COM_CHANGE_USER:
557
status_var_increment(session->status_var.com_other);
558
char *user= (char*) packet, *packet_end= packet + packet_length;
559
/* Safe because there is always a trailing \0 at the end of the packet */
560
char *passwd= strchr(user, '\0')+1;
563
session->clear_error(); // if errors from rollback
566
Old clients send null-terminated string ('\0' for empty string) for
567
password. New clients send the size (1 byte) + string (not null
568
terminated, so also '\0' for empty string).
570
Cast *passwd to an unsigned char, so that it doesn't extend the sign
571
for *passwd > 127 and become 2**32-127 after casting to uint32_t.
573
char db_buff[NAME_LEN+1]; // buffer to store db in utf8
577
If there is no password supplied, the packet must contain '\0',
578
in any type of handshake (4.1 or pre-4.1).
580
if (passwd >= packet_end)
582
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
585
uint32_t passwd_len= (session->client_capabilities & CLIENT_SECURE_CONNECTION ?
586
(unsigned char)(*passwd++) : strlen(passwd));
587
uint32_t dummy_errors, save_db_length, db_length;
589
Security_context save_security_ctx= *session->security_ctx;
590
USER_CONN *save_user_connect;
594
Database name is always NUL-terminated, so in case of empty database
595
the packet must contain at least the trailing '\0'.
597
if (db >= packet_end)
599
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
602
db_length= strlen(db);
604
char *ptr= db + db_length + 1;
605
uint32_t cs_number= 0;
607
if (ptr < packet_end)
609
if (ptr + 2 > packet_end)
611
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
615
cs_number= uint2korr(ptr);
618
/* Convert database name to utf8 */
619
db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
620
system_charset_info, db, db_length,
621
session->charset(), &dummy_errors)]= 0;
624
/* Save user and privileges */
625
save_db_length= session->db_length;
626
save_db= session->db;
627
save_user_connect= session->user_connect;
629
if (!(session->security_ctx->user= my_strdup(user, MYF(0))))
631
session->security_ctx->user= save_security_ctx.user;
632
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
636
/* Clear variables that are allocated */
637
session->user_connect= 0;
638
res= check_user(session, passwd, passwd_len, db, false);
642
if (session->security_ctx->user)
643
free(session->security_ctx->user);
644
*session->security_ctx= save_security_ctx;
645
session->user_connect= save_user_connect;
646
session->db= save_db;
647
session->db_length= save_db_length;
653
if (save_security_ctx.user)
654
free(save_security_ctx.user);
658
session_init_client_charset(session, cs_number);
659
session->update_charset();
234
if (not session->readAndStoreQuery(packet, packet_length))
666
if (alloc_query(session, packet, packet_length))
235
667
break; // fatal error is set
236
DRIZZLE_QUERY_START(session->getQueryString()->c_str(),
238
const_cast<const char *>(session->schema()->c_str()));
240
parse(session, session->getQueryString()->c_str(), session->getQueryString()->length());
668
char *packet_end= session->query + session->query_length;
669
const char* end_of_stmt= NULL;
671
mysql_parse(session, session->query, session->query_length, &end_of_stmt);
673
while (!session->killed && (end_of_stmt != NULL) && ! session->is_error())
675
char *beginning_of_next_stmt= (char*) end_of_stmt;
677
net_end_statement(session);
679
Multiple queries exits, execute them individually
681
close_thread_tables(session);
682
ulong length= (ulong)(packet_end - beginning_of_next_stmt);
684
log_slow_statement(session);
686
/* Remove garbage at start of query */
687
while (length > 0 && my_isspace(session->charset(), *beginning_of_next_stmt))
689
beginning_of_next_stmt++;
693
pthread_mutex_lock(&LOCK_thread_count);
694
session->query_length= length;
695
session->query= beginning_of_next_stmt;
697
Count each statement from the client.
699
statistic_increment(session->status_var.questions, &LOCK_status);
700
session->query_id= query_id.next();
701
session->set_time(); /* Reset the query start time. */
702
/* TODO: set session->lex->sql_command to SQLCOM_END here */
703
pthread_mutex_unlock(&LOCK_thread_count);
705
mysql_parse(session, beginning_of_next_stmt, length, &end_of_stmt);
709
case COM_FIELD_LIST: // This isn't actually needed
711
char *fields, *packet_end= packet + packet_length, *arg_end;
712
/* Locked closure of all tables */
713
TableList table_list;
714
LEX_STRING conv_name;
716
/* used as fields initializator */
719
status_var_increment(session->status_var.com_stat[SQLCOM_SHOW_FIELDS]);
720
memset(&table_list, 0, sizeof(table_list));
721
if (session->copy_db_to(&table_list.db, &table_list.db_length))
724
We have name + wildcard in packet, separated by endzero
726
arg_end= strchr(packet, '\0');
727
session->convert_string(&conv_name, system_charset_info,
728
packet, (uint32_t) (arg_end - packet), session->charset());
729
table_list.alias= table_list.table_name= conv_name.str;
732
if (!my_strcasecmp(system_charset_info, table_list.db,
733
INFORMATION_SCHEMA_NAME.c_str()))
735
ST_SCHEMA_TABLE *schema_table= find_schema_table(session, table_list.alias);
737
table_list.schema_table= schema_table;
740
session->query_length= (uint32_t) (packet_end - packet); // Don't count end \0
741
if (!(session->query=fields= (char*) session->memdup(packet,session->query_length+1)))
743
if (lower_case_table_names)
744
my_casedn_str(files_charset_info, table_list.table_name);
746
/* init structures for VIEW processing */
747
table_list.select_lex= &(session->lex->select_lex);
750
mysql_reset_session_for_next_command(session);
753
select_lex.table_list.link_in_list((unsigned char*) &table_list,
754
(unsigned char**) &table_list.next_local);
755
session->lex->add_to_query_tables(&table_list);
757
/* switch on VIEW optimisation: do not fill temporary tables */
758
session->lex->sql_command= SQLCOM_SHOW_FIELDS;
759
mysqld_list_fields(session,&table_list,fields);
760
session->lex->unit.cleanup();
761
session->cleanup_after_query();
245
765
/* We don't calculate statistics for this command */
766
net->error=0; // Don't give 'abort' message
246
767
session->main_da.disable_status(); // Don't send anything back
247
768
error=true; // End server
770
case COM_BINLOG_DUMP:
774
uint32_t slave_server_id;
776
status_var_increment(session->status_var.com_other);
777
/* TODO: The following has to be changed to an 8 byte integer */
778
pos = uint4korr(packet);
779
flags = uint2korr(packet + 4);
780
session->server_id=0; /* avoid suicide */
781
if ((slave_server_id= uint4korr(packet+6))) // mysqlbinlog.server_id==0
782
kill_zombie_dump_threads(slave_server_id);
783
session->server_id = slave_server_id;
785
mysql_binlog_send(session, session->strdup(packet + 10), (my_off_t) pos, flags);
786
/* fake COM_QUIT -- if we get here, the thread needs to terminate */
249
790
case COM_SHUTDOWN:
251
session->status_var.com_other++;
253
session->close_thread_tables(); // Free before kill
792
status_var_increment(session->status_var.com_other);
794
close_thread_tables(session); // Free before kill
259
session->status_var.com_other++;
260
session->my_ok(); // Tell client we are alive
800
status_var_increment(session->status_var.com_other);
801
my_ok(session); // Tell client we are alive
803
case COM_PROCESS_INFO:
804
status_var_increment(session->status_var.com_stat[SQLCOM_SHOW_PROCESSLIST]);
805
mysqld_list_processes(session, NULL, 0);
807
case COM_PROCESS_KILL:
809
status_var_increment(session->status_var.com_stat[SQLCOM_KILL]);
810
ulong id=(ulong) uint4korr(packet);
811
sql_kill(session,id,false);
816
status_var_increment(session->status_var.com_stat[SQLCOM_SET_OPTION]);
817
uint32_t opt_command= uint2korr(packet);
819
switch (opt_command) {
820
case (int) DRIZZLE_OPTION_MULTI_STATEMENTS_ON:
821
session->client_capabilities|= CLIENT_MULTI_STATEMENTS;
824
case (int) DRIZZLE_OPTION_MULTI_STATEMENTS_OFF:
825
session->client_capabilities&= ~CLIENT_MULTI_STATEMENTS;
829
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
263
835
case COM_CONNECT: // Impossible here
836
case COM_TIME: // Impossible from client
266
839
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
481
1108
variables, but for now this is probably good enough.
482
1109
Don't reset warnings when executing a stored routine.
484
if (all_tables || ! lex->is_single_level_stmt())
1111
if (all_tables || !lex->is_single_level_stmt())
486
1112
drizzle_reset_errors(session, 0);
489
assert(session->transaction.stmt.hasModifiedNonTransData() == false);
491
if (! (session->server_status & SERVER_STATUS_AUTOCOMMIT)
492
&& ! session->inTransaction()
493
&& lex->statement->isTransactional())
495
if (session->startTransaction() == false)
497
my_error(drizzled::ER_UNKNOWN_ERROR, MYF(0));
502
/* now we are ready to execute the statement */
503
res= lex->statement->execute();
1114
if (unlikely(session->slave_thread))
1117
Check if statment should be skipped because of slave filtering
1121
- UPDATE MULTI: For this statement, we want to check the filtering
1122
rules later in the code
1123
- SET: we always execute it (Not that many SET commands exists in
1124
the binary log anyway -- only 4.1 masters write SET statements,
1125
in 5.0 there are no SET statements in the binary log)
1126
- DROP TEMPORARY TABLE IF EXISTS: we always execute it (otherwise we
1127
have stale files on slave caused by exclusion of one tmp table).
1129
if (!(lex->sql_command == SQLCOM_UPDATE_MULTI) &&
1130
!(lex->sql_command == SQLCOM_SET_OPTION) &&
1131
!(lex->sql_command == SQLCOM_DROP_TABLE &&
1132
lex->drop_temporary && lex->drop_if_exists) &&
1133
all_tables_not_ok(session, all_tables))
1135
/* we warn the slave SQL thread */
1136
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
1143
When option readonly is set deny operations which change non-temporary
1144
tables. Except for the replication thread and the 'super' users.
1146
if (deny_updates_if_read_only_option(session, all_tables))
1148
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
1151
} /* endif unlikely slave */
1152
status_var_increment(session->status_var.com_stat[lex->sql_command]);
1154
assert(session->transaction.stmt.modified_non_trans_table == false);
1156
switch (lex->sql_command) {
1157
case SQLCOM_SHOW_STATUS:
1159
system_status_var old_status_var= session->status_var;
1160
session->initial_status_var= &old_status_var;
1161
res= execute_sqlcom_select(session, all_tables);
1162
/* Don't log SHOW STATUS commands to slow query log */
1163
session->server_status&= ~(SERVER_QUERY_NO_INDEX_USED |
1164
SERVER_QUERY_NO_GOOD_INDEX_USED);
1166
restore status variables, as we don't want 'show status' to cause
1169
pthread_mutex_lock(&LOCK_status);
1170
add_diff_to_status(&global_status_var, &session->status_var,
1172
session->status_var= old_status_var;
1173
pthread_mutex_unlock(&LOCK_status);
1176
case SQLCOM_SHOW_DATABASES:
1177
case SQLCOM_SHOW_TABLES:
1178
case SQLCOM_SHOW_TABLE_STATUS:
1179
case SQLCOM_SHOW_OPEN_TABLES:
1180
case SQLCOM_SHOW_FIELDS:
1181
case SQLCOM_SHOW_KEYS:
1182
case SQLCOM_SHOW_VARIABLES:
1185
session->status_var.last_query_cost= 0.0;
1186
res= execute_sqlcom_select(session, all_tables);
1189
case SQLCOM_EMPTY_QUERY:
1195
res = purge_master_logs(session, lex->to_log);
1198
case SQLCOM_PURGE_BEFORE:
1202
/* PURGE MASTER LOGS BEFORE 'data' */
1203
it= (Item *)lex->value_list.head();
1204
if ((!it->fixed && it->fix_fields(lex->session, &it)) ||
1207
my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE LOGS BEFORE");
1210
it= new Item_func_unix_timestamp(it);
1212
it is OK only emulate fix_fieds, because we need only
1215
it->quick_fix_field();
1216
res = purge_master_logs_before_date(session, (ulong)it->val_int());
1219
case SQLCOM_SHOW_WARNS:
1221
res= mysqld_show_warnings(session, (uint32_t)
1222
((1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_NOTE) |
1223
(1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_WARN) |
1224
(1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR)
1228
case SQLCOM_SHOW_ERRORS:
1230
res= mysqld_show_warnings(session, (uint32_t)
1231
(1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR));
1234
case SQLCOM_ASSIGN_TO_KEYCACHE:
1236
assert(first_table == all_tables && first_table != 0);
1237
res= mysql_assign_to_keycache(session, first_table, &lex->ident);
1240
case SQLCOM_CHANGE_MASTER:
1242
pthread_mutex_lock(&LOCK_active_mi);
1243
res = change_master(session,active_mi);
1244
pthread_mutex_unlock(&LOCK_active_mi);
1247
case SQLCOM_SHOW_SLAVE_STAT:
1249
pthread_mutex_lock(&LOCK_active_mi);
1250
if (active_mi != NULL)
1252
res = show_master_info(session, active_mi);
1256
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1257
"the master info structure does not exist");
1260
pthread_mutex_unlock(&LOCK_active_mi);
1263
case SQLCOM_SHOW_MASTER_STAT:
1265
res = show_binlog_info(session);
1269
case SQLCOM_SHOW_ENGINE_STATUS:
1271
res = ha_show_status(session, lex->create_info.db_type, HA_ENGINE_STATUS);
1274
case SQLCOM_CREATE_TABLE:
1276
/* If CREATE TABLE of non-temporary table, do implicit commit */
1277
if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE))
1279
if (end_active_trans(session))
1285
assert(first_table == all_tables && first_table != 0);
1287
// Skip first table, which is the table we are creating
1288
TableList *create_table= lex->unlink_first_table(&link_to_local);
1289
TableList *select_tables= lex->query_tables;
1291
Code below (especially in mysql_create_table() and select_create
1292
methods) may modify HA_CREATE_INFO structure in LEX, so we have to
1293
use a copy of this structure to make execution prepared statement-
1294
safe. A shallow copy is enough as this code won't modify any memory
1295
referenced from this structure.
1297
HA_CREATE_INFO create_info(lex->create_info);
1299
We need to copy alter_info for the same reasons of re-execution
1300
safety, only in case of Alter_info we have to do (almost) a deep
1303
Alter_info alter_info(lex->alter_info, session->mem_root);
1305
if (session->is_fatal_error)
1307
/* If out of memory when creating a copy of alter_info. */
1309
goto end_with_restore_list;
1312
if ((res= create_table_precheck(session, select_tables, create_table)))
1313
goto end_with_restore_list;
1315
/* Might have been updated in create_table_precheck */
1316
create_info.alias= create_table->alias;
1318
#ifdef HAVE_READLINK
1319
/* Fix names if symlinked tables */
1320
if (append_file_to_dir(session, &create_info.data_file_name,
1321
create_table->table_name) ||
1322
append_file_to_dir(session, &create_info.index_file_name,
1323
create_table->table_name))
1324
goto end_with_restore_list;
1327
If we are using SET CHARSET without DEFAULT, add an implicit
1328
DEFAULT to not confuse old users. (This may change).
1330
if ((create_info.used_fields &
1331
(HA_CREATE_USED_DEFAULT_CHARSET | HA_CREATE_USED_CHARSET)) ==
1332
HA_CREATE_USED_CHARSET)
1334
create_info.used_fields&= ~HA_CREATE_USED_CHARSET;
1335
create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
1336
create_info.default_table_charset= create_info.table_charset;
1337
create_info.table_charset= 0;
1340
The create-select command will open and read-lock the select table
1341
and then create, open and write-lock the new table. If a global
1342
read lock steps in, we get a deadlock. The write lock waits for
1343
the global read lock, while the global read lock waits for the
1344
select table to be closed. So we wait until the global readlock is
1345
gone before starting both steps. Note that
1346
wait_if_global_read_lock() sets a protection against a new global
1347
read lock when it succeeds. This needs to be released by
1348
start_waiting_global_read_lock(). We protect the normal CREATE
1349
TABLE in the same way. That way we avoid that a new table is
1350
created during a gobal read lock.
1352
if (!session->locked_tables &&
1353
!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
1356
goto end_with_restore_list;
1358
if (select_lex->item_list.elements) // With select
1360
select_result *result;
1362
select_lex->options|= SELECT_NO_UNLOCK;
1363
unit->set_limit(select_lex);
1365
if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
1367
lex->link_first_table_back(create_table, link_to_local);
1368
create_table->create= true;
1371
if (!(res= open_and_lock_tables(session, lex->query_tables)))
1374
Is table which we are changing used somewhere in other parts
1377
if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
1379
TableList *duplicate;
1380
create_table= lex->unlink_first_table(&link_to_local);
1381
if ((duplicate= unique_table(session, create_table, select_tables, 0)))
1383
update_non_unique_table_error(create_table, "CREATE", duplicate);
1385
goto end_with_restore_list;
1390
select_create is currently not re-execution friendly and
1391
needs to be created for every execution of a PS/SP.
1393
if ((result= new select_create(create_table,
1396
select_lex->item_list,
1402
CREATE from SELECT give its SELECT_LEX for SELECT,
1403
and item_list belong to SELECT
1405
res= handle_select(session, lex, result, 0);
1409
else if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
1410
create_table= lex->unlink_first_table(&link_to_local);
1415
/* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
1416
if (create_info.options & HA_LEX_CREATE_TMP_TABLE)
1417
session->options|= OPTION_KEEP_LOG;
1418
/* regular create */
1419
if (create_info.options & HA_LEX_CREATE_TABLE_LIKE)
1420
res= mysql_create_like_table(session, create_table, select_tables,
1424
res= mysql_create_table(session, create_table->db,
1425
create_table->table_name, &create_info,
1432
/* put tables back for PS rexecuting */
1433
end_with_restore_list:
1434
lex->link_first_table_back(create_table, link_to_local);
1437
case SQLCOM_CREATE_INDEX:
1439
case SQLCOM_DROP_INDEX:
1441
CREATE INDEX and DROP INDEX are implemented by calling ALTER
1442
TABLE with proper arguments.
1444
In the future ALTER TABLE will notice that the request is to
1445
only add indexes and create these one by one for the existing
1446
table without having to do a full rebuild.
1449
/* Prepare stack copies to be re-execution safe */
1450
HA_CREATE_INFO create_info;
1451
Alter_info alter_info(lex->alter_info, session->mem_root);
1453
if (session->is_fatal_error) /* out of memory creating a copy of alter_info */
1456
assert(first_table == all_tables && first_table != 0);
1457
if (end_active_trans(session))
1460
memset(&create_info, 0, sizeof(create_info));
1461
create_info.db_type= 0;
1462
create_info.row_type= ROW_TYPE_NOT_USED;
1463
create_info.default_table_charset= session->variables.collation_database;
1465
res= mysql_alter_table(session, first_table->db, first_table->table_name,
1466
&create_info, first_table, &alter_info,
1467
0, (order_st*) 0, 0);
1470
case SQLCOM_SLAVE_START:
1472
pthread_mutex_lock(&LOCK_active_mi);
1473
start_slave(session,active_mi,1 /* net report*/);
1474
pthread_mutex_unlock(&LOCK_active_mi);
1477
case SQLCOM_SLAVE_STOP:
1479
If the client thread has locked tables, a deadlock is possible.
1481
- the client thread does LOCK TABLE t READ.
1482
- then the master updates t.
1483
- then the SQL slave thread wants to update t,
1484
so it waits for the client thread because t is locked by it.
1485
- then the client thread does SLAVE STOP.
1486
SLAVE STOP waits for the SQL slave thread to terminate its
1487
update t, which waits for the client thread because t is locked by it.
1488
To prevent that, refuse SLAVE STOP if the
1489
client thread has locked tables
1491
if (session->locked_tables || session->active_transaction() || session->global_read_lock)
1493
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
1494
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
1498
pthread_mutex_lock(&LOCK_active_mi);
1499
stop_slave(session,active_mi,1/* net report*/);
1500
pthread_mutex_unlock(&LOCK_active_mi);
1504
case SQLCOM_ALTER_TABLE:
1505
assert(first_table == all_tables && first_table != 0);
1508
Code in mysql_alter_table() may modify its HA_CREATE_INFO argument,
1509
so we have to use a copy of this structure to make execution
1510
prepared statement- safe. A shallow copy is enough as no memory
1511
referenced from this structure will be modified.
1513
HA_CREATE_INFO create_info(lex->create_info);
1514
Alter_info alter_info(lex->alter_info, session->mem_root);
1516
if (session->is_fatal_error) /* out of memory creating a copy of alter_info */
1521
/* Must be set in the parser */
1522
assert(select_lex->db);
1524
{ // Rename of table
1525
TableList tmp_table;
1526
memset(&tmp_table, 0, sizeof(tmp_table));
1527
tmp_table.table_name= lex->name.str;
1528
tmp_table.db=select_lex->db;
1531
/* Don't yet allow changing of symlinks with ALTER TABLE */
1532
if (create_info.data_file_name)
1533
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1534
"DATA DIRECTORY option ignored");
1535
if (create_info.index_file_name)
1536
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1537
"INDEX DIRECTORY option ignored");
1538
create_info.data_file_name= create_info.index_file_name= NULL;
1539
/* ALTER TABLE ends previous transaction */
1540
if (end_active_trans(session))
1543
if (!session->locked_tables &&
1544
!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
1550
res= mysql_alter_table(session, select_lex->db, lex->name.str,
1554
select_lex->order_list.elements,
1555
(order_st *) select_lex->order_list.first,
1559
case SQLCOM_RENAME_TABLE:
1561
assert(first_table == all_tables && first_table != 0);
1563
for (table= first_table; table; table= table->next_local->next_local)
1565
TableList old_list, new_list;
1567
we do not need initialize old_list and new_list because we will
1568
come table[0] and table->next[0] there
1571
new_list= table->next_local[0];
1574
if (end_active_trans(session) || drizzle_rename_tables(session, first_table, 0))
1580
case SQLCOM_SHOW_BINLOGS:
1582
res = show_binlogs(session);
1585
case SQLCOM_SHOW_CREATE:
1586
assert(first_table == all_tables && first_table != 0);
1588
res= mysqld_show_create(session, first_table);
1591
case SQLCOM_CHECKSUM:
1593
assert(first_table == all_tables && first_table != 0);
1594
res = mysql_checksum_table(session, first_table, &lex->check_opt);
1599
assert(first_table == all_tables && first_table != 0);
1600
res= mysql_repair_table(session, first_table, &lex->check_opt);
1601
/* ! we write after unlocking the table */
1603
Presumably, REPAIR and binlog writing doesn't require synchronization
1605
write_bin_log(session, true, session->query, session->query_length);
1606
select_lex->table_list.first= (unsigned char*) first_table;
1607
lex->query_tables=all_tables;
1612
assert(first_table == all_tables && first_table != 0);
1613
res = mysql_check_table(session, first_table, &lex->check_opt);
1614
select_lex->table_list.first= (unsigned char*) first_table;
1615
lex->query_tables=all_tables;
1618
case SQLCOM_ANALYZE:
1620
assert(first_table == all_tables && first_table != 0);
1621
res= mysql_analyze_table(session, first_table, &lex->check_opt);
1622
/* ! we write after unlocking the table */
1623
write_bin_log(session, true, session->query, session->query_length);
1624
select_lex->table_list.first= (unsigned char*) first_table;
1625
lex->query_tables=all_tables;
1629
case SQLCOM_OPTIMIZE:
1631
assert(first_table == all_tables && first_table != 0);
1632
res= mysql_optimize_table(session, first_table, &lex->check_opt);
1633
/* ! we write after unlocking the table */
1634
write_bin_log(session, true, session->query, session->query_length);
1635
select_lex->table_list.first= (unsigned char*) first_table;
1636
lex->query_tables=all_tables;
1640
assert(first_table == all_tables && first_table != 0);
1641
if (update_precheck(session, all_tables))
1643
assert(select_lex->offset_limit == 0);
1644
unit->set_limit(select_lex);
1645
res= (up_result= mysql_update(session, all_tables,
1646
select_lex->item_list,
1649
select_lex->order_list.elements,
1650
(order_st *) select_lex->order_list.first,
1651
unit->select_limit_cnt,
1652
lex->duplicates, lex->ignore));
1653
/* mysql_update return 2 if we need to switch to multi-update */
1657
case SQLCOM_UPDATE_MULTI:
1659
assert(first_table == all_tables && first_table != 0);
1660
/* if we switched from normal update, rights are checked */
1663
if ((res= multi_update_precheck(session, all_tables)))
1669
res= mysql_multi_update_prepare(session);
1671
/* Check slave filtering rules */
1672
if (unlikely(session->slave_thread))
1674
if (all_tables_not_ok(session, all_tables))
1678
res= 0; /* don't care of prev failure */
1679
session->clear_error(); /* filters are of highest prior */
1681
/* we warn the slave SQL thread */
1682
my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
1693
some_non_temp_table_to_be_updated(session, all_tables))
1695
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
1700
res= mysql_multi_update(session, all_tables,
1701
&select_lex->item_list,
1704
select_lex->options,
1705
lex->duplicates, lex->ignore, unit, select_lex);
1708
case SQLCOM_REPLACE:
1711
assert(first_table == all_tables && first_table != 0);
1712
if ((res= insert_precheck(session, all_tables)))
1715
if (!session->locked_tables &&
1716
!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
1722
res= mysql_insert(session, all_tables, lex->field_list, lex->many_values,
1723
lex->update_list, lex->value_list,
1724
lex->duplicates, lex->ignore);
1728
case SQLCOM_REPLACE_SELECT:
1729
case SQLCOM_INSERT_SELECT:
1731
select_result *sel_result;
1732
assert(first_table == all_tables && first_table != 0);
1733
if ((res= insert_precheck(session, all_tables)))
1736
/* Fix lock for first table */
1737
if (first_table->lock_type == TL_WRITE_DELAYED)
1738
first_table->lock_type= TL_WRITE;
1740
/* Don't unlock tables until command is written to binary log */
1741
select_lex->options|= SELECT_NO_UNLOCK;
1743
unit->set_limit(select_lex);
1745
if (! session->locked_tables &&
1746
! (need_start_waiting= ! wait_if_global_read_lock(session, 0, 1)))
1752
if (!(res= open_and_lock_tables(session, all_tables)))
1754
/* Skip first table, which is the table we are inserting in */
1755
TableList *second_table= first_table->next_local;
1756
select_lex->table_list.first= (unsigned char*) second_table;
1757
select_lex->context.table_list=
1758
select_lex->context.first_name_resolution_table= second_table;
1759
res= mysql_insert_select_prepare(session);
1760
if (!res && (sel_result= new select_insert(first_table,
1768
res= handle_select(session, lex, sel_result, OPTION_SETUP_TABLES_DONE);
1770
Invalidate the table in the query cache if something changed
1771
after unlocking when changes become visible.
1772
TODO: this is workaround. right way will be move invalidating in
1773
the unlock procedure.
1775
if (first_table->lock_type == TL_WRITE_CONCURRENT_INSERT &&
1778
/* INSERT ... SELECT should invalidate only the very first table */
1779
TableList *save_table= first_table->next_local;
1780
first_table->next_local= 0;
1781
first_table->next_local= save_table;
1785
/* revert changes for SP */
1786
select_lex->table_list.first= (unsigned char*) first_table;
1791
case SQLCOM_TRUNCATE:
1792
if (end_active_trans(session))
1797
assert(first_table == all_tables && first_table != 0);
1799
Don't allow this within a transaction because we want to use
1802
if (session->locked_tables || session->active_transaction())
1804
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
1805
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
1809
res= mysql_truncate(session, first_table, 0);
1814
assert(first_table == all_tables && first_table != 0);
1815
assert(select_lex->offset_limit == 0);
1816
unit->set_limit(select_lex);
1818
if (!session->locked_tables &&
1819
!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
1825
res = mysql_delete(session, all_tables, select_lex->where,
1826
&select_lex->order_list,
1827
unit->select_limit_cnt, select_lex->options,
1831
case SQLCOM_DELETE_MULTI:
1833
assert(first_table == all_tables && first_table != 0);
1834
TableList *aux_tables=
1835
(TableList *)session->lex->auxiliary_table_list.first;
1836
multi_delete *del_result;
1838
if (!session->locked_tables &&
1839
!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
1845
if ((res= multi_delete_precheck(session, all_tables)))
1848
/* condition will be true on SP re-excuting */
1849
if (select_lex->item_list.elements != 0)
1850
select_lex->item_list.empty();
1851
if (add_item_to_list(session, new Item_null()))
1854
session->set_proc_info("init");
1855
if ((res= open_and_lock_tables(session, all_tables)))
1858
if ((res= mysql_multi_delete_prepare(session)))
1861
if (!session->is_fatal_error &&
1862
(del_result= new multi_delete(aux_tables, lex->table_count)))
1864
res= mysql_select(session, &select_lex->ref_pointer_array,
1865
select_lex->get_table_list(),
1866
select_lex->with_wild,
1867
select_lex->item_list,
1869
0, (order_st *)NULL, (order_st *)NULL, (Item *)NULL,
1871
select_lex->options | session->options |
1872
SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
1873
OPTION_SETUP_TABLES_DONE,
1874
del_result, unit, select_lex);
1875
res|= session->is_error();
1877
del_result->abort();
1884
case SQLCOM_DROP_TABLE:
1886
assert(first_table == all_tables && first_table != 0);
1887
if (!lex->drop_temporary)
1889
if (end_active_trans(session))
1895
If this is a slave thread, we may sometimes execute some
1896
DROP / * 40005 TEMPORARY * / TABLE
1897
that come from parts of binlogs (likely if we use RESET SLAVE or CHANGE
1898
MASTER TO), while the temporary table has already been dropped.
1899
To not generate such irrelevant "table does not exist errors",
1900
we silently add IF EXISTS if TEMPORARY was used.
1902
if (session->slave_thread)
1903
lex->drop_if_exists= 1;
1905
/* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
1906
session->options|= OPTION_KEEP_LOG;
1908
/* DDL and binlog write order protected by LOCK_open */
1909
res= mysql_rm_table(session, first_table, lex->drop_if_exists, lex->drop_temporary);
1912
case SQLCOM_SHOW_PROCESSLIST:
1913
mysqld_list_processes(session, NULL, lex->verbose);
1915
case SQLCOM_SHOW_ENGINE_LOGS:
1917
res= ha_show_status(session, lex->create_info.db_type, HA_ENGINE_LOGS);
1920
case SQLCOM_CHANGE_DB:
1922
LEX_STRING db_str= { (char *) select_lex->db, strlen(select_lex->db) };
1924
if (!mysql_change_db(session, &db_str, false))
1932
assert(first_table == all_tables && first_table != 0);
1933
if (lex->local_file)
1935
if (!(session->client_capabilities & CLIENT_LOCAL_FILES) ||
1938
my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), MYF(0));
1943
res= mysql_load(session, lex->exchange, first_table, lex->field_list,
1944
lex->update_list, lex->value_list, lex->duplicates,
1945
lex->ignore, (bool) lex->local_file);
1949
case SQLCOM_SET_OPTION:
1951
List<set_var_base> *lex_var_list= &lex->var_list;
1953
if (lex->autocommit && end_active_trans(session))
1956
if (open_and_lock_tables(session, all_tables))
1958
if (!(res= sql_set_variables(session, lex_var_list)))
1965
We encountered some sort of error, but no message was sent.
1966
Send something semi-generic here since we don't know which
1967
assignment in the list caused the error.
1969
if (!session->is_error())
1970
my_error(ER_WRONG_ARGUMENTS,MYF(0),"SET");
1977
case SQLCOM_UNLOCK_TABLES:
1979
It is critical for mysqldump --single-transaction --master-data that
1980
UNLOCK TABLES does not implicitely commit a connection which has only
1981
done FLUSH TABLES WITH READ LOCK + BEGIN. If this assumption becomes
1982
false, mysqldump will not work.
1984
unlock_locked_tables(session);
1985
if (session->options & OPTION_TABLE_LOCK)
1987
end_active_trans(session);
1988
session->options&= ~(OPTION_TABLE_LOCK);
1990
if (session->global_read_lock)
1991
unlock_global_read_lock(session);
1994
case SQLCOM_LOCK_TABLES:
1996
We try to take transactional locks if
1997
- only transactional locks are requested (lex->lock_transactional) and
1998
- no non-transactional locks exist (!session->locked_tables).
2000
if (lex->lock_transactional && !session->locked_tables)
2004
All requested locks are transactional and no non-transactional
2007
if ((rc= try_transactional_lock(session, all_tables)) == -1)
2015
Non-transactional locking has been requested or
2016
non-transactional locks exist already or transactional locks are
2017
not supported by all storage engines. Take non-transactional
2022
One or more requested locks are non-transactional and/or
2023
non-transactional locks exist or a storage engine does not support
2024
transactional locks. Check if at least one transactional lock is
2025
requested. If yes, warn about the conversion to non-transactional
2026
locks or abort in strict mode.
2028
if (check_transactional_lock(session, all_tables))
2030
unlock_locked_tables(session);
2031
/* we must end the trasaction first, regardless of anything */
2032
if (end_active_trans(session))
2034
session->in_lock_tables=1;
2035
session->options|= OPTION_TABLE_LOCK;
2037
if (!(res= simple_open_n_lock_tables(session, all_tables)))
2039
session->locked_tables=session->lock;
2041
(void) set_handler_table_locks(session, all_tables, false);
2047
Need to end the current transaction, so the storage engine (InnoDB)
2048
can free its locks if LOCK TABLES locked some tables before finding
2049
that it can't lock a table in its list
2051
ha_autocommit_or_rollback(session, 1);
2052
end_active_trans(session);
2053
session->options&= ~(OPTION_TABLE_LOCK);
2055
session->in_lock_tables=0;
2057
case SQLCOM_CREATE_DB:
2060
As mysql_create_db() may modify HA_CREATE_INFO structure passed to
2061
it, we need to use a copy of LEX::create_info to make execution
2062
prepared statement- safe.
2064
HA_CREATE_INFO create_info(lex->create_info);
2065
if (end_active_trans(session))
2071
if (!(alias=session->strmake(lex->name.str, lex->name.length)) ||
2072
check_db_name(&lex->name))
2074
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
2077
res= mysql_create_db(session,(lower_case_table_names == 2 ? alias :
2078
lex->name.str), &create_info, 0);
2081
case SQLCOM_DROP_DB:
2083
if (end_active_trans(session))
2088
if (check_db_name(&lex->name))
2090
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
2093
if (session->locked_tables || session->active_transaction())
2095
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
2096
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
2099
res= mysql_rm_db(session, lex->name.str, lex->drop_if_exists, 0);
2102
case SQLCOM_ALTER_DB:
2104
LEX_STRING *db= &lex->name;
2105
HA_CREATE_INFO create_info(lex->create_info);
2106
if (check_db_name(db))
2108
my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
2111
if (session->locked_tables || session->active_transaction())
2113
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
2114
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
2117
res= mysql_alter_db(session, db->str, &create_info);
2120
case SQLCOM_SHOW_CREATE_DB:
2122
if (check_db_name(&lex->name))
2124
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
2127
res= mysqld_show_create_db(session, lex->name.str, &lex->create_info);
2133
bool write_to_binlog;
2136
reload_cache() will tell us if we are allowed to write to the
2139
if (!reload_cache(session, lex->type, first_table, &write_to_binlog))
2142
We WANT to write and we CAN write.
2143
! we write after unlocking the table.
2146
Presumably, RESET and binlog writing doesn't require synchronization
2148
write_bin_log(session, false, session->query, session->query_length);
2156
Item *it= (Item *)lex->value_list.head();
2158
if (lex->table_or_sp_used())
2160
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "Usage of subqueries or stored "
2161
"function calls as part of this statement");
2165
if ((!it->fixed && it->fix_fields(lex->session, &it)) || it->check_cols(1))
2167
my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
2171
sql_kill(session, (ulong)it->val_int(), lex->type & ONLY_KILL_QUERY);
2175
if (session->transaction.xid_state.xa_state != XA_NOTR)
2177
my_error(ER_XAER_RMFAIL, MYF(0),
2178
xa_state_names[session->transaction.xid_state.xa_state]);
2182
Breakpoints for backup testing.
2184
if (begin_trans(session))
2189
if (end_trans(session, lex->tx_release ? COMMIT_RELEASE :
2190
lex->tx_chain ? COMMIT_AND_CHAIN : COMMIT))
2194
case SQLCOM_ROLLBACK:
2195
if (end_trans(session, lex->tx_release ? ROLLBACK_RELEASE :
2196
lex->tx_chain ? ROLLBACK_AND_CHAIN : ROLLBACK))
2200
case SQLCOM_RELEASE_SAVEPOINT:
2203
for (sv=session->transaction.savepoints; sv; sv=sv->prev)
2205
if (my_strnncoll(system_charset_info,
2206
(unsigned char *)lex->ident.str, lex->ident.length,
2207
(unsigned char *)sv->name, sv->length) == 0)
2212
if (ha_release_savepoint(session, sv))
2213
res= true; // cannot happen
2216
session->transaction.savepoints=sv->prev;
2219
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
2222
case SQLCOM_ROLLBACK_TO_SAVEPOINT:
2225
for (sv=session->transaction.savepoints; sv; sv=sv->prev)
2227
if (my_strnncoll(system_charset_info,
2228
(unsigned char *)lex->ident.str, lex->ident.length,
2229
(unsigned char *)sv->name, sv->length) == 0)
2234
if (ha_rollback_to_savepoint(session, sv))
2235
res= true; // cannot happen
2238
if (((session->options & OPTION_KEEP_LOG) ||
2239
session->transaction.all.modified_non_trans_table) &&
2240
!session->slave_thread)
2241
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2242
ER_WARNING_NOT_COMPLETE_ROLLBACK,
2243
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
2246
session->transaction.savepoints=sv;
2249
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
2252
case SQLCOM_SAVEPOINT:
2253
if (!(session->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) || !opt_using_transactions)
2257
SAVEPOINT **sv, *newsv;
2258
for (sv=&session->transaction.savepoints; *sv; sv=&(*sv)->prev)
2260
if (my_strnncoll(system_charset_info,
2261
(unsigned char *)lex->ident.str, lex->ident.length,
2262
(unsigned char *)(*sv)->name, (*sv)->length) == 0)
2265
if (*sv) /* old savepoint of the same name exists */
2268
ha_release_savepoint(session, *sv); // it cannot fail
2271
else if ((newsv=(SAVEPOINT *) alloc_root(&session->transaction.mem_root,
2272
savepoint_alloc_size)) == 0)
2274
my_error(ER_OUT_OF_RESOURCES, MYF(0));
2277
newsv->name=strmake_root(&session->transaction.mem_root,
2278
lex->ident.str, lex->ident.length);
2279
newsv->length=lex->ident.length;
2281
if we'll get an error here, don't add new savepoint to the list.
2282
we'll lose a little bit of memory in transaction mem_root, but it'll
2283
be free'd when transaction ends anyway
2285
if (ha_savepoint(session, newsv))
2289
newsv->prev=session->transaction.savepoints;
2290
session->transaction.savepoints=newsv;
2295
case SQLCOM_BINLOG_BASE64_EVENT:
2297
mysql_client_binlog_statement(session);
2301
assert(0); /* Impossible */
504
2305
session->set_proc_info("query end");
506
2308
The return value for ROW_COUNT() is "implementation dependent" if the
507
2309
statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC
508
2310
wants. We also keep the last value in case of SQLCOM_CALL or
511
if (! (sql_command_flags[lex->sql_command].test(CF_BIT_HAS_ROW_COUNT)))
2313
if (!(sql_command_flags[lex->sql_command].test(CF_BIT_HAS_ROW_COUNT)))
513
2314
session->row_count_func= -1;
2322
if (need_start_waiting)
2325
Release the protection against the global read lock and wake
2326
everyone, who might want to set a global read lock.
2328
start_waiting_global_read_lock(session);
516
return (res || session->is_error());
2330
return(res || session->is_error());
518
2333
bool execute_sqlcom_select(Session *session, TableList *all_tables)
520
2335
LEX *lex= session->lex;
521
2336
select_result *result=lex->result;
523
2338
/* assign global limit variable if limit is not given */
525
Select_Lex *param= lex->unit.global_parameters;
2340
SELECT_LEX *param= lex->unit.global_parameters;
526
2341
if (!param->explicit_limit)
527
2342
param->select_limit=
528
2343
new Item_int((uint64_t) session->variables.select_limit);
532
&& ! (session->server_status & SERVER_STATUS_AUTOCOMMIT)
533
&& ! session->inTransaction()
534
&& ! lex->statement->isShow())
536
if (session->startTransaction() == false)
538
my_error(drizzled::ER_UNKNOWN_ERROR, MYF(0));
543
if (not (res= session->openTablesLock(all_tables)))
2345
if (!(res= open_and_lock_tables(session, all_tables)))
545
2347
if (lex->describe)