123
179
sql_command_flags[SQLCOM_DROP_INDEX]= CF_CHANGES_DATA;
125
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;
126
183
sql_command_flags[SQLCOM_INSERT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
127
184
sql_command_flags[SQLCOM_INSERT_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
128
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;
129
187
sql_command_flags[SQLCOM_REPLACE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
130
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_CHARSETS]= CF_STATUS_COMMAND;
197
sql_command_flags[SQLCOM_SHOW_COLLATIONS]= CF_STATUS_COMMAND;
198
sql_command_flags[SQLCOM_SHOW_BINLOGS]= CF_STATUS_COMMAND;
199
sql_command_flags[SQLCOM_SHOW_SLAVE_HOSTS]= CF_STATUS_COMMAND;
200
sql_command_flags[SQLCOM_SHOW_BINLOG_EVENTS]= CF_STATUS_COMMAND;
132
201
sql_command_flags[SQLCOM_SHOW_WARNS]= CF_STATUS_COMMAND;
133
202
sql_command_flags[SQLCOM_SHOW_ERRORS]= CF_STATUS_COMMAND;
203
sql_command_flags[SQLCOM_SHOW_ENGINE_STATUS]= CF_STATUS_COMMAND;
204
sql_command_flags[SQLCOM_SHOW_PROCESSLIST]= CF_STATUS_COMMAND;
134
205
sql_command_flags[SQLCOM_SHOW_CREATE_DB]= CF_STATUS_COMMAND;
135
206
sql_command_flags[SQLCOM_SHOW_CREATE]= CF_STATUS_COMMAND;
207
sql_command_flags[SQLCOM_SHOW_MASTER_STAT]= CF_STATUS_COMMAND;
208
sql_command_flags[SQLCOM_SHOW_SLAVE_STAT]= CF_STATUS_COMMAND;
210
sql_command_flags[SQLCOM_SHOW_TABLES]= (CF_STATUS_COMMAND |
211
CF_SHOW_TABLE_COMMAND);
212
sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]= (CF_STATUS_COMMAND |
213
CF_SHOW_TABLE_COMMAND);
138
215
The following admin table operations are allowed
218
sql_command_flags[SQLCOM_REPAIR]= CF_WRITE_LOGS_COMMAND;
219
sql_command_flags[SQLCOM_OPTIMIZE]= CF_WRITE_LOGS_COMMAND;
141
220
sql_command_flags[SQLCOM_ANALYZE]= CF_WRITE_LOGS_COMMAND;
224
bool is_update_query(enum enum_sql_command command)
226
assert(command >= 0 && command <= SQLCOM_END);
227
return (sql_command_flags[command] & CF_CHANGES_DATA) != 0;
230
void execute_init_command(THD *thd, sys_var_str *init_command_var,
231
rw_lock_t *var_mutex)
234
ulong save_client_capabilities;
236
thd_proc_info(thd, "Execution of init_command");
238
We need to lock init_command_var because
239
during execution of init_command_var query
240
values of init_command_var can't be changed
242
rw_rdlock(var_mutex);
243
save_client_capabilities= thd->client_capabilities;
244
thd->client_capabilities|= CLIENT_MULTI_STATEMENTS;
246
We don't need return result of execution to client side.
247
To forbid this we should set thd->net.vio to 0.
249
save_vio= thd->net.vio;
251
dispatch_command(COM_QUERY, thd,
252
init_command_var->value,
253
init_command_var->value_length);
254
rw_unlock(var_mutex);
255
thd->client_capabilities= save_client_capabilities;
256
thd->net.vio= save_vio;
260
Ends the current transaction and (maybe) begin the next.
262
@param thd Current thread
263
@param completion Completion type
269
int end_trans(THD *thd, enum enum_mysql_completiontype completion)
274
if (unlikely(thd->in_sub_stmt))
276
my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
279
if (thd->transaction.xid_state.xa_state != XA_NOTR)
281
my_error(ER_XAER_RMFAIL, MYF(0),
282
xa_state_names[thd->transaction.xid_state.xa_state]);
285
switch (completion) {
288
We don't use end_active_trans() here to ensure that this works
289
even if there is a problem with the OPTION_AUTO_COMMIT flag
290
(Which of course should never happen...)
292
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
294
thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
295
thd->transaction.all.modified_non_trans_table= false;
298
do_release= 1; /* fall through */
299
case COMMIT_AND_CHAIN:
300
res= end_active_trans(thd);
301
if (!res && completion == COMMIT_AND_CHAIN)
302
res= begin_trans(thd);
304
case ROLLBACK_RELEASE:
305
do_release= 1; /* fall through */
307
case ROLLBACK_AND_CHAIN:
309
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
310
if (ha_rollback(thd))
312
thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
313
thd->transaction.all.modified_non_trans_table= false;
314
if (!res && (completion == ROLLBACK_AND_CHAIN))
315
res= begin_trans(thd);
320
my_error(ER_UNKNOWN_COM_ERROR, MYF(0));
325
my_error(thd->killed_errno(), MYF(0));
326
else if ((res == 0) && do_release)
327
thd->killed= THD::KILL_CONNECTION;
334
Read one command from connection and execute it (query or simple command).
335
This function is called in loop from thread function.
337
For profiling to work, it must never be called recursively.
342
1 request of thread shutdown (see dispatch_command() description)
345
bool do_command(THD *thd)
351
enum enum_server_command command;
354
indicator of uninitialized lex => normal flow of errors handling
357
thd->lex->current_select= 0;
360
This thread will do a blocking read from the client which
361
will be interrupted when the next command is received from
362
the client, the connection is closed or "net_wait_timeout"
363
number of seconds has passed
365
my_net_set_read_timeout(net, thd->variables.net_wait_timeout);
368
XXX: this code is here only to clear possible errors of init_connect.
369
Consider moving to init_connect() instead.
371
thd->clear_error(); // Clear error message
372
thd->main_da.reset_diagnostics_area();
374
net_new_transaction(net);
376
packet_length= my_net_read(net);
377
if (packet_length == packet_error)
379
/* Check if we can continue without closing the connection */
381
/* The error must be set. */
382
assert(thd->is_error());
383
net_end_statement(thd);
387
return_value= true; // We have to close it.
396
packet= (char*) net->read_pos;
398
'packet_length' contains length of data, as it was stored in packet
399
header. In case of malformed header, my_net_read returns zero.
400
If packet_length is not zero, my_net_read ensures that the returned
401
number of bytes was actually read from network.
402
There is also an extra safety measure in my_net_read:
403
it sets packet[packet_length]= 0, but only for non-zero packets.
405
if (packet_length == 0) /* safety */
407
/* Initialize with COM_SLEEP packet */
408
packet[0]= (unsigned char) COM_SLEEP;
411
/* Do not rely on my_net_read, extra safety against programming errors. */
412
packet[packet_length]= '\0'; /* safety */
414
command= (enum enum_server_command) (unsigned char) packet[0];
416
if (command >= COM_END)
417
command= COM_END; // Wrong command
419
/* Restore read timeout value */
420
my_net_set_read_timeout(net, thd->variables.net_read_timeout);
422
assert(packet_length);
423
return_value= dispatch_command(command, thd, packet+1, (uint32_t) (packet_length-1));
426
return(return_value);
430
Determine if an attempt to update a non-temporary table while the
431
read-only option was enabled has been made.
433
This is a helper function to mysql_execute_command.
435
@note SQLCOM_MULTI_UPDATE is an exception and dealt with elsewhere.
437
@see mysql_execute_command
440
@retval true The statement should be denied.
441
@retval false The statement isn't updating any relevant tables.
444
static bool deny_updates_if_read_only_option(THD *thd,
445
TableList *all_tables)
452
if (!(sql_command_flags[lex->sql_command] & CF_CHANGES_DATA))
455
/* Multi update is an exception and is dealt with later. */
456
if (lex->sql_command == SQLCOM_UPDATE_MULTI)
459
const bool create_temp_tables=
460
(lex->sql_command == SQLCOM_CREATE_TABLE) &&
461
(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE);
463
const bool drop_temp_tables=
464
(lex->sql_command == SQLCOM_DROP_TABLE) &&
467
const bool update_real_tables=
468
some_non_temp_table_to_be_updated(thd, all_tables) &&
469
!(create_temp_tables || drop_temp_tables);
472
const bool create_or_drop_databases=
473
(lex->sql_command == SQLCOM_CREATE_DB) ||
474
(lex->sql_command == SQLCOM_DROP_DB);
476
if (update_real_tables || create_or_drop_databases)
479
An attempt was made to modify one or more non-temporary tables.
485
/* Assuming that only temporary tables are modified. */
145
490
Perform one connection-level (COM_XXXX) command.
147
492
@param command type of command to perform
148
@param session connection handle
493
@param thd connection handle
149
494
@param packet data for the command, packet is always null-terminated
150
495
@param packet_length length of packet + 1 (to show that data is
151
496
null-terminated) except for COM_SLEEP, where it
155
set session->lex->sql_command to SQLCOM_END here.
500
set thd->lex->sql_command to SQLCOM_END here.
157
502
The following has to be changed to an 8 byte integer
183
531
/* Increase id and count all other statements. */
185
statistic_increment(session->status_var.questions, &LOCK_status);
533
statistic_increment(thd->status_var.questions, &LOCK_status);
189
/* TODO: set session->lex->sql_command to SQLCOM_END here */
191
plugin::Logging::preDo(session);
193
session->server_status&=
538
/* TODO: set thd->lex->sql_command to SQLCOM_END here */
539
pthread_mutex_unlock(&LOCK_thread_count);
194
544
~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
195
545
switch (command) {
196
546
case COM_INIT_DB:
198
status_var_increment(session->status_var.com_stat[SQLCOM_CHANGE_DB]);
199
if (packet_length == 0)
201
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
205
string tmp(packet, packet_length);
207
SchemaIdentifier identifier(tmp);
209
if (not mysql_change_db(session, identifier))
549
status_var_increment(thd->status_var.com_stat[SQLCOM_CHANGE_DB]);
550
thd->convert_string(&tmp, system_charset_info,
551
packet, packet_length, thd->charset());
552
if (!mysql_change_db(thd, &tmp, false))
558
case COM_REGISTER_SLAVE:
560
if (!register_slave(thd, (unsigned char*)packet, packet_length))
564
case COM_CHANGE_USER:
566
status_var_increment(thd->status_var.com_other);
567
char *user= (char*) packet, *packet_end= packet + packet_length;
568
/* Safe because there is always a trailing \0 at the end of the packet */
569
char *passwd= strchr(user, '\0')+1;
572
thd->clear_error(); // if errors from rollback
575
Old clients send null-terminated string ('\0' for empty string) for
576
password. New clients send the size (1 byte) + string (not null
577
terminated, so also '\0' for empty string).
579
Cast *passwd to an unsigned char, so that it doesn't extend the sign
580
for *passwd > 127 and become 2**32-127 after casting to uint32_t.
582
char db_buff[NAME_LEN+1]; // buffer to store db in utf8
586
If there is no password supplied, the packet must contain '\0',
587
in any type of handshake (4.1 or pre-4.1).
589
if (passwd >= packet_end)
591
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
594
uint32_t passwd_len= (thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
595
(unsigned char)(*passwd++) : strlen(passwd));
596
uint32_t dummy_errors, save_db_length, db_length;
598
Security_context save_security_ctx= *thd->security_ctx;
599
USER_CONN *save_user_connect;
603
Database name is always NUL-terminated, so in case of empty database
604
the packet must contain at least the trailing '\0'.
606
if (db >= packet_end)
608
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
611
db_length= strlen(db);
613
char *ptr= db + db_length + 1;
614
uint32_t cs_number= 0;
616
if (ptr < packet_end)
618
if (ptr + 2 > packet_end)
620
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
624
cs_number= uint2korr(ptr);
627
/* Convert database name to utf8 */
628
db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
629
system_charset_info, db, db_length,
630
thd->charset(), &dummy_errors)]= 0;
633
/* Save user and privileges */
634
save_db_length= thd->db_length;
636
save_user_connect= thd->user_connect;
638
if (!(thd->security_ctx->user= my_strdup(user, MYF(0))))
640
thd->security_ctx->user= save_security_ctx.user;
641
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
645
/* Clear variables that are allocated */
646
thd->user_connect= 0;
647
res= check_user(thd, passwd, passwd_len, db, false);
651
if (thd->security_ctx->user)
652
free(thd->security_ctx->user);
653
*thd->security_ctx= save_security_ctx;
654
thd->user_connect= save_user_connect;
656
thd->db_length= save_db_length;
662
if (save_security_ctx.user)
663
free(save_security_ctx.user);
667
thd_init_client_charset(thd, cs_number);
668
thd->update_charset();
217
if (! session->readAndStoreQuery(packet, packet_length))
675
if (alloc_query(thd, packet, packet_length))
218
676
break; // fatal error is set
219
DRIZZLE_QUERY_START(session->query.c_str(),
221
const_cast<const char *>(session->db.empty() ? "" : session->db.c_str()));
223
plugin::QueryRewriter::rewriteQuery(session->db, session->query);
224
mysql_parse(session, session->query.c_str(), session->query.length());
677
char *packet_end= thd->query + thd->query_length;
678
const char* end_of_stmt= NULL;
680
mysql_parse(thd, thd->query, thd->query_length, &end_of_stmt);
682
while (!thd->killed && (end_of_stmt != NULL) && ! thd->is_error())
684
char *beginning_of_next_stmt= (char*) end_of_stmt;
686
net_end_statement(thd);
688
Multiple queries exits, execute them individually
690
close_thread_tables(thd);
691
ulong length= (ulong)(packet_end - beginning_of_next_stmt);
693
log_slow_statement(thd);
695
/* Remove garbage at start of query */
696
while (length > 0 && my_isspace(thd->charset(), *beginning_of_next_stmt))
698
beginning_of_next_stmt++;
702
pthread_mutex_lock(&LOCK_thread_count);
703
thd->query_length= length;
704
thd->query= beginning_of_next_stmt;
706
Count each statement from the client.
708
statistic_increment(thd->status_var.questions, &LOCK_status);
709
thd->query_id= next_query_id();
710
thd->set_time(); /* Reset the query start time. */
711
/* TODO: set thd->lex->sql_command to SQLCOM_END here */
712
pthread_mutex_unlock(&LOCK_thread_count);
714
mysql_parse(thd, beginning_of_next_stmt, length, &end_of_stmt);
718
case COM_FIELD_LIST: // This isn't actually needed
720
char *fields, *packet_end= packet + packet_length, *arg_end;
721
/* Locked closure of all tables */
722
TableList table_list;
723
LEX_STRING conv_name;
725
/* used as fields initializator */
728
status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_FIELDS]);
729
memset(&table_list, 0, sizeof(table_list));
730
if (thd->copy_db_to(&table_list.db, &table_list.db_length))
733
We have name + wildcard in packet, separated by endzero
735
arg_end= strchr(packet, '\0');
736
thd->convert_string(&conv_name, system_charset_info,
737
packet, (uint32_t) (arg_end - packet), thd->charset());
738
table_list.alias= table_list.table_name= conv_name.str;
741
if (!my_strcasecmp(system_charset_info, table_list.db,
742
INFORMATION_SCHEMA_NAME.str))
744
ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, table_list.alias);
746
table_list.schema_table= schema_table;
749
thd->query_length= (uint32_t) (packet_end - packet); // Don't count end \0
750
if (!(thd->query=fields= (char*) thd->memdup(packet,thd->query_length+1)))
752
if (lower_case_table_names)
753
my_casedn_str(files_charset_info, table_list.table_name);
755
/* init structures for VIEW processing */
756
table_list.select_lex= &(thd->lex->select_lex);
759
mysql_reset_thd_for_next_command(thd);
762
select_lex.table_list.link_in_list((unsigned char*) &table_list,
763
(unsigned char**) &table_list.next_local);
764
thd->lex->add_to_query_tables(&table_list);
766
/* switch on VIEW optimisation: do not fill temporary tables */
767
thd->lex->sql_command= SQLCOM_SHOW_FIELDS;
768
mysqld_list_fields(thd,&table_list,fields);
769
thd->lex->unit.cleanup();
770
thd->cleanup_after_query();
229
774
/* We don't calculate statistics for this command */
230
session->main_da.disable_status(); // Don't send anything back
775
net->error=0; // Don't give 'abort' message
776
thd->main_da.disable_status(); // Don't send anything back
231
777
error=true; // End server
779
case COM_BINLOG_DUMP:
783
uint32_t slave_server_id;
785
status_var_increment(thd->status_var.com_other);
786
thd->enable_slow_log= opt_log_slow_admin_statements;
787
/* TODO: The following has to be changed to an 8 byte integer */
788
pos = uint4korr(packet);
789
flags = uint2korr(packet + 4);
790
thd->server_id=0; /* avoid suicide */
791
if ((slave_server_id= uint4korr(packet+6))) // mysqlbinlog.server_id==0
792
kill_zombie_dump_threads(slave_server_id);
793
thd->server_id = slave_server_id;
795
mysql_binlog_send(thd, thd->strdup(packet + 10), (my_off_t) pos, flags);
796
unregister_slave(thd,1,1);
797
/* fake COM_QUIT -- if we get here, the thread needs to terminate */
233
801
case COM_SHUTDOWN:
235
status_var_increment(session->status_var.com_other);
237
session->close_thread_tables(); // Free before kill
803
status_var_increment(thd->status_var.com_other);
805
close_thread_tables(thd); // Free before kill
243
status_var_increment(session->status_var.com_other);
244
session->my_ok(); // Tell client we are alive
811
status_var_increment(thd->status_var.com_other);
812
my_ok(thd); // Tell client we are alive
814
case COM_PROCESS_INFO:
815
status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_PROCESSLIST]);
816
mysqld_list_processes(thd, NULL, 0);
818
case COM_PROCESS_KILL:
820
status_var_increment(thd->status_var.com_stat[SQLCOM_KILL]);
821
ulong id=(ulong) uint4korr(packet);
822
sql_kill(thd,id,false);
827
status_var_increment(thd->status_var.com_stat[SQLCOM_SET_OPTION]);
828
uint32_t opt_command= uint2korr(packet);
830
switch (opt_command) {
831
case (int) DRIZZLE_OPTION_MULTI_STATEMENTS_ON:
832
thd->client_capabilities|= CLIENT_MULTI_STATEMENTS;
835
case (int) DRIZZLE_OPTION_MULTI_STATEMENTS_OFF:
836
thd->client_capabilities&= ~CLIENT_MULTI_STATEMENTS;
840
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
247
846
case COM_CONNECT: // Impossible here
847
case COM_TIME: // Impossible from client
250
850
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
468
1145
variables, but for now this is probably good enough.
469
1146
Don't reset warnings when executing a stored routine.
471
if (all_tables || ! lex->is_single_level_stmt())
473
drizzle_reset_errors(session, 0);
476
status_var_increment(session->status_var.com_stat[lex->sql_command]);
478
assert(session->transaction.stmt.hasModifiedNonTransData() == false);
480
/* now we are ready to execute the statement */
481
res= lex->statement->execute();
483
session->set_proc_info("query end");
1148
if (all_tables || !lex->is_single_level_stmt())
1149
drizzle_reset_errors(thd, 0);
1151
if (unlikely(thd->slave_thread))
1154
Check if statment should be skipped because of slave filtering
1158
- UPDATE MULTI: For this statement, we want to check the filtering
1159
rules later in the code
1160
- SET: we always execute it (Not that many SET commands exists in
1161
the binary log anyway -- only 4.1 masters write SET statements,
1162
in 5.0 there are no SET statements in the binary log)
1163
- DROP TEMPORARY TABLE IF EXISTS: we always execute it (otherwise we
1164
have stale files on slave caused by exclusion of one tmp table).
1166
if (!(lex->sql_command == SQLCOM_UPDATE_MULTI) &&
1167
!(lex->sql_command == SQLCOM_SET_OPTION) &&
1168
!(lex->sql_command == SQLCOM_DROP_TABLE &&
1169
lex->drop_temporary && lex->drop_if_exists) &&
1170
all_tables_not_ok(thd, all_tables))
1172
/* we warn the slave SQL thread */
1173
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
1174
if (thd->one_shot_set)
1177
It's ok to check thd->one_shot_set here:
1179
The charsets in a MySQL 5.0 slave can change by both a binlogged
1180
SET ONE_SHOT statement and the event-internal charset setting,
1181
and these two ways to change charsets do not seems to work
1184
At least there seems to be problems in the rli cache for
1185
charsets if we are using ONE_SHOT. Note that this is normally no
1186
problem because either the >= 5.0 slave reads a 4.1 binlog (with
1187
ONE_SHOT) *or* or 5.0 binlog (without ONE_SHOT) but never both."
1189
reset_one_shot_variables(thd);
1197
When option readonly is set deny operations which change non-temporary
1198
tables. Except for the replication thread and the 'super' users.
1200
if (deny_updates_if_read_only_option(thd, all_tables))
1202
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
1205
} /* endif unlikely slave */
1206
status_var_increment(thd->status_var.com_stat[lex->sql_command]);
1208
assert(thd->transaction.stmt.modified_non_trans_table == false);
1210
switch (lex->sql_command) {
1211
case SQLCOM_SHOW_STATUS:
1213
system_status_var old_status_var= thd->status_var;
1214
thd->initial_status_var= &old_status_var;
1215
res= execute_sqlcom_select(thd, all_tables);
1216
/* Don't log SHOW STATUS commands to slow query log */
1217
thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED |
1218
SERVER_QUERY_NO_GOOD_INDEX_USED);
1220
restore status variables, as we don't want 'show status' to cause
1223
pthread_mutex_lock(&LOCK_status);
1224
add_diff_to_status(&global_status_var, &thd->status_var,
1226
thd->status_var= old_status_var;
1227
pthread_mutex_unlock(&LOCK_status);
1230
case SQLCOM_SHOW_DATABASES:
1231
case SQLCOM_SHOW_TABLES:
1232
case SQLCOM_SHOW_TABLE_STATUS:
1233
case SQLCOM_SHOW_OPEN_TABLES:
1234
case SQLCOM_SHOW_FIELDS:
1235
case SQLCOM_SHOW_KEYS:
1236
case SQLCOM_SHOW_VARIABLES:
1237
case SQLCOM_SHOW_CHARSETS:
1238
case SQLCOM_SHOW_COLLATIONS:
1241
thd->status_var.last_query_cost= 0.0;
1242
res= execute_sqlcom_select(thd, all_tables);
1245
case SQLCOM_EMPTY_QUERY:
1251
res = purge_master_logs(thd, lex->to_log);
1254
case SQLCOM_PURGE_BEFORE:
1258
/* PURGE MASTER LOGS BEFORE 'data' */
1259
it= (Item *)lex->value_list.head();
1260
if ((!it->fixed && it->fix_fields(lex->thd, &it)) ||
1263
my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE LOGS BEFORE");
1266
it= new Item_func_unix_timestamp(it);
1268
it is OK only emulate fix_fieds, because we need only
1271
it->quick_fix_field();
1272
res = purge_master_logs_before_date(thd, (ulong)it->val_int());
1275
case SQLCOM_SHOW_WARNS:
1277
res= mysqld_show_warnings(thd, (uint32_t)
1278
((1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_NOTE) |
1279
(1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_WARN) |
1280
(1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR)
1284
case SQLCOM_SHOW_ERRORS:
1286
res= mysqld_show_warnings(thd, (uint32_t)
1287
(1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR));
1290
case SQLCOM_SHOW_SLAVE_HOSTS:
1292
res = show_slave_hosts(thd);
1295
case SQLCOM_SHOW_BINLOG_EVENTS:
1297
res = mysql_show_binlog_events(thd);
1301
case SQLCOM_ASSIGN_TO_KEYCACHE:
1303
assert(first_table == all_tables && first_table != 0);
1304
res= mysql_assign_to_keycache(thd, first_table, &lex->ident);
1307
case SQLCOM_CHANGE_MASTER:
1309
pthread_mutex_lock(&LOCK_active_mi);
1310
res = change_master(thd,active_mi);
1311
pthread_mutex_unlock(&LOCK_active_mi);
1314
case SQLCOM_SHOW_SLAVE_STAT:
1316
pthread_mutex_lock(&LOCK_active_mi);
1317
if (active_mi != NULL)
1319
res = show_master_info(thd, active_mi);
1323
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1324
"the master info structure does not exist");
1327
pthread_mutex_unlock(&LOCK_active_mi);
1330
case SQLCOM_SHOW_MASTER_STAT:
1332
res = show_binlog_info(thd);
1336
case SQLCOM_SHOW_ENGINE_STATUS:
1338
res = ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_STATUS);
1341
case SQLCOM_CREATE_TABLE:
1343
/* If CREATE TABLE of non-temporary table, do implicit commit */
1344
if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE))
1346
if (end_active_trans(thd))
1352
assert(first_table == all_tables && first_table != 0);
1354
// Skip first table, which is the table we are creating
1355
TableList *create_table= lex->unlink_first_table(&link_to_local);
1356
TableList *select_tables= lex->query_tables;
1358
Code below (especially in mysql_create_table() and select_create
1359
methods) may modify HA_CREATE_INFO structure in LEX, so we have to
1360
use a copy of this structure to make execution prepared statement-
1361
safe. A shallow copy is enough as this code won't modify any memory
1362
referenced from this structure.
1364
HA_CREATE_INFO create_info(lex->create_info);
1366
We need to copy alter_info for the same reasons of re-execution
1367
safety, only in case of Alter_info we have to do (almost) a deep
1370
Alter_info alter_info(lex->alter_info, thd->mem_root);
1372
if (thd->is_fatal_error)
1374
/* If out of memory when creating a copy of alter_info. */
1376
goto end_with_restore_list;
1379
if ((res= create_table_precheck(thd, select_tables, create_table)))
1380
goto end_with_restore_list;
1382
/* Might have been updated in create_table_precheck */
1383
create_info.alias= create_table->alias;
1385
#ifdef HAVE_READLINK
1386
/* Fix names if symlinked tables */
1387
if (append_file_to_dir(thd, &create_info.data_file_name,
1388
create_table->table_name) ||
1389
append_file_to_dir(thd, &create_info.index_file_name,
1390
create_table->table_name))
1391
goto end_with_restore_list;
1394
If we are using SET CHARSET without DEFAULT, add an implicit
1395
DEFAULT to not confuse old users. (This may change).
1397
if ((create_info.used_fields &
1398
(HA_CREATE_USED_DEFAULT_CHARSET | HA_CREATE_USED_CHARSET)) ==
1399
HA_CREATE_USED_CHARSET)
1401
create_info.used_fields&= ~HA_CREATE_USED_CHARSET;
1402
create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
1403
create_info.default_table_charset= create_info.table_charset;
1404
create_info.table_charset= 0;
1407
The create-select command will open and read-lock the select table
1408
and then create, open and write-lock the new table. If a global
1409
read lock steps in, we get a deadlock. The write lock waits for
1410
the global read lock, while the global read lock waits for the
1411
select table to be closed. So we wait until the global readlock is
1412
gone before starting both steps. Note that
1413
wait_if_global_read_lock() sets a protection against a new global
1414
read lock when it succeeds. This needs to be released by
1415
start_waiting_global_read_lock(). We protect the normal CREATE
1416
TABLE in the same way. That way we avoid that a new table is
1417
created during a gobal read lock.
1419
if (!thd->locked_tables &&
1420
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
1423
goto end_with_restore_list;
1425
if (select_lex->item_list.elements) // With select
1427
select_result *result;
1429
select_lex->options|= SELECT_NO_UNLOCK;
1430
unit->set_limit(select_lex);
1432
if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
1434
lex->link_first_table_back(create_table, link_to_local);
1435
create_table->create= true;
1438
if (!(res= open_and_lock_tables(thd, lex->query_tables)))
1441
Is table which we are changing used somewhere in other parts
1444
if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
1446
TableList *duplicate;
1447
create_table= lex->unlink_first_table(&link_to_local);
1448
if ((duplicate= unique_table(thd, create_table, select_tables, 0)))
1450
update_non_unique_table_error(create_table, "CREATE", duplicate);
1452
goto end_with_restore_list;
1457
select_create is currently not re-execution friendly and
1458
needs to be created for every execution of a PS/SP.
1460
if ((result= new select_create(create_table,
1463
select_lex->item_list,
1469
CREATE from SELECT give its SELECT_LEX for SELECT,
1470
and item_list belong to SELECT
1472
res= handle_select(thd, lex, result, 0);
1476
else if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
1477
create_table= lex->unlink_first_table(&link_to_local);
1482
/* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
1483
if (create_info.options & HA_LEX_CREATE_TMP_TABLE)
1484
thd->options|= OPTION_KEEP_LOG;
1485
/* regular create */
1486
if (create_info.options & HA_LEX_CREATE_TABLE_LIKE)
1487
res= mysql_create_like_table(thd, create_table, select_tables,
1491
res= mysql_create_table(thd, create_table->db,
1492
create_table->table_name, &create_info,
1499
/* put tables back for PS rexecuting */
1500
end_with_restore_list:
1501
lex->link_first_table_back(create_table, link_to_local);
1504
case SQLCOM_CREATE_INDEX:
1506
case SQLCOM_DROP_INDEX:
1508
CREATE INDEX and DROP INDEX are implemented by calling ALTER
1509
TABLE with proper arguments.
1511
In the future ALTER TABLE will notice that the request is to
1512
only add indexes and create these one by one for the existing
1513
table without having to do a full rebuild.
1516
/* Prepare stack copies to be re-execution safe */
1517
HA_CREATE_INFO create_info;
1518
Alter_info alter_info(lex->alter_info, thd->mem_root);
1520
if (thd->is_fatal_error) /* out of memory creating a copy of alter_info */
1523
assert(first_table == all_tables && first_table != 0);
1524
if (end_active_trans(thd))
1527
Currently CREATE INDEX or DROP INDEX cause a full table rebuild
1528
and thus classify as slow administrative statements just like
1531
thd->enable_slow_log= opt_log_slow_admin_statements;
1533
memset(&create_info, 0, sizeof(create_info));
1534
create_info.db_type= 0;
1535
create_info.row_type= ROW_TYPE_NOT_USED;
1536
create_info.default_table_charset= thd->variables.collation_database;
1538
res= mysql_alter_table(thd, first_table->db, first_table->table_name,
1539
&create_info, first_table, &alter_info,
1540
0, (order_st*) 0, 0);
1543
case SQLCOM_SLAVE_START:
1545
pthread_mutex_lock(&LOCK_active_mi);
1546
start_slave(thd,active_mi,1 /* net report*/);
1547
pthread_mutex_unlock(&LOCK_active_mi);
1550
case SQLCOM_SLAVE_STOP:
1552
If the client thread has locked tables, a deadlock is possible.
1554
- the client thread does LOCK TABLE t READ.
1555
- then the master updates t.
1556
- then the SQL slave thread wants to update t,
1557
so it waits for the client thread because t is locked by it.
1558
- then the client thread does SLAVE STOP.
1559
SLAVE STOP waits for the SQL slave thread to terminate its
1560
update t, which waits for the client thread because t is locked by it.
1561
To prevent that, refuse SLAVE STOP if the
1562
client thread has locked tables
1564
if (thd->locked_tables || thd->active_transaction() || thd->global_read_lock)
1566
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
1567
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
1571
pthread_mutex_lock(&LOCK_active_mi);
1572
stop_slave(thd,active_mi,1/* net report*/);
1573
pthread_mutex_unlock(&LOCK_active_mi);
1577
case SQLCOM_ALTER_TABLE:
1578
assert(first_table == all_tables && first_table != 0);
1581
Code in mysql_alter_table() may modify its HA_CREATE_INFO argument,
1582
so we have to use a copy of this structure to make execution
1583
prepared statement- safe. A shallow copy is enough as no memory
1584
referenced from this structure will be modified.
1586
HA_CREATE_INFO create_info(lex->create_info);
1587
Alter_info alter_info(lex->alter_info, thd->mem_root);
1589
if (thd->is_fatal_error) /* out of memory creating a copy of alter_info */
1594
/* Must be set in the parser */
1595
assert(select_lex->db);
1597
{ // Rename of table
1598
TableList tmp_table;
1599
memset(&tmp_table, 0, sizeof(tmp_table));
1600
tmp_table.table_name= lex->name.str;
1601
tmp_table.db=select_lex->db;
1604
/* Don't yet allow changing of symlinks with ALTER TABLE */
1605
if (create_info.data_file_name)
1606
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1607
"DATA DIRECTORY option ignored");
1608
if (create_info.index_file_name)
1609
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1610
"INDEX DIRECTORY option ignored");
1611
create_info.data_file_name= create_info.index_file_name= NULL;
1612
/* ALTER TABLE ends previous transaction */
1613
if (end_active_trans(thd))
1616
if (!thd->locked_tables &&
1617
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
1623
thd->enable_slow_log= opt_log_slow_admin_statements;
1624
res= mysql_alter_table(thd, select_lex->db, lex->name.str,
1628
select_lex->order_list.elements,
1629
(order_st *) select_lex->order_list.first,
1633
case SQLCOM_RENAME_TABLE:
1635
assert(first_table == all_tables && first_table != 0);
1637
for (table= first_table; table; table= table->next_local->next_local)
1639
TableList old_list, new_list;
1641
we do not need initialize old_list and new_list because we will
1642
come table[0] and table->next[0] there
1645
new_list= table->next_local[0];
1648
if (end_active_trans(thd) || mysql_rename_tables(thd, first_table, 0))
1654
case SQLCOM_SHOW_BINLOGS:
1656
res = show_binlogs(thd);
1659
case SQLCOM_SHOW_CREATE:
1660
assert(first_table == all_tables && first_table != 0);
1662
res= mysqld_show_create(thd, first_table);
1665
case SQLCOM_CHECKSUM:
1667
assert(first_table == all_tables && first_table != 0);
1668
res = mysql_checksum_table(thd, first_table, &lex->check_opt);
1673
assert(first_table == all_tables && first_table != 0);
1674
thd->enable_slow_log= opt_log_slow_admin_statements;
1675
res= mysql_repair_table(thd, first_table, &lex->check_opt);
1676
/* ! we write after unlocking the table */
1678
Presumably, REPAIR and binlog writing doesn't require synchronization
1680
write_bin_log(thd, true, thd->query, thd->query_length);
1681
select_lex->table_list.first= (unsigned char*) first_table;
1682
lex->query_tables=all_tables;
1687
assert(first_table == all_tables && first_table != 0);
1688
thd->enable_slow_log= opt_log_slow_admin_statements;
1689
res = mysql_check_table(thd, first_table, &lex->check_opt);
1690
select_lex->table_list.first= (unsigned char*) first_table;
1691
lex->query_tables=all_tables;
1694
case SQLCOM_ANALYZE:
1696
assert(first_table == all_tables && first_table != 0);
1697
thd->enable_slow_log= opt_log_slow_admin_statements;
1698
res= mysql_analyze_table(thd, first_table, &lex->check_opt);
1699
/* ! we write after unlocking the table */
1700
write_bin_log(thd, true, thd->query, thd->query_length);
1701
select_lex->table_list.first= (unsigned char*) first_table;
1702
lex->query_tables=all_tables;
1706
case SQLCOM_OPTIMIZE:
1708
assert(first_table == all_tables && first_table != 0);
1709
thd->enable_slow_log= opt_log_slow_admin_statements;
1710
res= mysql_optimize_table(thd, first_table, &lex->check_opt);
1711
/* ! we write after unlocking the table */
1712
write_bin_log(thd, true, thd->query, thd->query_length);
1713
select_lex->table_list.first= (unsigned char*) first_table;
1714
lex->query_tables=all_tables;
1718
assert(first_table == all_tables && first_table != 0);
1719
if (update_precheck(thd, all_tables))
1721
assert(select_lex->offset_limit == 0);
1722
unit->set_limit(select_lex);
1723
res= (up_result= mysql_update(thd, all_tables,
1724
select_lex->item_list,
1727
select_lex->order_list.elements,
1728
(order_st *) select_lex->order_list.first,
1729
unit->select_limit_cnt,
1730
lex->duplicates, lex->ignore));
1731
/* mysql_update return 2 if we need to switch to multi-update */
1735
case SQLCOM_UPDATE_MULTI:
1737
assert(first_table == all_tables && first_table != 0);
1738
/* if we switched from normal update, rights are checked */
1741
if ((res= multi_update_precheck(thd, all_tables)))
1747
res= mysql_multi_update_prepare(thd);
1749
/* Check slave filtering rules */
1750
if (unlikely(thd->slave_thread))
1752
if (all_tables_not_ok(thd, all_tables))
1756
res= 0; /* don't care of prev failure */
1757
thd->clear_error(); /* filters are of highest prior */
1759
/* we warn the slave SQL thread */
1760
my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
1771
some_non_temp_table_to_be_updated(thd, all_tables))
1773
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
1778
res= mysql_multi_update(thd, all_tables,
1779
&select_lex->item_list,
1782
select_lex->options,
1783
lex->duplicates, lex->ignore, unit, select_lex);
1786
case SQLCOM_REPLACE:
1789
assert(first_table == all_tables && first_table != 0);
1790
if ((res= insert_precheck(thd, all_tables)))
1793
if (!thd->locked_tables &&
1794
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
1800
res= mysql_insert(thd, all_tables, lex->field_list, lex->many_values,
1801
lex->update_list, lex->value_list,
1802
lex->duplicates, lex->ignore);
1806
case SQLCOM_REPLACE_SELECT:
1807
case SQLCOM_INSERT_SELECT:
1809
select_result *sel_result;
1810
assert(first_table == all_tables && first_table != 0);
1811
if ((res= insert_precheck(thd, all_tables)))
1814
/* Fix lock for first table */
1815
if (first_table->lock_type == TL_WRITE_DELAYED)
1816
first_table->lock_type= TL_WRITE;
1818
/* Don't unlock tables until command is written to binary log */
1819
select_lex->options|= SELECT_NO_UNLOCK;
1821
unit->set_limit(select_lex);
1823
if (! thd->locked_tables &&
1824
! (need_start_waiting= ! wait_if_global_read_lock(thd, 0, 1)))
1830
if (!(res= open_and_lock_tables(thd, all_tables)))
1832
/* Skip first table, which is the table we are inserting in */
1833
TableList *second_table= first_table->next_local;
1834
select_lex->table_list.first= (unsigned char*) second_table;
1835
select_lex->context.table_list=
1836
select_lex->context.first_name_resolution_table= second_table;
1837
res= mysql_insert_select_prepare(thd);
1838
if (!res && (sel_result= new select_insert(first_table,
1846
res= handle_select(thd, lex, sel_result, OPTION_SETUP_TABLES_DONE);
1848
Invalidate the table in the query cache if something changed
1849
after unlocking when changes become visible.
1850
TODO: this is workaround. right way will be move invalidating in
1851
the unlock procedure.
1853
if (first_table->lock_type == TL_WRITE_CONCURRENT_INSERT &&
1856
/* INSERT ... SELECT should invalidate only the very first table */
1857
TableList *save_table= first_table->next_local;
1858
first_table->next_local= 0;
1859
first_table->next_local= save_table;
1863
/* revert changes for SP */
1864
select_lex->table_list.first= (unsigned char*) first_table;
1869
case SQLCOM_TRUNCATE:
1870
if (end_active_trans(thd))
1875
assert(first_table == all_tables && first_table != 0);
1877
Don't allow this within a transaction because we want to use
1880
if (thd->locked_tables || thd->active_transaction())
1882
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
1883
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
1887
res= mysql_truncate(thd, first_table, 0);
1892
assert(first_table == all_tables && first_table != 0);
1893
assert(select_lex->offset_limit == 0);
1894
unit->set_limit(select_lex);
1896
if (!thd->locked_tables &&
1897
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
1903
res = mysql_delete(thd, all_tables, select_lex->where,
1904
&select_lex->order_list,
1905
unit->select_limit_cnt, select_lex->options,
1909
case SQLCOM_DELETE_MULTI:
1911
assert(first_table == all_tables && first_table != 0);
1912
TableList *aux_tables=
1913
(TableList *)thd->lex->auxiliary_table_list.first;
1914
multi_delete *del_result;
1916
if (!thd->locked_tables &&
1917
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
1923
if ((res= multi_delete_precheck(thd, all_tables)))
1926
/* condition will be true on SP re-excuting */
1927
if (select_lex->item_list.elements != 0)
1928
select_lex->item_list.empty();
1929
if (add_item_to_list(thd, new Item_null()))
1932
thd_proc_info(thd, "init");
1933
if ((res= open_and_lock_tables(thd, all_tables)))
1936
if ((res= mysql_multi_delete_prepare(thd)))
1939
if (!thd->is_fatal_error &&
1940
(del_result= new multi_delete(aux_tables, lex->table_count)))
1942
res= mysql_select(thd, &select_lex->ref_pointer_array,
1943
select_lex->get_table_list(),
1944
select_lex->with_wild,
1945
select_lex->item_list,
1947
0, (order_st *)NULL, (order_st *)NULL, (Item *)NULL,
1949
select_lex->options | thd->options |
1950
SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
1951
OPTION_SETUP_TABLES_DONE,
1952
del_result, unit, select_lex);
1953
res|= thd->is_error();
1955
del_result->abort();
1962
case SQLCOM_DROP_TABLE:
1964
assert(first_table == all_tables && first_table != 0);
1965
if (!lex->drop_temporary)
1967
if (end_active_trans(thd))
1973
If this is a slave thread, we may sometimes execute some
1974
DROP / * 40005 TEMPORARY * / TABLE
1975
that come from parts of binlogs (likely if we use RESET SLAVE or CHANGE
1976
MASTER TO), while the temporary table has already been dropped.
1977
To not generate such irrelevant "table does not exist errors",
1978
we silently add IF EXISTS if TEMPORARY was used.
1980
if (thd->slave_thread)
1981
lex->drop_if_exists= 1;
1983
/* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
1984
thd->options|= OPTION_KEEP_LOG;
1986
/* DDL and binlog write order protected by LOCK_open */
1987
res= mysql_rm_table(thd, first_table, lex->drop_if_exists, lex->drop_temporary);
1990
case SQLCOM_SHOW_PROCESSLIST:
1991
mysqld_list_processes(thd, NULL, lex->verbose);
1993
case SQLCOM_SHOW_ENGINE_LOGS:
1995
res= ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_LOGS);
1998
case SQLCOM_CHANGE_DB:
2000
LEX_STRING db_str= { (char *) select_lex->db, strlen(select_lex->db) };
2002
if (!mysql_change_db(thd, &db_str, false))
2010
assert(first_table == all_tables && first_table != 0);
2011
if (lex->local_file)
2013
if (!(thd->client_capabilities & CLIENT_LOCAL_FILES) ||
2016
my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), MYF(0));
2021
res= mysql_load(thd, lex->exchange, first_table, lex->field_list,
2022
lex->update_list, lex->value_list, lex->duplicates,
2023
lex->ignore, (bool) lex->local_file);
2027
case SQLCOM_SET_OPTION:
2029
List<set_var_base> *lex_var_list= &lex->var_list;
2031
if (lex->autocommit && end_active_trans(thd))
2034
if (open_and_lock_tables(thd, all_tables))
2036
if (lex->one_shot_set && not_all_support_one_shot(lex_var_list))
2038
my_error(ER_RESERVED_SYNTAX, MYF(0), "SET ONE_SHOT");
2041
if (!(res= sql_set_variables(thd, lex_var_list)))
2044
If the previous command was a SET ONE_SHOT, we don't want to forget
2045
about the ONE_SHOT property of that SET. So we use a |= instead of = .
2047
thd->one_shot_set|= lex->one_shot_set;
2053
We encountered some sort of error, but no message was sent.
2054
Send something semi-generic here since we don't know which
2055
assignment in the list caused the error.
2057
if (!thd->is_error())
2058
my_error(ER_WRONG_ARGUMENTS,MYF(0),"SET");
2065
case SQLCOM_UNLOCK_TABLES:
2067
It is critical for mysqldump --single-transaction --master-data that
2068
UNLOCK TABLES does not implicitely commit a connection which has only
2069
done FLUSH TABLES WITH READ LOCK + BEGIN. If this assumption becomes
2070
false, mysqldump will not work.
2072
unlock_locked_tables(thd);
2073
if (thd->options & OPTION_TABLE_LOCK)
2075
end_active_trans(thd);
2076
thd->options&= ~(OPTION_TABLE_LOCK);
2078
if (thd->global_read_lock)
2079
unlock_global_read_lock(thd);
2082
case SQLCOM_LOCK_TABLES:
2084
We try to take transactional locks if
2085
- only transactional locks are requested (lex->lock_transactional) and
2086
- no non-transactional locks exist (!thd->locked_tables).
2088
if (lex->lock_transactional && !thd->locked_tables)
2092
All requested locks are transactional and no non-transactional
2095
if ((rc= try_transactional_lock(thd, all_tables)) == -1)
2103
Non-transactional locking has been requested or
2104
non-transactional locks exist already or transactional locks are
2105
not supported by all storage engines. Take non-transactional
2110
One or more requested locks are non-transactional and/or
2111
non-transactional locks exist or a storage engine does not support
2112
transactional locks. Check if at least one transactional lock is
2113
requested. If yes, warn about the conversion to non-transactional
2114
locks or abort in strict mode.
2116
if (check_transactional_lock(thd, all_tables))
2118
unlock_locked_tables(thd);
2119
/* we must end the trasaction first, regardless of anything */
2120
if (end_active_trans(thd))
2122
thd->in_lock_tables=1;
2123
thd->options|= OPTION_TABLE_LOCK;
2125
if (!(res= simple_open_n_lock_tables(thd, all_tables)))
2127
thd->locked_tables=thd->lock;
2129
(void) set_handler_table_locks(thd, all_tables, false);
2135
Need to end the current transaction, so the storage engine (InnoDB)
2136
can free its locks if LOCK TABLES locked some tables before finding
2137
that it can't lock a table in its list
2139
ha_autocommit_or_rollback(thd, 1);
2140
end_active_trans(thd);
2141
thd->options&= ~(OPTION_TABLE_LOCK);
2143
thd->in_lock_tables=0;
2145
case SQLCOM_CREATE_DB:
2148
As mysql_create_db() may modify HA_CREATE_INFO structure passed to
2149
it, we need to use a copy of LEX::create_info to make execution
2150
prepared statement- safe.
2152
HA_CREATE_INFO create_info(lex->create_info);
2153
if (end_active_trans(thd))
2159
if (!(alias=thd->strmake(lex->name.str, lex->name.length)) ||
2160
check_db_name(&lex->name))
2162
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
2166
If in a slave thread :
2167
CREATE DATABASE DB was certainly not preceded by USE DB.
2168
For that reason, db_ok() in sql/slave.cc did not check the
2169
do_db/ignore_db. And as this query involves no tables, tables_ok()
2170
above was not called. So we have to check rules again here.
2172
if (thd->slave_thread &&
2173
(!rpl_filter->db_ok(lex->name.str) ||
2174
!rpl_filter->db_ok_with_wild_table(lex->name.str)))
2176
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
2179
res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias :
2180
lex->name.str), &create_info, 0);
2183
case SQLCOM_DROP_DB:
2185
if (end_active_trans(thd))
2190
if (check_db_name(&lex->name))
2192
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
2196
If in a slave thread :
2197
DROP DATABASE DB may not be preceded by USE DB.
2198
For that reason, maybe db_ok() in sql/slave.cc did not check the
2199
do_db/ignore_db. And as this query involves no tables, tables_ok()
2200
above was not called. So we have to check rules again here.
2202
if (thd->slave_thread &&
2203
(!rpl_filter->db_ok(lex->name.str) ||
2204
!rpl_filter->db_ok_with_wild_table(lex->name.str)))
2206
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
2209
if (thd->locked_tables || thd->active_transaction())
2211
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
2212
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
2215
res= mysql_rm_db(thd, lex->name.str, lex->drop_if_exists, 0);
2218
case SQLCOM_ALTER_DB:
2220
LEX_STRING *db= &lex->name;
2221
HA_CREATE_INFO create_info(lex->create_info);
2222
if (check_db_name(db))
2224
my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
2228
If in a slave thread :
2229
ALTER DATABASE DB may not be preceded by USE DB.
2230
For that reason, maybe db_ok() in sql/slave.cc did not check the
2231
do_db/ignore_db. And as this query involves no tables, tables_ok()
2232
above was not called. So we have to check rules again here.
2234
if (thd->slave_thread &&
2235
(!rpl_filter->db_ok(db->str) ||
2236
!rpl_filter->db_ok_with_wild_table(db->str)))
2238
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
2241
if (thd->locked_tables || thd->active_transaction())
2243
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
2244
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
2247
res= mysql_alter_db(thd, db->str, &create_info);
2250
case SQLCOM_SHOW_CREATE_DB:
2252
if (check_db_name(&lex->name))
2254
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
2257
res= mysqld_show_create_db(thd, lex->name.str, &lex->create_info);
2263
bool write_to_binlog;
2266
reload_cache() will tell us if we are allowed to write to the
2269
if (!reload_cache(thd, lex->type, first_table, &write_to_binlog))
2272
We WANT to write and we CAN write.
2273
! we write after unlocking the table.
2276
Presumably, RESET and binlog writing doesn't require synchronization
2278
write_bin_log(thd, false, thd->query, thd->query_length);
2286
Item *it= (Item *)lex->value_list.head();
2288
if (lex->table_or_sp_used())
2290
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "Usage of subqueries or stored "
2291
"function calls as part of this statement");
2295
if ((!it->fixed && it->fix_fields(lex->thd, &it)) || it->check_cols(1))
2297
my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
2301
sql_kill(thd, (ulong)it->val_int(), lex->type & ONLY_KILL_QUERY);
2305
if (thd->transaction.xid_state.xa_state != XA_NOTR)
2307
my_error(ER_XAER_RMFAIL, MYF(0),
2308
xa_state_names[thd->transaction.xid_state.xa_state]);
2312
Breakpoints for backup testing.
2314
if (begin_trans(thd))
2319
if (end_trans(thd, lex->tx_release ? COMMIT_RELEASE :
2320
lex->tx_chain ? COMMIT_AND_CHAIN : COMMIT))
2324
case SQLCOM_ROLLBACK:
2325
if (end_trans(thd, lex->tx_release ? ROLLBACK_RELEASE :
2326
lex->tx_chain ? ROLLBACK_AND_CHAIN : ROLLBACK))
2330
case SQLCOM_RELEASE_SAVEPOINT:
2333
for (sv=thd->transaction.savepoints; sv; sv=sv->prev)
2335
if (my_strnncoll(system_charset_info,
2336
(unsigned char *)lex->ident.str, lex->ident.length,
2337
(unsigned char *)sv->name, sv->length) == 0)
2342
if (ha_release_savepoint(thd, sv))
2343
res= true; // cannot happen
2346
thd->transaction.savepoints=sv->prev;
2349
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
2352
case SQLCOM_ROLLBACK_TO_SAVEPOINT:
2355
for (sv=thd->transaction.savepoints; sv; sv=sv->prev)
2357
if (my_strnncoll(system_charset_info,
2358
(unsigned char *)lex->ident.str, lex->ident.length,
2359
(unsigned char *)sv->name, sv->length) == 0)
2364
if (ha_rollback_to_savepoint(thd, sv))
2365
res= true; // cannot happen
2368
if (((thd->options & OPTION_KEEP_LOG) ||
2369
thd->transaction.all.modified_non_trans_table) &&
2371
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2372
ER_WARNING_NOT_COMPLETE_ROLLBACK,
2373
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
2376
thd->transaction.savepoints=sv;
2379
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
2382
case SQLCOM_SAVEPOINT:
2383
if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) ||
2384
thd->in_sub_stmt) || !opt_using_transactions)
2388
SAVEPOINT **sv, *newsv;
2389
for (sv=&thd->transaction.savepoints; *sv; sv=&(*sv)->prev)
2391
if (my_strnncoll(system_charset_info,
2392
(unsigned char *)lex->ident.str, lex->ident.length,
2393
(unsigned char *)(*sv)->name, (*sv)->length) == 0)
2396
if (*sv) /* old savepoint of the same name exists */
2399
ha_release_savepoint(thd, *sv); // it cannot fail
2402
else if ((newsv=(SAVEPOINT *) alloc_root(&thd->transaction.mem_root,
2403
savepoint_alloc_size)) == 0)
2405
my_error(ER_OUT_OF_RESOURCES, MYF(0));
2408
newsv->name=strmake_root(&thd->transaction.mem_root,
2409
lex->ident.str, lex->ident.length);
2410
newsv->length=lex->ident.length;
2412
if we'll get an error here, don't add new savepoint to the list.
2413
we'll lose a little bit of memory in transaction mem_root, but it'll
2414
be free'd when transaction ends anyway
2416
if (ha_savepoint(thd, newsv))
2420
newsv->prev=thd->transaction.savepoints;
2421
thd->transaction.savepoints=newsv;
2426
case SQLCOM_BINLOG_BASE64_EVENT:
2428
mysql_client_binlog_statement(thd);
2432
assert(0); /* Impossible */
2436
thd_proc_info(thd, "query end");
2439
Binlog-related cleanup:
2440
Reset system variables temporarily modified by SET ONE SHOT.
2442
Exception: If this is a SET, do nothing. This is to allow
2443
mysqlbinlog to print many SET commands (in this case we want the
2444
charset temp setting to live until the real query). This is also
2445
needed so that SET CHARACTER_SET_CLIENT... does not cancel itself
2448
if (thd->one_shot_set && lex->sql_command != SQLCOM_SET_OPTION)
2449
reset_one_shot_variables(thd);
486
2452
The return value for ROW_COUNT() is "implementation dependent" if the