138
178
sql_command_flags[SQLCOM_DROP_INDEX]= CF_CHANGES_DATA;
140
180
sql_command_flags[SQLCOM_UPDATE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
181
sql_command_flags[SQLCOM_UPDATE_MULTI]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
141
182
sql_command_flags[SQLCOM_INSERT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
142
183
sql_command_flags[SQLCOM_INSERT_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
143
184
sql_command_flags[SQLCOM_DELETE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
185
sql_command_flags[SQLCOM_DELETE_MULTI]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
144
186
sql_command_flags[SQLCOM_REPLACE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
145
187
sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
189
sql_command_flags[SQLCOM_SHOW_STATUS]= CF_STATUS_COMMAND;
190
sql_command_flags[SQLCOM_SHOW_DATABASES]= CF_STATUS_COMMAND;
191
sql_command_flags[SQLCOM_SHOW_OPEN_TABLES]= CF_STATUS_COMMAND;
192
sql_command_flags[SQLCOM_SHOW_FIELDS]= CF_STATUS_COMMAND;
193
sql_command_flags[SQLCOM_SHOW_KEYS]= CF_STATUS_COMMAND;
194
sql_command_flags[SQLCOM_SHOW_VARIABLES]= CF_STATUS_COMMAND;
195
sql_command_flags[SQLCOM_SHOW_CHARSETS]= CF_STATUS_COMMAND;
196
sql_command_flags[SQLCOM_SHOW_COLLATIONS]= CF_STATUS_COMMAND;
197
sql_command_flags[SQLCOM_SHOW_BINLOGS]= CF_STATUS_COMMAND;
198
sql_command_flags[SQLCOM_SHOW_SLAVE_HOSTS]= CF_STATUS_COMMAND;
199
sql_command_flags[SQLCOM_SHOW_BINLOG_EVENTS]= CF_STATUS_COMMAND;
147
200
sql_command_flags[SQLCOM_SHOW_WARNS]= CF_STATUS_COMMAND;
148
201
sql_command_flags[SQLCOM_SHOW_ERRORS]= CF_STATUS_COMMAND;
202
sql_command_flags[SQLCOM_SHOW_ENGINE_STATUS]= CF_STATUS_COMMAND;
203
sql_command_flags[SQLCOM_SHOW_PROCESSLIST]= CF_STATUS_COMMAND;
149
204
sql_command_flags[SQLCOM_SHOW_CREATE_DB]= CF_STATUS_COMMAND;
150
205
sql_command_flags[SQLCOM_SHOW_CREATE]= CF_STATUS_COMMAND;
206
sql_command_flags[SQLCOM_SHOW_MASTER_STAT]= CF_STATUS_COMMAND;
207
sql_command_flags[SQLCOM_SHOW_SLAVE_STAT]= CF_STATUS_COMMAND;
209
sql_command_flags[SQLCOM_SHOW_TABLES]= (CF_STATUS_COMMAND |
210
CF_SHOW_TABLE_COMMAND);
211
sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]= (CF_STATUS_COMMAND |
212
CF_SHOW_TABLE_COMMAND);
153
214
The following admin table operations are allowed
217
sql_command_flags[SQLCOM_REPAIR]= CF_WRITE_LOGS_COMMAND;
218
sql_command_flags[SQLCOM_OPTIMIZE]= CF_WRITE_LOGS_COMMAND;
156
219
sql_command_flags[SQLCOM_ANALYZE]= CF_WRITE_LOGS_COMMAND;
223
bool is_update_query(enum enum_sql_command command)
225
assert(command >= 0 && command <= SQLCOM_END);
226
return (sql_command_flags[command] & CF_CHANGES_DATA) != 0;
229
void execute_init_command(THD *thd, sys_var_str *init_command_var,
230
rw_lock_t *var_mutex)
233
ulong save_client_capabilities;
235
thd_proc_info(thd, "Execution of init_command");
237
We need to lock init_command_var because
238
during execution of init_command_var query
239
values of init_command_var can't be changed
241
rw_rdlock(var_mutex);
242
save_client_capabilities= thd->client_capabilities;
243
thd->client_capabilities|= CLIENT_MULTI_STATEMENTS;
245
We don't need return result of execution to client side.
246
To forbid this we should set thd->net.vio to 0.
248
save_vio= thd->net.vio;
250
dispatch_command(COM_QUERY, thd,
251
init_command_var->value,
252
init_command_var->value_length);
253
rw_unlock(var_mutex);
254
thd->client_capabilities= save_client_capabilities;
255
thd->net.vio= save_vio;
259
Ends the current transaction and (maybe) begin the next.
261
@param thd Current thread
262
@param completion Completion type
268
int end_trans(THD *thd, enum enum_mysql_completiontype completion)
273
if (unlikely(thd->in_sub_stmt))
275
my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
278
if (thd->transaction.xid_state.xa_state != XA_NOTR)
280
my_error(ER_XAER_RMFAIL, MYF(0),
281
xa_state_names[thd->transaction.xid_state.xa_state]);
284
switch (completion) {
287
We don't use end_active_trans() here to ensure that this works
288
even if there is a problem with the OPTION_AUTO_COMMIT flag
289
(Which of course should never happen...)
291
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
293
thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
294
thd->transaction.all.modified_non_trans_table= false;
297
do_release= 1; /* fall through */
298
case COMMIT_AND_CHAIN:
299
res= end_active_trans(thd);
300
if (!res && completion == COMMIT_AND_CHAIN)
301
res= begin_trans(thd);
303
case ROLLBACK_RELEASE:
304
do_release= 1; /* fall through */
306
case ROLLBACK_AND_CHAIN:
308
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
309
if (ha_rollback(thd))
311
thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
312
thd->transaction.all.modified_non_trans_table= false;
313
if (!res && (completion == ROLLBACK_AND_CHAIN))
314
res= begin_trans(thd);
319
my_error(ER_UNKNOWN_COM_ERROR, MYF(0));
324
my_error(thd->killed_errno(), MYF(0));
325
else if ((res == 0) && do_release)
326
thd->killed= THD::KILL_CONNECTION;
333
Read one command from connection and execute it (query or simple command).
334
This function is called in loop from thread function.
336
For profiling to work, it must never be called recursively.
341
1 request of thread shutdown (see dispatch_command() description)
344
bool do_command(THD *thd)
350
enum enum_server_command command;
353
indicator of uninitialized lex => normal flow of errors handling
356
thd->lex->current_select= 0;
359
This thread will do a blocking read from the client which
360
will be interrupted when the next command is received from
361
the client, the connection is closed or "net_wait_timeout"
362
number of seconds has passed
364
my_net_set_read_timeout(net, thd->variables.net_wait_timeout);
367
XXX: this code is here only to clear possible errors of init_connect.
368
Consider moving to init_connect() instead.
370
thd->clear_error(); // Clear error message
371
thd->main_da.reset_diagnostics_area();
373
net_new_transaction(net);
375
packet_length= my_net_read(net);
376
if (packet_length == packet_error)
378
/* Check if we can continue without closing the connection */
380
/* The error must be set. */
381
assert(thd->is_error());
382
net_end_statement(thd);
386
return_value= true; // We have to close it.
395
packet= (char*) net->read_pos;
397
'packet_length' contains length of data, as it was stored in packet
398
header. In case of malformed header, my_net_read returns zero.
399
If packet_length is not zero, my_net_read ensures that the returned
400
number of bytes was actually read from network.
401
There is also an extra safety measure in my_net_read:
402
it sets packet[packet_length]= 0, but only for non-zero packets.
404
if (packet_length == 0) /* safety */
406
/* Initialize with COM_SLEEP packet */
407
packet[0]= (uchar) COM_SLEEP;
410
/* Do not rely on my_net_read, extra safety against programming errors. */
411
packet[packet_length]= '\0'; /* safety */
413
command= (enum enum_server_command) (uchar) packet[0];
415
if (command >= COM_END)
416
command= COM_END; // Wrong command
418
/* Restore read timeout value */
419
my_net_set_read_timeout(net, thd->variables.net_read_timeout);
421
assert(packet_length);
422
return_value= dispatch_command(command, thd, packet+1, (uint) (packet_length-1));
425
return(return_value);
429
Determine if an attempt to update a non-temporary table while the
430
read-only option was enabled has been made.
432
This is a helper function to mysql_execute_command.
434
@note SQLCOM_MULTI_UPDATE is an exception and dealt with elsewhere.
436
@see mysql_execute_command
439
@retval true The statement should be denied.
440
@retval false The statement isn't updating any relevant tables.
443
static bool deny_updates_if_read_only_option(THD *thd,
444
TABLE_LIST *all_tables)
451
if (!(sql_command_flags[lex->sql_command] & CF_CHANGES_DATA))
454
/* Multi update is an exception and is dealt with later. */
455
if (lex->sql_command == SQLCOM_UPDATE_MULTI)
458
const bool create_temp_tables=
459
(lex->sql_command == SQLCOM_CREATE_TABLE) &&
460
(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE);
462
const bool drop_temp_tables=
463
(lex->sql_command == SQLCOM_DROP_TABLE) &&
466
const bool update_real_tables=
467
some_non_temp_table_to_be_updated(thd, all_tables) &&
468
!(create_temp_tables || drop_temp_tables);
471
const bool create_or_drop_databases=
472
(lex->sql_command == SQLCOM_CREATE_DB) ||
473
(lex->sql_command == SQLCOM_DROP_DB);
475
if (update_real_tables || create_or_drop_databases)
478
An attempt was made to modify one or more non-temporary tables.
484
/* Assuming that only temporary tables are modified. */
160
489
Perform one connection-level (COM_XXXX) command.
162
491
@param command type of command to perform
163
@param session connection handle
492
@param thd connection handle
164
493
@param packet data for the command, packet is always null-terminated
165
494
@param packet_length length of packet + 1 (to show that data is
166
495
null-terminated) except for COM_SLEEP, where it
170
set session->lex->sql_command to SQLCOM_END here.
499
set thd->lex->sql_command to SQLCOM_END here.
172
501
The following has to be changed to an 8 byte integer
197
530
/* Increase id and count all other statements. */
199
session->status_var.questions++;
203
/* @todo set session->lex->sql_command to SQLCOM_END here */
205
plugin::Logging::preDo(session);
206
if (unlikely(plugin::EventObserver::beforeStatement(*session)))
208
// We should do something about an error...
211
session->server_status&=
532
statistic_increment(thd->status_var.questions, &LOCK_status);
537
/* TODO: set thd->lex->sql_command to SQLCOM_END here */
538
VOID(pthread_mutex_unlock(&LOCK_thread_count));
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(thd->status_var.com_stat[SQLCOM_CHANGE_DB]);
547
thd->convert_string(&tmp, system_charset_info,
548
packet, packet_length, thd->charset());
549
if (!mysql_change_db(thd, &tmp, false))
551
general_log_write(thd, command, thd->db, thd->db_length);
556
case COM_REGISTER_SLAVE:
558
if (!register_slave(thd, (uchar*)packet, packet_length))
562
case COM_CHANGE_USER:
564
status_var_increment(thd->status_var.com_other);
565
char *user= (char*) packet, *packet_end= packet + packet_length;
566
/* Safe because there is always a trailing \0 at the end of the packet */
567
char *passwd= strend(user)+1;
570
thd->clear_error(); // if errors from rollback
573
Old clients send null-terminated string ('\0' for empty string) for
574
password. New clients send the size (1 byte) + string (not null
575
terminated, so also '\0' for empty string).
577
Cast *passwd to an unsigned char, so that it doesn't extend the sign
578
for *passwd > 127 and become 2**32-127 after casting to uint.
580
char db_buff[NAME_LEN+1]; // buffer to store db in utf8
584
If there is no password supplied, the packet must contain '\0',
585
in any type of handshake (4.1 or pre-4.1).
587
if (passwd >= packet_end)
589
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
592
uint passwd_len= (thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
593
(uchar)(*passwd++) : strlen(passwd));
594
uint dummy_errors, save_db_length, db_length;
596
Security_context save_security_ctx= *thd->security_ctx;
597
USER_CONN *save_user_connect;
601
Database name is always NUL-terminated, so in case of empty database
602
the packet must contain at least the trailing '\0'.
604
if (db >= packet_end)
606
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
609
db_length= strlen(db);
611
char *ptr= db + db_length + 1;
614
if (ptr < packet_end)
616
if (ptr + 2 > packet_end)
618
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
622
cs_number= uint2korr(ptr);
625
/* Convert database name to utf8 */
626
db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
627
system_charset_info, db, db_length,
628
thd->charset(), &dummy_errors)]= 0;
631
/* Save user and privileges */
632
save_db_length= thd->db_length;
634
save_user_connect= thd->user_connect;
636
if (!(thd->security_ctx->user= my_strdup(user, MYF(0))))
638
thd->security_ctx->user= save_security_ctx.user;
639
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
643
/* Clear variables that are allocated */
644
thd->user_connect= 0;
645
res= check_user(thd, COM_CHANGE_USER, passwd, passwd_len, db, false);
649
x_free(thd->security_ctx->user);
650
*thd->security_ctx= save_security_ctx;
651
thd->user_connect= save_user_connect;
653
thd->db_length= save_db_length;
658
x_free(save_security_ctx.user);
662
thd_init_client_charset(thd, cs_number);
663
thd->update_charset();
234
if (not session->readAndStoreQuery(packet, packet_length))
670
if (alloc_query(thd, packet, packet_length))
235
671
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());
672
char *packet_end= thd->query + thd->query_length;
673
const char* end_of_stmt= NULL;
675
general_log_write(thd, command, thd->query, thd->query_length);
677
mysql_parse(thd, thd->query, thd->query_length, &end_of_stmt);
679
while (!thd->killed && (end_of_stmt != NULL) && ! thd->is_error())
681
char *beginning_of_next_stmt= (char*) end_of_stmt;
683
net_end_statement(thd);
685
Multiple queries exits, execute them individually
687
close_thread_tables(thd);
688
ulong length= (ulong)(packet_end - beginning_of_next_stmt);
690
log_slow_statement(thd);
692
/* Remove garbage at start of query */
693
while (length > 0 && my_isspace(thd->charset(), *beginning_of_next_stmt))
695
beginning_of_next_stmt++;
699
VOID(pthread_mutex_lock(&LOCK_thread_count));
700
thd->query_length= length;
701
thd->query= beginning_of_next_stmt;
703
Count each statement from the client.
705
statistic_increment(thd->status_var.questions, &LOCK_status);
706
thd->query_id= next_query_id();
707
thd->set_time(); /* Reset the query start time. */
708
/* TODO: set thd->lex->sql_command to SQLCOM_END here */
709
VOID(pthread_mutex_unlock(&LOCK_thread_count));
711
mysql_parse(thd, beginning_of_next_stmt, length, &end_of_stmt);
715
case COM_FIELD_LIST: // This isn't actually needed
717
char *fields, *packet_end= packet + packet_length, *arg_end;
718
/* Locked closure of all tables */
719
TABLE_LIST table_list;
720
LEX_STRING conv_name;
722
/* used as fields initializator */
725
status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_FIELDS]);
726
memset(&table_list, 0, sizeof(table_list));
727
if (thd->copy_db_to(&table_list.db, &table_list.db_length))
730
We have name + wildcard in packet, separated by endzero
732
arg_end= strend(packet);
733
thd->convert_string(&conv_name, system_charset_info,
734
packet, (uint) (arg_end - packet), thd->charset());
735
table_list.alias= table_list.table_name= conv_name.str;
738
if (!my_strcasecmp(system_charset_info, table_list.db,
739
INFORMATION_SCHEMA_NAME.str))
741
ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, table_list.alias);
743
table_list.schema_table= schema_table;
746
thd->query_length= (uint) (packet_end - packet); // Don't count end \0
747
if (!(thd->query=fields= (char*) thd->memdup(packet,thd->query_length+1)))
749
general_log_print(thd, command, "%s %s", table_list.table_name, fields);
750
if (lower_case_table_names)
751
my_casedn_str(files_charset_info, table_list.table_name);
753
/* init structures for VIEW processing */
754
table_list.select_lex= &(thd->lex->select_lex);
757
mysql_reset_thd_for_next_command(thd);
760
select_lex.table_list.link_in_list((uchar*) &table_list,
761
(uchar**) &table_list.next_local);
762
thd->lex->add_to_query_tables(&table_list);
764
/* switch on VIEW optimisation: do not fill temporary tables */
765
thd->lex->sql_command= SQLCOM_SHOW_FIELDS;
766
mysqld_list_fields(thd,&table_list,fields);
767
thd->lex->unit.cleanup();
768
thd->cleanup_after_query();
245
772
/* We don't calculate statistics for this command */
246
session->main_da.disable_status(); // Don't send anything back
773
general_log_print(thd, command, NullS);
774
net->error=0; // Don't give 'abort' message
775
thd->main_da.disable_status(); // Don't send anything back
247
776
error=true; // End server
778
case COM_BINLOG_DUMP:
782
uint32_t slave_server_id;
784
status_var_increment(thd->status_var.com_other);
785
thd->enable_slow_log= opt_log_slow_admin_statements;
786
/* TODO: The following has to be changed to an 8 byte integer */
787
pos = uint4korr(packet);
788
flags = uint2korr(packet + 4);
789
thd->server_id=0; /* avoid suicide */
790
if ((slave_server_id= uint4korr(packet+6))) // mysqlbinlog.server_id==0
791
kill_zombie_dump_threads(slave_server_id);
792
thd->server_id = slave_server_id;
794
general_log_print(thd, command, "Log: '%s' Pos: %ld", packet+10,
796
mysql_binlog_send(thd, thd->strdup(packet + 10), (my_off_t) pos, flags);
797
unregister_slave(thd,1,1);
798
/* fake COM_QUIT -- if we get here, the thread needs to terminate */
249
802
case COM_SHUTDOWN:
251
session->status_var.com_other++;
253
session->close_thread_tables(); // Free before kill
804
status_var_increment(thd->status_var.com_other);
806
If the client is < 4.1.3, it is going to send us no argument; then
807
packet_length is 0, packet[0] is the end 0 of the packet. Note that
808
SHUTDOWN_DEFAULT is 0. If client is >= 4.1.3, the shutdown level is in
811
enum drizzle_enum_shutdown_level level=
812
(enum drizzle_enum_shutdown_level) (uchar) packet[0];
813
if (level == SHUTDOWN_DEFAULT)
814
level= SHUTDOWN_WAIT_ALL_BUFFERS; // soon default will be configurable
815
else if (level != SHUTDOWN_WAIT_ALL_BUFFERS)
817
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "this shutdown level");
820
general_log_print(thd, command, NullS);
822
close_thread_tables(thd); // Free before kill
259
session->status_var.com_other++;
260
session->my_ok(); // Tell client we are alive
828
status_var_increment(thd->status_var.com_other);
829
my_ok(thd); // Tell client we are alive
831
case COM_PROCESS_INFO:
832
status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_PROCESSLIST]);
833
general_log_print(thd, command, NullS);
834
mysqld_list_processes(thd, NullS, 0);
836
case COM_PROCESS_KILL:
838
status_var_increment(thd->status_var.com_stat[SQLCOM_KILL]);
839
ulong id=(ulong) uint4korr(packet);
840
sql_kill(thd,id,false);
845
status_var_increment(thd->status_var.com_stat[SQLCOM_SET_OPTION]);
846
uint opt_command= uint2korr(packet);
848
switch (opt_command) {
849
case (int) MYSQL_OPTION_MULTI_STATEMENTS_ON:
850
thd->client_capabilities|= CLIENT_MULTI_STATEMENTS;
853
case (int) MYSQL_OPTION_MULTI_STATEMENTS_OFF:
854
thd->client_capabilities&= ~CLIENT_MULTI_STATEMENTS;
858
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
263
864
case COM_CONNECT: // Impossible here
865
case COM_TIME: // Impossible from client
266
868
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
481
1183
variables, but for now this is probably good enough.
482
1184
Don't reset warnings when executing a stored routine.
484
if (all_tables || ! lex->is_single_level_stmt())
486
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();
504
session->set_proc_info("query end");
1186
if (all_tables || !lex->is_single_level_stmt())
1187
drizzle_reset_errors(thd, 0);
1189
if (unlikely(thd->slave_thread))
1192
Check if statment should be skipped because of slave filtering
1196
- UPDATE MULTI: For this statement, we want to check the filtering
1197
rules later in the code
1198
- SET: we always execute it (Not that many SET commands exists in
1199
the binary log anyway -- only 4.1 masters write SET statements,
1200
in 5.0 there are no SET statements in the binary log)
1201
- DROP TEMPORARY TABLE IF EXISTS: we always execute it (otherwise we
1202
have stale files on slave caused by exclusion of one tmp table).
1204
if (!(lex->sql_command == SQLCOM_UPDATE_MULTI) &&
1205
!(lex->sql_command == SQLCOM_SET_OPTION) &&
1206
!(lex->sql_command == SQLCOM_DROP_TABLE &&
1207
lex->drop_temporary && lex->drop_if_exists) &&
1208
all_tables_not_ok(thd, all_tables))
1210
/* we warn the slave SQL thread */
1211
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
1212
if (thd->one_shot_set)
1215
It's ok to check thd->one_shot_set here:
1217
The charsets in a MySQL 5.0 slave can change by both a binlogged
1218
SET ONE_SHOT statement and the event-internal charset setting,
1219
and these two ways to change charsets do not seems to work
1222
At least there seems to be problems in the rli cache for
1223
charsets if we are using ONE_SHOT. Note that this is normally no
1224
problem because either the >= 5.0 slave reads a 4.1 binlog (with
1225
ONE_SHOT) *or* or 5.0 binlog (without ONE_SHOT) but never both."
1227
reset_one_shot_variables(thd);
1235
When option readonly is set deny operations which change non-temporary
1236
tables. Except for the replication thread and the 'super' users.
1238
if (deny_updates_if_read_only_option(thd, all_tables))
1240
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
1243
} /* endif unlikely slave */
1244
status_var_increment(thd->status_var.com_stat[lex->sql_command]);
1246
assert(thd->transaction.stmt.modified_non_trans_table == false);
1248
switch (lex->sql_command) {
1249
case SQLCOM_SHOW_STATUS:
1251
system_status_var old_status_var= thd->status_var;
1252
thd->initial_status_var= &old_status_var;
1253
res= execute_sqlcom_select(thd, all_tables);
1254
/* Don't log SHOW STATUS commands to slow query log */
1255
thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED |
1256
SERVER_QUERY_NO_GOOD_INDEX_USED);
1258
restore status variables, as we don't want 'show status' to cause
1261
pthread_mutex_lock(&LOCK_status);
1262
add_diff_to_status(&global_status_var, &thd->status_var,
1264
thd->status_var= old_status_var;
1265
pthread_mutex_unlock(&LOCK_status);
1268
case SQLCOM_SHOW_DATABASES:
1269
case SQLCOM_SHOW_TABLES:
1270
case SQLCOM_SHOW_TABLE_STATUS:
1271
case SQLCOM_SHOW_OPEN_TABLES:
1272
case SQLCOM_SHOW_FIELDS:
1273
case SQLCOM_SHOW_KEYS:
1274
case SQLCOM_SHOW_VARIABLES:
1275
case SQLCOM_SHOW_CHARSETS:
1276
case SQLCOM_SHOW_COLLATIONS:
1279
thd->status_var.last_query_cost= 0.0;
1280
res= execute_sqlcom_select(thd, all_tables);
1283
case SQLCOM_EMPTY_QUERY:
1289
res = purge_master_logs(thd, lex->to_log);
1292
case SQLCOM_PURGE_BEFORE:
1296
/* PURGE MASTER LOGS BEFORE 'data' */
1297
it= (Item *)lex->value_list.head();
1298
if ((!it->fixed && it->fix_fields(lex->thd, &it)) ||
1301
my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE LOGS BEFORE");
1304
it= new Item_func_unix_timestamp(it);
1306
it is OK only emulate fix_fieds, because we need only
1309
it->quick_fix_field();
1310
res = purge_master_logs_before_date(thd, (ulong)it->val_int());
1313
case SQLCOM_SHOW_WARNS:
1315
res= mysqld_show_warnings(thd, (ulong)
1316
((1L << (uint) DRIZZLE_ERROR::WARN_LEVEL_NOTE) |
1317
(1L << (uint) DRIZZLE_ERROR::WARN_LEVEL_WARN) |
1318
(1L << (uint) DRIZZLE_ERROR::WARN_LEVEL_ERROR)
1322
case SQLCOM_SHOW_ERRORS:
1324
res= mysqld_show_warnings(thd, (ulong)
1325
(1L << (uint) DRIZZLE_ERROR::WARN_LEVEL_ERROR));
1328
case SQLCOM_SHOW_SLAVE_HOSTS:
1330
res = show_slave_hosts(thd);
1333
case SQLCOM_SHOW_BINLOG_EVENTS:
1335
res = mysql_show_binlog_events(thd);
1339
case SQLCOM_ASSIGN_TO_KEYCACHE:
1341
assert(first_table == all_tables && first_table != 0);
1342
res= mysql_assign_to_keycache(thd, first_table, &lex->ident);
1345
case SQLCOM_CHANGE_MASTER:
1347
pthread_mutex_lock(&LOCK_active_mi);
1348
res = change_master(thd,active_mi);
1349
pthread_mutex_unlock(&LOCK_active_mi);
1352
case SQLCOM_SHOW_SLAVE_STAT:
1354
pthread_mutex_lock(&LOCK_active_mi);
1355
if (active_mi != NULL)
1357
res = show_master_info(thd, active_mi);
1361
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1362
"the master info structure does not exist");
1365
pthread_mutex_unlock(&LOCK_active_mi);
1368
case SQLCOM_SHOW_MASTER_STAT:
1370
res = show_binlog_info(thd);
1374
case SQLCOM_SHOW_ENGINE_STATUS:
1376
res = ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_STATUS);
1379
case SQLCOM_CREATE_TABLE:
1381
/* If CREATE TABLE of non-temporary table, do implicit commit */
1382
if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE))
1384
if (end_active_trans(thd))
1390
assert(first_table == all_tables && first_table != 0);
1392
// Skip first table, which is the table we are creating
1393
TABLE_LIST *create_table= lex->unlink_first_table(&link_to_local);
1394
TABLE_LIST *select_tables= lex->query_tables;
1396
Code below (especially in mysql_create_table() and select_create
1397
methods) may modify HA_CREATE_INFO structure in LEX, so we have to
1398
use a copy of this structure to make execution prepared statement-
1399
safe. A shallow copy is enough as this code won't modify any memory
1400
referenced from this structure.
1402
HA_CREATE_INFO create_info(lex->create_info);
1404
We need to copy alter_info for the same reasons of re-execution
1405
safety, only in case of Alter_info we have to do (almost) a deep
1408
Alter_info alter_info(lex->alter_info, thd->mem_root);
1410
if (thd->is_fatal_error)
1412
/* If out of memory when creating a copy of alter_info. */
1414
goto end_with_restore_list;
1417
if ((res= create_table_precheck(thd, select_tables, create_table)))
1418
goto end_with_restore_list;
1420
/* Might have been updated in create_table_precheck */
1421
create_info.alias= create_table->alias;
1423
#ifdef HAVE_READLINK
1424
/* Fix names if symlinked tables */
1425
if (append_file_to_dir(thd, &create_info.data_file_name,
1426
create_table->table_name) ||
1427
append_file_to_dir(thd, &create_info.index_file_name,
1428
create_table->table_name))
1429
goto end_with_restore_list;
1432
If we are using SET CHARSET without DEFAULT, add an implicit
1433
DEFAULT to not confuse old users. (This may change).
1435
if ((create_info.used_fields &
1436
(HA_CREATE_USED_DEFAULT_CHARSET | HA_CREATE_USED_CHARSET)) ==
1437
HA_CREATE_USED_CHARSET)
1439
create_info.used_fields&= ~HA_CREATE_USED_CHARSET;
1440
create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
1441
create_info.default_table_charset= create_info.table_charset;
1442
create_info.table_charset= 0;
1445
The create-select command will open and read-lock the select table
1446
and then create, open and write-lock the new table. If a global
1447
read lock steps in, we get a deadlock. The write lock waits for
1448
the global read lock, while the global read lock waits for the
1449
select table to be closed. So we wait until the global readlock is
1450
gone before starting both steps. Note that
1451
wait_if_global_read_lock() sets a protection against a new global
1452
read lock when it succeeds. This needs to be released by
1453
start_waiting_global_read_lock(). We protect the normal CREATE
1454
TABLE in the same way. That way we avoid that a new table is
1455
created during a gobal read lock.
1457
if (!thd->locked_tables &&
1458
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
1461
goto end_with_restore_list;
1463
if (select_lex->item_list.elements) // With select
1465
select_result *result;
1467
select_lex->options|= SELECT_NO_UNLOCK;
1468
unit->set_limit(select_lex);
1471
Disable non-empty MERGE tables with CREATE...SELECT. Too
1472
complicated. See Bug #26379. Empty MERGE tables are read-only
1473
and don't allow CREATE...SELECT anyway.
1475
if (create_info.used_fields & HA_CREATE_USED_UNION)
1477
my_error(ER_WRONG_OBJECT, MYF(0), create_table->db,
1478
create_table->table_name, "BASE TABLE");
1480
goto end_with_restore_list;
1483
if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
1485
lex->link_first_table_back(create_table, link_to_local);
1486
create_table->create= true;
1489
if (!(res= open_and_lock_tables(thd, lex->query_tables)))
1492
Is table which we are changing used somewhere in other parts
1495
if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
1497
TABLE_LIST *duplicate;
1498
create_table= lex->unlink_first_table(&link_to_local);
1499
if ((duplicate= unique_table(thd, create_table, select_tables, 0)))
1501
update_non_unique_table_error(create_table, "CREATE", duplicate);
1503
goto end_with_restore_list;
1506
/* If we create merge table, we have to test tables in merge, too */
1507
if (create_info.used_fields & HA_CREATE_USED_UNION)
1510
for (tab= (TABLE_LIST*) create_info.merge_list.first;
1512
tab= tab->next_local)
1514
TABLE_LIST *duplicate;
1515
if ((duplicate= unique_table(thd, tab, select_tables, 0)))
1517
update_non_unique_table_error(tab, "CREATE", duplicate);
1519
goto end_with_restore_list;
1525
select_create is currently not re-execution friendly and
1526
needs to be created for every execution of a PS/SP.
1528
if ((result= new select_create(create_table,
1531
select_lex->item_list,
1537
CREATE from SELECT give its SELECT_LEX for SELECT,
1538
and item_list belong to SELECT
1540
res= handle_select(thd, lex, result, 0);
1544
else if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
1545
create_table= lex->unlink_first_table(&link_to_local);
1550
/* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
1551
if (create_info.options & HA_LEX_CREATE_TMP_TABLE)
1552
thd->options|= OPTION_KEEP_LOG;
1553
/* regular create */
1554
if (create_info.options & HA_LEX_CREATE_TABLE_LIKE)
1555
res= mysql_create_like_table(thd, create_table, select_tables,
1559
res= mysql_create_table(thd, create_table->db,
1560
create_table->table_name, &create_info,
1567
/* put tables back for PS rexecuting */
1568
end_with_restore_list:
1569
lex->link_first_table_back(create_table, link_to_local);
1572
case SQLCOM_CREATE_INDEX:
1574
case SQLCOM_DROP_INDEX:
1576
CREATE INDEX and DROP INDEX are implemented by calling ALTER
1577
TABLE with proper arguments.
1579
In the future ALTER TABLE will notice that the request is to
1580
only add indexes and create these one by one for the existing
1581
table without having to do a full rebuild.
1584
/* Prepare stack copies to be re-execution safe */
1585
HA_CREATE_INFO create_info;
1586
Alter_info alter_info(lex->alter_info, thd->mem_root);
1588
if (thd->is_fatal_error) /* out of memory creating a copy of alter_info */
1591
assert(first_table == all_tables && first_table != 0);
1592
if (end_active_trans(thd))
1595
Currently CREATE INDEX or DROP INDEX cause a full table rebuild
1596
and thus classify as slow administrative statements just like
1599
thd->enable_slow_log= opt_log_slow_admin_statements;
1601
memset(&create_info, 0, sizeof(create_info));
1602
create_info.db_type= 0;
1603
create_info.row_type= ROW_TYPE_NOT_USED;
1604
create_info.default_table_charset= thd->variables.collation_database;
1606
res= mysql_alter_table(thd, first_table->db, first_table->table_name,
1607
&create_info, first_table, &alter_info,
1611
case SQLCOM_SLAVE_START:
1613
pthread_mutex_lock(&LOCK_active_mi);
1614
start_slave(thd,active_mi,1 /* net report*/);
1615
pthread_mutex_unlock(&LOCK_active_mi);
1618
case SQLCOM_SLAVE_STOP:
1620
If the client thread has locked tables, a deadlock is possible.
1622
- the client thread does LOCK TABLE t READ.
1623
- then the master updates t.
1624
- then the SQL slave thread wants to update t,
1625
so it waits for the client thread because t is locked by it.
1626
- then the client thread does SLAVE STOP.
1627
SLAVE STOP waits for the SQL slave thread to terminate its
1628
update t, which waits for the client thread because t is locked by it.
1629
To prevent that, refuse SLAVE STOP if the
1630
client thread has locked tables
1632
if (thd->locked_tables || thd->active_transaction() || thd->global_read_lock)
1634
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
1635
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
1639
pthread_mutex_lock(&LOCK_active_mi);
1640
stop_slave(thd,active_mi,1/* net report*/);
1641
pthread_mutex_unlock(&LOCK_active_mi);
1645
case SQLCOM_ALTER_TABLE:
1646
assert(first_table == all_tables && first_table != 0);
1649
Code in mysql_alter_table() may modify its HA_CREATE_INFO argument,
1650
so we have to use a copy of this structure to make execution
1651
prepared statement- safe. A shallow copy is enough as no memory
1652
referenced from this structure will be modified.
1654
HA_CREATE_INFO create_info(lex->create_info);
1655
Alter_info alter_info(lex->alter_info, thd->mem_root);
1657
if (thd->is_fatal_error) /* out of memory creating a copy of alter_info */
1662
/* Must be set in the parser */
1663
assert(select_lex->db);
1665
{ // Rename of table
1666
TABLE_LIST tmp_table;
1667
memset(&tmp_table, 0, sizeof(tmp_table));
1668
tmp_table.table_name= lex->name.str;
1669
tmp_table.db=select_lex->db;
1672
/* Don't yet allow changing of symlinks with ALTER TABLE */
1673
if (create_info.data_file_name)
1674
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1675
"DATA DIRECTORY option ignored");
1676
if (create_info.index_file_name)
1677
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1678
"INDEX DIRECTORY option ignored");
1679
create_info.data_file_name= create_info.index_file_name= NULL;
1680
/* ALTER TABLE ends previous transaction */
1681
if (end_active_trans(thd))
1684
if (!thd->locked_tables &&
1685
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
1691
thd->enable_slow_log= opt_log_slow_admin_statements;
1692
res= mysql_alter_table(thd, select_lex->db, lex->name.str,
1696
select_lex->order_list.elements,
1697
(ORDER *) select_lex->order_list.first,
1701
case SQLCOM_RENAME_TABLE:
1703
assert(first_table == all_tables && first_table != 0);
1705
for (table= first_table; table; table= table->next_local->next_local)
1707
TABLE_LIST old_list, new_list;
1709
we do not need initialize old_list and new_list because we will
1710
come table[0] and table->next[0] there
1713
new_list= table->next_local[0];
1716
if (end_active_trans(thd) || mysql_rename_tables(thd, first_table, 0))
1722
case SQLCOM_SHOW_BINLOGS:
1724
res = show_binlogs(thd);
1727
case SQLCOM_SHOW_CREATE:
1728
assert(first_table == all_tables && first_table != 0);
1730
res= mysqld_show_create(thd, first_table);
1733
case SQLCOM_CHECKSUM:
1735
assert(first_table == all_tables && first_table != 0);
1736
res = mysql_checksum_table(thd, first_table, &lex->check_opt);
1741
assert(first_table == all_tables && first_table != 0);
1742
thd->enable_slow_log= opt_log_slow_admin_statements;
1743
res= mysql_repair_table(thd, first_table, &lex->check_opt);
1744
/* ! we write after unlocking the table */
1745
if (!res && !lex->no_write_to_binlog)
1748
Presumably, REPAIR and binlog writing doesn't require synchronization
1750
write_bin_log(thd, true, thd->query, thd->query_length);
1752
select_lex->table_list.first= (uchar*) first_table;
1753
lex->query_tables=all_tables;
1758
assert(first_table == all_tables && first_table != 0);
1759
thd->enable_slow_log= opt_log_slow_admin_statements;
1760
res = mysql_check_table(thd, first_table, &lex->check_opt);
1761
select_lex->table_list.first= (uchar*) first_table;
1762
lex->query_tables=all_tables;
1765
case SQLCOM_ANALYZE:
1767
assert(first_table == all_tables && first_table != 0);
1768
thd->enable_slow_log= opt_log_slow_admin_statements;
1769
res= mysql_analyze_table(thd, first_table, &lex->check_opt);
1770
/* ! we write after unlocking the table */
1771
if (!res && !lex->no_write_to_binlog)
1774
Presumably, ANALYZE and binlog writing doesn't require synchronization
1776
write_bin_log(thd, true, thd->query, thd->query_length);
1778
select_lex->table_list.first= (uchar*) first_table;
1779
lex->query_tables=all_tables;
1783
case SQLCOM_OPTIMIZE:
1785
assert(first_table == all_tables && first_table != 0);
1786
thd->enable_slow_log= opt_log_slow_admin_statements;
1787
res= (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) ?
1788
mysql_recreate_table(thd, first_table) :
1789
mysql_optimize_table(thd, first_table, &lex->check_opt);
1790
/* ! we write after unlocking the table */
1791
if (!res && !lex->no_write_to_binlog)
1794
Presumably, OPTIMIZE and binlog writing doesn't require synchronization
1796
write_bin_log(thd, true, thd->query, thd->query_length);
1798
select_lex->table_list.first= (uchar*) first_table;
1799
lex->query_tables=all_tables;
1803
assert(first_table == all_tables && first_table != 0);
1804
if (update_precheck(thd, all_tables))
1806
assert(select_lex->offset_limit == 0);
1807
unit->set_limit(select_lex);
1808
res= (up_result= mysql_update(thd, all_tables,
1809
select_lex->item_list,
1812
select_lex->order_list.elements,
1813
(ORDER *) select_lex->order_list.first,
1814
unit->select_limit_cnt,
1815
lex->duplicates, lex->ignore));
1816
/* mysql_update return 2 if we need to switch to multi-update */
1820
case SQLCOM_UPDATE_MULTI:
1822
assert(first_table == all_tables && first_table != 0);
1823
/* if we switched from normal update, rights are checked */
1826
if ((res= multi_update_precheck(thd, all_tables)))
1832
res= mysql_multi_update_prepare(thd);
1834
/* Check slave filtering rules */
1835
if (unlikely(thd->slave_thread))
1837
if (all_tables_not_ok(thd, all_tables))
1841
res= 0; /* don't care of prev failure */
1842
thd->clear_error(); /* filters are of highest prior */
1844
/* we warn the slave SQL thread */
1845
my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
1856
some_non_temp_table_to_be_updated(thd, all_tables))
1858
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
1863
res= mysql_multi_update(thd, all_tables,
1864
&select_lex->item_list,
1867
select_lex->options,
1868
lex->duplicates, lex->ignore, unit, select_lex);
1871
case SQLCOM_REPLACE:
1874
assert(first_table == all_tables && first_table != 0);
1875
if ((res= insert_precheck(thd, all_tables)))
1878
if (!thd->locked_tables &&
1879
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
1885
res= mysql_insert(thd, all_tables, lex->field_list, lex->many_values,
1886
lex->update_list, lex->value_list,
1887
lex->duplicates, lex->ignore);
1891
case SQLCOM_REPLACE_SELECT:
1892
case SQLCOM_INSERT_SELECT:
1894
select_result *sel_result;
1895
assert(first_table == all_tables && first_table != 0);
1896
if ((res= insert_precheck(thd, all_tables)))
1899
/* Fix lock for first table */
1900
if (first_table->lock_type == TL_WRITE_DELAYED)
1901
first_table->lock_type= TL_WRITE;
1903
/* Don't unlock tables until command is written to binary log */
1904
select_lex->options|= SELECT_NO_UNLOCK;
1906
unit->set_limit(select_lex);
1908
if (! thd->locked_tables &&
1909
! (need_start_waiting= ! wait_if_global_read_lock(thd, 0, 1)))
1915
if (!(res= open_and_lock_tables(thd, all_tables)))
1917
/* Skip first table, which is the table we are inserting in */
1918
TABLE_LIST *second_table= first_table->next_local;
1919
select_lex->table_list.first= (uchar*) second_table;
1920
select_lex->context.table_list=
1921
select_lex->context.first_name_resolution_table= second_table;
1922
res= mysql_insert_select_prepare(thd);
1923
if (!res && (sel_result= new select_insert(first_table,
1931
res= handle_select(thd, lex, sel_result, OPTION_SETUP_TABLES_DONE);
1933
Invalidate the table in the query cache if something changed
1934
after unlocking when changes become visible.
1935
TODO: this is workaround. right way will be move invalidating in
1936
the unlock procedure.
1938
if (first_table->lock_type == TL_WRITE_CONCURRENT_INSERT &&
1941
/* INSERT ... SELECT should invalidate only the very first table */
1942
TABLE_LIST *save_table= first_table->next_local;
1943
first_table->next_local= 0;
1944
first_table->next_local= save_table;
1948
/* revert changes for SP */
1949
select_lex->table_list.first= (uchar*) first_table;
1954
case SQLCOM_TRUNCATE:
1955
if (end_active_trans(thd))
1960
assert(first_table == all_tables && first_table != 0);
1962
Don't allow this within a transaction because we want to use
1965
if (thd->locked_tables || thd->active_transaction())
1967
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
1968
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
1972
res= mysql_truncate(thd, first_table, 0);
1977
assert(first_table == all_tables && first_table != 0);
1978
assert(select_lex->offset_limit == 0);
1979
unit->set_limit(select_lex);
1981
if (!thd->locked_tables &&
1982
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
1988
res = mysql_delete(thd, all_tables, select_lex->where,
1989
&select_lex->order_list,
1990
unit->select_limit_cnt, select_lex->options,
1994
case SQLCOM_DELETE_MULTI:
1996
assert(first_table == all_tables && first_table != 0);
1997
TABLE_LIST *aux_tables=
1998
(TABLE_LIST *)thd->lex->auxiliary_table_list.first;
1999
multi_delete *del_result;
2001
if (!thd->locked_tables &&
2002
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
2008
if ((res= multi_delete_precheck(thd, all_tables)))
2011
/* condition will be true on SP re-excuting */
2012
if (select_lex->item_list.elements != 0)
2013
select_lex->item_list.empty();
2014
if (add_item_to_list(thd, new Item_null()))
2017
thd_proc_info(thd, "init");
2018
if ((res= open_and_lock_tables(thd, all_tables)))
2021
if ((res= mysql_multi_delete_prepare(thd)))
2024
if (!thd->is_fatal_error &&
2025
(del_result= new multi_delete(aux_tables, lex->table_count)))
2027
res= mysql_select(thd, &select_lex->ref_pointer_array,
2028
select_lex->get_table_list(),
2029
select_lex->with_wild,
2030
select_lex->item_list,
2032
0, (ORDER *)NULL, (ORDER *)NULL, (Item *)NULL,
2034
select_lex->options | thd->options |
2035
SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
2036
OPTION_SETUP_TABLES_DONE,
2037
del_result, unit, select_lex);
2038
res|= thd->is_error();
2040
del_result->abort();
2047
case SQLCOM_DROP_TABLE:
2049
assert(first_table == all_tables && first_table != 0);
2050
if (!lex->drop_temporary)
2052
if (end_active_trans(thd))
2058
If this is a slave thread, we may sometimes execute some
2059
DROP / * 40005 TEMPORARY * / TABLE
2060
that come from parts of binlogs (likely if we use RESET SLAVE or CHANGE
2061
MASTER TO), while the temporary table has already been dropped.
2062
To not generate such irrelevant "table does not exist errors",
2063
we silently add IF EXISTS if TEMPORARY was used.
2065
if (thd->slave_thread)
2066
lex->drop_if_exists= 1;
2068
/* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
2069
thd->options|= OPTION_KEEP_LOG;
2071
/* DDL and binlog write order protected by LOCK_open */
2072
res= mysql_rm_table(thd, first_table, lex->drop_if_exists, lex->drop_temporary);
2075
case SQLCOM_SHOW_PROCESSLIST:
2076
mysqld_list_processes(thd, NullS, lex->verbose);
2078
case SQLCOM_SHOW_ENGINE_LOGS:
2080
res= ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_LOGS);
2083
case SQLCOM_CHANGE_DB:
2085
LEX_STRING db_str= { (char *) select_lex->db, strlen(select_lex->db) };
2087
if (!mysql_change_db(thd, &db_str, false))
2095
assert(first_table == all_tables && first_table != 0);
2096
if (lex->local_file)
2098
if (!(thd->client_capabilities & CLIENT_LOCAL_FILES) ||
2101
my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), MYF(0));
2106
res= mysql_load(thd, lex->exchange, first_table, lex->field_list,
2107
lex->update_list, lex->value_list, lex->duplicates,
2108
lex->ignore, (bool) lex->local_file);
2112
case SQLCOM_SET_OPTION:
2114
List<set_var_base> *lex_var_list= &lex->var_list;
2116
if (lex->autocommit && end_active_trans(thd))
2119
if (open_and_lock_tables(thd, all_tables))
2121
if (lex->one_shot_set && not_all_support_one_shot(lex_var_list))
2123
my_error(ER_RESERVED_SYNTAX, MYF(0), "SET ONE_SHOT");
2126
if (!(res= sql_set_variables(thd, lex_var_list)))
2129
If the previous command was a SET ONE_SHOT, we don't want to forget
2130
about the ONE_SHOT property of that SET. So we use a |= instead of = .
2132
thd->one_shot_set|= lex->one_shot_set;
2138
We encountered some sort of error, but no message was sent.
2139
Send something semi-generic here since we don't know which
2140
assignment in the list caused the error.
2142
if (!thd->is_error())
2143
my_error(ER_WRONG_ARGUMENTS,MYF(0),"SET");
2150
case SQLCOM_UNLOCK_TABLES:
2152
It is critical for mysqldump --single-transaction --master-data that
2153
UNLOCK TABLES does not implicitely commit a connection which has only
2154
done FLUSH TABLES WITH READ LOCK + BEGIN. If this assumption becomes
2155
false, mysqldump will not work.
2157
unlock_locked_tables(thd);
2158
if (thd->options & OPTION_TABLE_LOCK)
2160
end_active_trans(thd);
2161
thd->options&= ~(OPTION_TABLE_LOCK);
2163
if (thd->global_read_lock)
2164
unlock_global_read_lock(thd);
2167
case SQLCOM_LOCK_TABLES:
2169
We try to take transactional locks if
2170
- only transactional locks are requested (lex->lock_transactional) and
2171
- no non-transactional locks exist (!thd->locked_tables).
2173
if (lex->lock_transactional && !thd->locked_tables)
2177
All requested locks are transactional and no non-transactional
2180
if ((rc= try_transactional_lock(thd, all_tables)) == -1)
2188
Non-transactional locking has been requested or
2189
non-transactional locks exist already or transactional locks are
2190
not supported by all storage engines. Take non-transactional
2195
One or more requested locks are non-transactional and/or
2196
non-transactional locks exist or a storage engine does not support
2197
transactional locks. Check if at least one transactional lock is
2198
requested. If yes, warn about the conversion to non-transactional
2199
locks or abort in strict mode.
2201
if (check_transactional_lock(thd, all_tables))
2203
unlock_locked_tables(thd);
2204
/* we must end the trasaction first, regardless of anything */
2205
if (end_active_trans(thd))
2207
thd->in_lock_tables=1;
2208
thd->options|= OPTION_TABLE_LOCK;
2210
if (!(res= simple_open_n_lock_tables(thd, all_tables)))
2212
thd->locked_tables=thd->lock;
2214
(void) set_handler_table_locks(thd, all_tables, false);
2220
Need to end the current transaction, so the storage engine (InnoDB)
2221
can free its locks if LOCK TABLES locked some tables before finding
2222
that it can't lock a table in its list
2224
ha_autocommit_or_rollback(thd, 1);
2225
end_active_trans(thd);
2226
thd->options&= ~(OPTION_TABLE_LOCK);
2228
thd->in_lock_tables=0;
2230
case SQLCOM_CREATE_DB:
2233
As mysql_create_db() may modify HA_CREATE_INFO structure passed to
2234
it, we need to use a copy of LEX::create_info to make execution
2235
prepared statement- safe.
2237
HA_CREATE_INFO create_info(lex->create_info);
2238
if (end_active_trans(thd))
2244
if (!(alias=thd->strmake(lex->name.str, lex->name.length)) ||
2245
check_db_name(&lex->name))
2247
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
2251
If in a slave thread :
2252
CREATE DATABASE DB was certainly not preceded by USE DB.
2253
For that reason, db_ok() in sql/slave.cc did not check the
2254
do_db/ignore_db. And as this query involves no tables, tables_ok()
2255
above was not called. So we have to check rules again here.
2257
if (thd->slave_thread &&
2258
(!rpl_filter->db_ok(lex->name.str) ||
2259
!rpl_filter->db_ok_with_wild_table(lex->name.str)))
2261
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
2264
res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias :
2265
lex->name.str), &create_info, 0);
2268
case SQLCOM_DROP_DB:
2270
if (end_active_trans(thd))
2275
if (check_db_name(&lex->name))
2277
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
2281
If in a slave thread :
2282
DROP DATABASE DB may not be preceded by USE DB.
2283
For that reason, maybe db_ok() in sql/slave.cc did not check the
2284
do_db/ignore_db. And as this query involves no tables, tables_ok()
2285
above was not called. So we have to check rules again here.
2287
if (thd->slave_thread &&
2288
(!rpl_filter->db_ok(lex->name.str) ||
2289
!rpl_filter->db_ok_with_wild_table(lex->name.str)))
2291
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
2294
if (thd->locked_tables || thd->active_transaction())
2296
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
2297
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
2300
res= mysql_rm_db(thd, lex->name.str, lex->drop_if_exists, 0);
2303
case SQLCOM_ALTER_DB:
2305
LEX_STRING *db= &lex->name;
2306
HA_CREATE_INFO create_info(lex->create_info);
2307
if (check_db_name(db))
2309
my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
2313
If in a slave thread :
2314
ALTER DATABASE DB may not be preceded by USE DB.
2315
For that reason, maybe db_ok() in sql/slave.cc did not check the
2316
do_db/ignore_db. And as this query involves no tables, tables_ok()
2317
above was not called. So we have to check rules again here.
2319
if (thd->slave_thread &&
2320
(!rpl_filter->db_ok(db->str) ||
2321
!rpl_filter->db_ok_with_wild_table(db->str)))
2323
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
2326
if (thd->locked_tables || thd->active_transaction())
2328
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
2329
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
2332
res= mysql_alter_db(thd, db->str, &create_info);
2335
case SQLCOM_SHOW_CREATE_DB:
2337
if (check_db_name(&lex->name))
2339
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
2342
res= mysqld_show_create_db(thd, lex->name.str, &lex->create_info);
2347
RESET commands are never written to the binary log, so we have to
2348
initialize this variable because RESET shares the same code as FLUSH
2350
lex->no_write_to_binlog= 1;
2353
bool write_to_binlog;
2356
reload_cache() will tell us if we are allowed to write to the
2359
if (!reload_cache(thd, lex->type, first_table, &write_to_binlog))
2362
We WANT to write and we CAN write.
2363
! we write after unlocking the table.
2366
Presumably, RESET and binlog writing doesn't require synchronization
2368
if (!lex->no_write_to_binlog && write_to_binlog)
2370
write_bin_log(thd, false, thd->query, thd->query_length);
2379
Item *it= (Item *)lex->value_list.head();
2381
if (lex->table_or_sp_used())
2383
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "Usage of subqueries or stored "
2384
"function calls as part of this statement");
2388
if ((!it->fixed && it->fix_fields(lex->thd, &it)) || it->check_cols(1))
2390
my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
2394
sql_kill(thd, (ulong)it->val_int(), lex->type & ONLY_KILL_QUERY);
2398
if (thd->transaction.xid_state.xa_state != XA_NOTR)
2400
my_error(ER_XAER_RMFAIL, MYF(0),
2401
xa_state_names[thd->transaction.xid_state.xa_state]);
2405
Breakpoints for backup testing.
2407
if (begin_trans(thd))
2412
if (end_trans(thd, lex->tx_release ? COMMIT_RELEASE :
2413
lex->tx_chain ? COMMIT_AND_CHAIN : COMMIT))
2417
case SQLCOM_ROLLBACK:
2418
if (end_trans(thd, lex->tx_release ? ROLLBACK_RELEASE :
2419
lex->tx_chain ? ROLLBACK_AND_CHAIN : ROLLBACK))
2423
case SQLCOM_RELEASE_SAVEPOINT:
2426
for (sv=thd->transaction.savepoints; sv; sv=sv->prev)
2428
if (my_strnncoll(system_charset_info,
2429
(uchar *)lex->ident.str, lex->ident.length,
2430
(uchar *)sv->name, sv->length) == 0)
2435
if (ha_release_savepoint(thd, sv))
2436
res= true; // cannot happen
2439
thd->transaction.savepoints=sv->prev;
2442
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
2445
case SQLCOM_ROLLBACK_TO_SAVEPOINT:
2448
for (sv=thd->transaction.savepoints; sv; sv=sv->prev)
2450
if (my_strnncoll(system_charset_info,
2451
(uchar *)lex->ident.str, lex->ident.length,
2452
(uchar *)sv->name, sv->length) == 0)
2457
if (ha_rollback_to_savepoint(thd, sv))
2458
res= true; // cannot happen
2461
if (((thd->options & OPTION_KEEP_LOG) ||
2462
thd->transaction.all.modified_non_trans_table) &&
2464
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2465
ER_WARNING_NOT_COMPLETE_ROLLBACK,
2466
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
2469
thd->transaction.savepoints=sv;
2472
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
2475
case SQLCOM_SAVEPOINT:
2476
if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) ||
2477
thd->in_sub_stmt) || !opt_using_transactions)
2481
SAVEPOINT **sv, *newsv;
2482
for (sv=&thd->transaction.savepoints; *sv; sv=&(*sv)->prev)
2484
if (my_strnncoll(system_charset_info,
2485
(uchar *)lex->ident.str, lex->ident.length,
2486
(uchar *)(*sv)->name, (*sv)->length) == 0)
2489
if (*sv) /* old savepoint of the same name exists */
2492
ha_release_savepoint(thd, *sv); // it cannot fail
2495
else if ((newsv=(SAVEPOINT *) alloc_root(&thd->transaction.mem_root,
2496
savepoint_alloc_size)) == 0)
2498
my_error(ER_OUT_OF_RESOURCES, MYF(0));
2501
newsv->name=strmake_root(&thd->transaction.mem_root,
2502
lex->ident.str, lex->ident.length);
2503
newsv->length=lex->ident.length;
2505
if we'll get an error here, don't add new savepoint to the list.
2506
we'll lose a little bit of memory in transaction mem_root, but it'll
2507
be free'd when transaction ends anyway
2509
if (ha_savepoint(thd, newsv))
2513
newsv->prev=thd->transaction.savepoints;
2514
thd->transaction.savepoints=newsv;
2519
case SQLCOM_BINLOG_BASE64_EVENT:
2521
mysql_client_binlog_statement(thd);
2525
assert(0); /* Impossible */
2529
thd_proc_info(thd, "query end");
2532
Binlog-related cleanup:
2533
Reset system variables temporarily modified by SET ONE SHOT.
2535
Exception: If this is a SET, do nothing. This is to allow
2536
mysqlbinlog to print many SET commands (in this case we want the
2537
charset temp setting to live until the real query). This is also
2538
needed so that SET CHARACTER_SET_CLIENT... does not cancel itself
2541
if (thd->one_shot_set && lex->sql_command != SQLCOM_SET_OPTION)
2542
reset_one_shot_variables(thd);
506
2545
The return value for ROW_COUNT() is "implementation dependent" if the
507
2546
statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC
508
2547
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)))
2550
if (!(sql_command_flags[lex->sql_command] & CF_HAS_ROW_COUNT))
2551
thd->row_count_func= -1;
2559
if (need_start_waiting)
513
session->row_count_func= -1;
2562
Release the protection against the global read lock and wake
2563
everyone, who might want to set a global read lock.
2565
start_waiting_global_read_lock(thd);
516
return (res || session->is_error());
2567
return(res || thd->is_error());
518
bool execute_sqlcom_select(Session *session, TableList *all_tables)
2570
bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
520
LEX *lex= session->lex;
521
2573
select_result *result=lex->result;
523
2575
/* assign global limit variable if limit is not given */
525
Select_Lex *param= lex->unit.global_parameters;
2577
SELECT_LEX *param= lex->unit.global_parameters;
526
2578
if (!param->explicit_limit)
527
2579
param->select_limit=
528
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)))
2580
new Item_int((uint64_t) thd->variables.select_limit);
2582
if (!(res= open_and_lock_tables(thd, all_tables)))
545
2584
if (lex->describe)