12
12
You should have received a copy of the GNU General Public License
13
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
16
18
#define DRIZZLE_LEX 1
17
#include <drizzled/server_includes.h>
18
#include <drizzled/replication/replication.h>
19
#include <libdrizzle/libdrizzle.h>
20
#include <mysys/hash.h>
21
#include <drizzled/replication/binlog.h>
22
#include <drizzled/logging.h>
23
#include <drizzled/db.h>
20
#include <drizzled/item/num.h>
21
#include <drizzled/abort_exception.h>
24
22
#include <drizzled/error.h>
25
23
#include <drizzled/nested_join.h>
26
24
#include <drizzled/query_id.h>
25
#include <drizzled/transaction_services.h>
27
26
#include <drizzled/sql_parse.h>
28
27
#include <drizzled/data_home.h>
29
28
#include <drizzled/sql_base.h>
30
29
#include <drizzled/show.h>
31
#include <drizzled/rename.h>
32
#include <drizzled/functions/time/unix_timestamp.h>
30
#include <drizzled/function/time/unix_timestamp.h>
31
#include <drizzled/function/get_system_var.h>
33
32
#include <drizzled/item/cmpfunc.h>
33
#include <drizzled/item/null.h>
34
34
#include <drizzled/session.h>
35
#include <drizzled/session/cache.h>
35
36
#include <drizzled/sql_load.h>
37
#include <drizzled/lock.h>
38
#include <drizzled/select_send.h>
39
#include <drizzled/plugin/client.h>
40
#include <drizzled/statement.h>
41
#include <drizzled/statement/alter_table.h>
42
#include <drizzled/probes.h>
43
#include <drizzled/charset.h>
44
#include <drizzled/plugin/logging.h>
45
#include <drizzled/plugin/query_rewrite.h>
46
#include <drizzled/plugin/query_cache.h>
47
#include <drizzled/plugin/authorization.h>
48
#include <drizzled/optimizer/explain_plan.h>
49
#include <drizzled/pthread_globals.h>
50
#include <drizzled/plugin/event_observer.h>
51
#include <drizzled/display.h>
52
#include <drizzled/visibility.h>
53
#include <drizzled/kill.h>
54
#include <drizzled/schema.h>
55
#include <drizzled/item/subselect.h>
56
#include <drizzled/diagnostics_area.h>
57
#include <drizzled/table_ident.h>
58
#include <drizzled/statistics_variables.h>
59
#include <drizzled/system_variables.h>
60
#include <drizzled/session/times.h>
61
#include <drizzled/session/transactions.h>
62
#include <drizzled/create_field.h>
63
#include <drizzled/lex_input_stream.h>
69
#include <boost/date_time.hpp>
70
#include <drizzled/internal/my_sys.h>
38
72
using namespace std;
74
extern int base_sql_parse(drizzled::Session *session); // from sql_yacc.cc
79
bool my_yyoverflow(short **a, ParserType **b, ulong *yystacksize);
80
static bool parse_sql(Session *session, Lex_input_stream *lip);
81
void parse(Session&, const char *inBuf, uint32_t length);
41
84
@defgroup Runtime_Environment Runtime Environment
45
extern const CHARSET_INFO *character_set_filesystem;
46
const char *any_db="*any*"; // Special symbol for check_access
48
const LEX_STRING command_name[COM_END+1]={
49
{ C_STRING_WITH_LEN("Sleep") },
50
{ C_STRING_WITH_LEN("Quit") },
51
{ C_STRING_WITH_LEN("Init DB") },
52
{ C_STRING_WITH_LEN("Query") },
53
{ C_STRING_WITH_LEN("Field List") },
54
{ C_STRING_WITH_LEN("Create DB") },
55
{ C_STRING_WITH_LEN("Drop DB") },
56
{ C_STRING_WITH_LEN("Refresh") },
57
{ C_STRING_WITH_LEN("Shutdown") },
58
{ C_STRING_WITH_LEN("Processlist") },
59
{ C_STRING_WITH_LEN("Connect") },
60
{ C_STRING_WITH_LEN("Kill") },
61
{ C_STRING_WITH_LEN("Ping") },
62
{ C_STRING_WITH_LEN("Time") },
63
{ C_STRING_WITH_LEN("Change user") },
64
{ C_STRING_WITH_LEN("Binlog Dump") },
65
{ C_STRING_WITH_LEN("Connect Out") },
66
{ C_STRING_WITH_LEN("Register Slave") },
67
{ C_STRING_WITH_LEN("Set option") },
68
{ C_STRING_WITH_LEN("Daemon") },
69
{ C_STRING_WITH_LEN("Error") } // Last command number
72
const char *xa_state_names[]={
88
extern size_t my_thread_stack_size;
89
extern const charset_info_st *character_set_filesystem;
93
static const std::string command_name[]=
103
"Error" // Last command number
107
const char *xa_state_names[]=
73
109
"NON-EXISTING", "ACTIVE", "IDLE", "PREPARED"
76
static void unlock_locked_tables(Session *session)
78
if (session->locked_tables)
80
session->lock=session->locked_tables;
81
session->locked_tables=0; // Will be automatically closed
82
close_thread_tables(session); // Free tables
87
bool end_active_trans(Session *session)
91
if (session->transaction.xid_state.xa_state != XA_NOTR)
93
my_error(ER_XAER_RMFAIL, MYF(0),
94
xa_state_names[session->transaction.xid_state.xa_state]);
97
if (session->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN |
100
/* Safety if one did "drop table" on locked tables */
101
if (!session->locked_tables)
102
session->options&= ~OPTION_TABLE_LOCK;
103
session->server_status&= ~SERVER_STATUS_IN_TRANS;
104
if (ha_commit(session))
107
session->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
108
session->transaction.all.modified_non_trans_table= false;
113
bool begin_trans(Session *session)
116
if (session->locked_tables)
118
session->lock=session->locked_tables;
119
session->locked_tables=0; // Will be automatically closed
120
close_thread_tables(session); // Free tables
122
if (end_active_trans(session))
126
LEX *lex= session->lex;
127
session->options|= OPTION_BEGIN;
128
session->server_status|= SERVER_STATUS_IN_TRANS;
129
if (lex->start_transaction_opt & DRIZZLE_START_TRANS_OPT_WITH_CONS_SNAPSHOT)
130
error= ha_start_consistent_snapshot(session);
136
Returns true if all tables should be ignored.
138
inline bool all_tables_not_ok(Session *, TableList *)
144
static bool some_non_temp_table_to_be_updated(Session *session, TableList *tables)
146
for (TableList *table= tables; table; table= table->next_global)
148
assert(table->db && table->table_name);
149
if (table->updating &&
150
!find_temporary_table(session, table->db, table->table_name))
158
114
Mark all commands that somehow changes a table.
188
149
sql_command_flags[SQLCOM_DROP_INDEX]= CF_CHANGES_DATA;
190
151
sql_command_flags[SQLCOM_UPDATE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
191
sql_command_flags[SQLCOM_UPDATE_MULTI]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
192
152
sql_command_flags[SQLCOM_INSERT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
193
153
sql_command_flags[SQLCOM_INSERT_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
194
154
sql_command_flags[SQLCOM_DELETE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
195
sql_command_flags[SQLCOM_DELETE_MULTI]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
196
155
sql_command_flags[SQLCOM_REPLACE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
197
156
sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
199
sql_command_flags[SQLCOM_SHOW_STATUS]= CF_STATUS_COMMAND;
200
sql_command_flags[SQLCOM_SHOW_DATABASES]= CF_STATUS_COMMAND;
201
sql_command_flags[SQLCOM_SHOW_OPEN_TABLES]= CF_STATUS_COMMAND;
202
sql_command_flags[SQLCOM_SHOW_FIELDS]= CF_STATUS_COMMAND;
203
sql_command_flags[SQLCOM_SHOW_KEYS]= CF_STATUS_COMMAND;
204
sql_command_flags[SQLCOM_SHOW_VARIABLES]= CF_STATUS_COMMAND;
205
sql_command_flags[SQLCOM_SHOW_BINLOGS]= CF_STATUS_COMMAND;
206
158
sql_command_flags[SQLCOM_SHOW_WARNS]= CF_STATUS_COMMAND;
207
159
sql_command_flags[SQLCOM_SHOW_ERRORS]= CF_STATUS_COMMAND;
208
sql_command_flags[SQLCOM_SHOW_ENGINE_STATUS]= CF_STATUS_COMMAND;
209
sql_command_flags[SQLCOM_SHOW_PROCESSLIST]= CF_STATUS_COMMAND;
210
160
sql_command_flags[SQLCOM_SHOW_CREATE_DB]= CF_STATUS_COMMAND;
211
161
sql_command_flags[SQLCOM_SHOW_CREATE]= CF_STATUS_COMMAND;
212
sql_command_flags[SQLCOM_SHOW_MASTER_STAT]= CF_STATUS_COMMAND;
213
sql_command_flags[SQLCOM_SHOW_SLAVE_STAT]= CF_STATUS_COMMAND;
215
sql_command_flags[SQLCOM_SHOW_TABLES]= (CF_STATUS_COMMAND |
216
CF_SHOW_TABLE_COMMAND);
217
sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]= (CF_STATUS_COMMAND |
218
CF_SHOW_TABLE_COMMAND);
220
164
The following admin table operations are allowed
223
sql_command_flags[SQLCOM_REPAIR]= CF_WRITE_LOGS_COMMAND;
224
sql_command_flags[SQLCOM_OPTIMIZE]= CF_WRITE_LOGS_COMMAND;
225
167
sql_command_flags[SQLCOM_ANALYZE]= CF_WRITE_LOGS_COMMAND;
229
bool is_update_query(enum enum_sql_command command)
231
assert(command >= 0 && command <= SQLCOM_END);
232
return (sql_command_flags[command].test(CF_BIT_CHANGES_DATA));
235
void execute_init_command(Session *session, sys_var_str *init_command_var,
236
rw_lock_t *var_mutex)
239
ulong save_client_capabilities;
241
session->set_proc_info("Execution of init_command");
243
We need to lock init_command_var because
244
during execution of init_command_var query
245
values of init_command_var can't be changed
247
rw_rdlock(var_mutex);
248
save_client_capabilities= session->client_capabilities;
249
session->client_capabilities|= CLIENT_MULTI_STATEMENTS;
251
We don't need return result of execution to client side.
252
To forbid this we should set session->net.vio to 0.
254
save_vio= session->net.vio;
256
dispatch_command(COM_QUERY, session,
257
init_command_var->value,
258
init_command_var->value_length);
259
rw_unlock(var_mutex);
260
session->client_capabilities= save_client_capabilities;
261
session->net.vio= save_vio;
265
Ends the current transaction and (maybe) begin the next.
267
@param session Current thread
268
@param completion Completion type
274
int end_trans(Session *session, enum enum_mysql_completiontype completion)
279
if (session->transaction.xid_state.xa_state != XA_NOTR)
281
my_error(ER_XAER_RMFAIL, MYF(0),
282
xa_state_names[session->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
session->server_status&= ~SERVER_STATUS_IN_TRANS;
293
res= ha_commit(session);
294
session->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
295
session->transaction.all.modified_non_trans_table= false;
298
do_release= 1; /* fall through */
299
case COMMIT_AND_CHAIN:
300
res= end_active_trans(session);
301
if (!res && completion == COMMIT_AND_CHAIN)
302
res= begin_trans(session);
304
case ROLLBACK_RELEASE:
305
do_release= 1; /* fall through */
307
case ROLLBACK_AND_CHAIN:
309
session->server_status&= ~SERVER_STATUS_IN_TRANS;
310
if (ha_rollback(session))
312
session->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
313
session->transaction.all.modified_non_trans_table= false;
314
if (!res && (completion == ROLLBACK_AND_CHAIN))
315
res= begin_trans(session);
320
my_error(ER_UNKNOWN_COM_ERROR, MYF(0));
325
my_error(session->killed_errno(), MYF(0));
326
else if ((res == 0) && do_release)
327
session->killed= Session::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(Session *session)
350
NET *net= &session->net;
351
enum enum_server_command command;
354
indicator of uninitialized lex => normal flow of errors handling
357
session->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, session->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
session->clear_error(); // Clear error message
372
session->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(session->is_error());
383
net_end_statement(session);
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, session->variables.net_read_timeout);
422
assert(packet_length);
423
return_value= dispatch_command(command, session, 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(Session *session,
445
TableList *all_tables)
450
LEX *lex= session->lex;
452
if (!(sql_command_flags[lex->sql_command].test(CF_BIT_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(session, 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. */
490
171
Perform one connection-level (COM_XXXX) command.
507
188
1 request of thread shutdown, i. e. if command is
508
189
COM_QUIT/COM_SHUTDOWN
510
bool dispatch_command(enum enum_server_command command, Session *session,
511
char* packet, uint32_t packet_length)
191
bool dispatch_command(enum_server_command command, Session *session,
192
const char* packet, uint32_t packet_length)
513
NET *net= &session->net;
515
Query_id &query_id= Query_id::get_query_id();
517
session->command=command;
518
session->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
520
pthread_mutex_lock(&LOCK_thread_count);
521
session->query_id= query_id.value();
524
/* Ignore these statements. */
527
/* Increase id and count all other statements. */
529
statistic_increment(session->status_var.questions, &LOCK_status);
195
Query_id& query_id= Query_id::get_query_id();
197
DRIZZLE_COMMAND_START(session->thread_id, command);
199
session->command= command;
200
session->lex().sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
201
session->times.set_time();
202
session->setQueryId(query_id.value());
204
if (command != COM_PING)
206
// Increase id and count all other statements
207
session->status_var.questions++;
534
/* TODO: set session->lex->sql_command to SQLCOM_END here */
535
pthread_mutex_unlock(&LOCK_thread_count);
537
logging_pre_do(session);
539
session->server_status&=
540
~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
211
/* @todo set session->lex().sql_command to SQLCOM_END here */
213
plugin::Logging::preDo(session);
214
if (unlikely(plugin::EventObserver::beforeStatement(*session)))
545
status_var_increment(session->status_var.com_stat[SQLCOM_CHANGE_DB]);
546
session->convert_string(&tmp, system_charset_info,
547
packet, packet_length, session->charset());
548
if (!mysql_change_db(session, &tmp, false))
216
// We should do something about an error...
554
case COM_CHANGE_USER:
219
session->server_status&= ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
556
status_var_increment(session->status_var.com_other);
557
char *user= (char*) packet, *packet_end= packet + packet_length;
558
/* Safe because there is always a trailing \0 at the end of the packet */
559
char *passwd= strchr(user, '\0')+1;
562
session->clear_error(); // if errors from rollback
565
Old clients send null-terminated string ('\0' for empty string) for
566
password. New clients send the size (1 byte) + string (not null
567
terminated, so also '\0' for empty string).
569
Cast *passwd to an unsigned char, so that it doesn't extend the sign
570
for *passwd > 127 and become 2**32-127 after casting to uint32_t.
572
char db_buff[NAME_LEN+1]; // buffer to store db in utf8
576
If there is no password supplied, the packet must contain '\0',
577
in any type of handshake (4.1 or pre-4.1).
579
if (passwd >= packet_end)
581
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
584
uint32_t passwd_len= (session->client_capabilities & CLIENT_SECURE_CONNECTION ?
585
(unsigned char)(*passwd++) : strlen(passwd));
586
uint32_t dummy_errors, save_db_length, db_length;
588
Security_context save_security_ctx= *session->security_ctx;
589
USER_CONN *save_user_connect;
593
Database name is always NUL-terminated, so in case of empty database
594
the packet must contain at least the trailing '\0'.
596
if (db >= packet_end)
598
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
601
db_length= strlen(db);
603
char *ptr= db + db_length + 1;
604
uint32_t cs_number= 0;
606
if (ptr < packet_end)
608
if (ptr + 2 > packet_end)
225
if (packet_length == 0)
610
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
227
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
614
cs_number= uint2korr(ptr);
617
/* Convert database name to utf8 */
618
db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
619
system_charset_info, db, db_length,
620
session->charset(), &dummy_errors)]= 0;
623
/* Save user and privileges */
624
save_db_length= session->db_length;
625
save_db= session->db;
626
save_user_connect= session->user_connect;
628
if (!(session->security_ctx->user= my_strdup(user, MYF(0))))
630
session->security_ctx->user= save_security_ctx.user;
631
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
230
if (not schema::change(*session, identifier::Schema(string(packet, packet_length))))
635
/* Clear variables that are allocated */
636
session->user_connect= 0;
637
res= check_user(session, passwd, passwd_len, db, false);
641
if (session->security_ctx->user)
642
free(session->security_ctx->user);
643
*session->security_ctx= save_security_ctx;
644
session->user_connect= save_user_connect;
645
session->db= save_db;
646
session->db_length= save_db_length;
652
if (save_security_ctx.user)
653
free(save_security_ctx.user);
657
session_init_client_charset(session, cs_number);
658
session->update_charset();
665
if (alloc_query(session, packet, packet_length))
666
break; // fatal error is set
667
char *packet_end= session->query + session->query_length;
668
const char* end_of_stmt= NULL;
670
mysql_parse(session, session->query, session->query_length, &end_of_stmt);
672
while (!session->killed && (end_of_stmt != NULL) && ! session->is_error())
674
char *beginning_of_next_stmt= (char*) end_of_stmt;
676
net_end_statement(session);
678
Multiple queries exits, execute them individually
680
close_thread_tables(session);
681
ulong length= (ulong)(packet_end - beginning_of_next_stmt);
683
log_slow_statement(session);
685
/* Remove garbage at start of query */
686
while (length > 0 && my_isspace(session->charset(), *beginning_of_next_stmt))
688
beginning_of_next_stmt++;
692
pthread_mutex_lock(&LOCK_thread_count);
693
session->query_length= length;
694
session->query= beginning_of_next_stmt;
696
Count each statement from the client.
698
statistic_increment(session->status_var.questions, &LOCK_status);
699
session->query_id= query_id.next();
700
session->set_time(); /* Reset the query start time. */
701
/* TODO: set session->lex->sql_command to SQLCOM_END here */
702
pthread_mutex_unlock(&LOCK_thread_count);
704
mysql_parse(session, beginning_of_next_stmt, length, &end_of_stmt);
708
case COM_FIELD_LIST: // This isn't actually needed
710
char *fields, *packet_end= packet + packet_length, *arg_end;
711
/* Locked closure of all tables */
712
TableList table_list;
713
LEX_STRING conv_name;
715
/* used as fields initializator */
718
status_var_increment(session->status_var.com_stat[SQLCOM_SHOW_FIELDS]);
719
memset(&table_list, 0, sizeof(table_list));
720
if (session->copy_db_to(&table_list.db, &table_list.db_length))
723
We have name + wildcard in packet, separated by endzero
725
arg_end= strchr(packet, '\0');
726
session->convert_string(&conv_name, system_charset_info,
727
packet, (uint32_t) (arg_end - packet), session->charset());
728
table_list.alias= table_list.table_name= conv_name.str;
731
if (!my_strcasecmp(system_charset_info, table_list.db,
732
INFORMATION_SCHEMA_NAME.c_str()))
734
ST_SCHEMA_TABLE *schema_table= find_schema_table(session, table_list.alias);
736
table_list.schema_table= schema_table;
739
session->query_length= (uint32_t) (packet_end - packet); // Don't count end \0
740
if (!(session->query=fields= (char*) session->memdup(packet,session->query_length+1)))
742
if (lower_case_table_names)
743
my_casedn_str(files_charset_info, table_list.table_name);
745
/* init structures for VIEW processing */
746
table_list.select_lex= &(session->lex->select_lex);
749
mysql_reset_session_for_next_command(session);
752
select_lex.table_list.link_in_list((unsigned char*) &table_list,
753
(unsigned char**) &table_list.next_local);
754
session->lex->add_to_query_tables(&table_list);
756
/* switch on VIEW optimisation: do not fill temporary tables */
757
session->lex->sql_command= SQLCOM_SHOW_FIELDS;
758
mysqld_list_fields(session,&table_list,fields);
759
session->lex->unit.cleanup();
760
session->cleanup_after_query();
239
session->readAndStoreQuery(packet, packet_length);
240
DRIZZLE_QUERY_START(session->getQueryString()->c_str(), session->thread_id, session->schema()->c_str());
241
parse(*session, session->getQueryString()->c_str(), session->getQueryString()->length());
764
246
/* We don't calculate statistics for this command */
765
net->error=0; // Don't give 'abort' message
766
session->main_da.disable_status(); // Don't send anything back
767
error=true; // End server
247
session->main_da().disable_status(); // Don't send anything back
248
error= true; // End server
769
case COM_BINLOG_DUMP:
773
uint32_t slave_server_id;
775
status_var_increment(session->status_var.com_other);
776
/* TODO: The following has to be changed to an 8 byte integer */
777
pos = uint4korr(packet);
778
flags = uint2korr(packet + 4);
779
session->server_id=0; /* avoid suicide */
780
if ((slave_server_id= uint4korr(packet+6))) // mysqlbinlog.server_id==0
781
kill_zombie_dump_threads(slave_server_id);
782
session->server_id = slave_server_id;
784
mysql_binlog_send(session, session->strdup(packet + 10), (my_off_t) pos, flags);
785
/* fake COM_QUIT -- if we get here, the thread needs to terminate */
253
if (packet_length != 4)
255
my_error(ER_NO_SUCH_THREAD, MYF(0), 0);
261
memcpy(&kill_id, packet, sizeof(uint32_t));
263
kill_id= ntohl(kill_id);
264
(void)drizzled::kill(*session->user(), kill_id, true);
789
270
case COM_SHUTDOWN:
791
status_var_increment(session->status_var.com_other);
793
close_thread_tables(session); // Free before kill
272
session->status_var.com_other++;
274
session->close_thread_tables(); // Free before kill
799
status_var_increment(session->status_var.com_other);
800
my_ok(session); // Tell client we are alive
802
case COM_PROCESS_INFO:
803
status_var_increment(session->status_var.com_stat[SQLCOM_SHOW_PROCESSLIST]);
804
mysqld_list_processes(session, NULL, 0);
806
case COM_PROCESS_KILL:
808
status_var_increment(session->status_var.com_stat[SQLCOM_KILL]);
809
ulong id=(ulong) uint4korr(packet);
810
sql_kill(session,id,false);
815
status_var_increment(session->status_var.com_stat[SQLCOM_SET_OPTION]);
816
uint32_t opt_command= uint2korr(packet);
281
session->status_var.com_other++;
282
session->my_ok(); // Tell client we are alive
818
switch (opt_command) {
819
case (int) DRIZZLE_OPTION_MULTI_STATEMENTS_ON:
820
session->client_capabilities|= CLIENT_MULTI_STATEMENTS;
823
case (int) DRIZZLE_OPTION_MULTI_STATEMENTS_OFF:
824
session->client_capabilities&= ~CLIENT_MULTI_STATEMENTS;
828
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
834
286
case COM_CONNECT: // Impossible here
835
case COM_TIME: // Impossible from client
838
289
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
1107
489
variables, but for now this is probably good enough.
1108
490
Don't reset warnings when executing a stored routine.
1110
if (all_tables || !lex->is_single_level_stmt())
1111
drizzle_reset_errors(session, 0);
1113
if (unlikely(session->slave_thread))
1116
Check if statment should be skipped because of slave filtering
1120
- UPDATE MULTI: For this statement, we want to check the filtering
1121
rules later in the code
1122
- SET: we always execute it (Not that many SET commands exists in
1123
the binary log anyway -- only 4.1 masters write SET statements,
1124
in 5.0 there are no SET statements in the binary log)
1125
- DROP TEMPORARY TABLE IF EXISTS: we always execute it (otherwise we
1126
have stale files on slave caused by exclusion of one tmp table).
1128
if (!(lex->sql_command == SQLCOM_UPDATE_MULTI) &&
1129
!(lex->sql_command == SQLCOM_SET_OPTION) &&
1130
!(lex->sql_command == SQLCOM_DROP_TABLE &&
1131
lex->drop_temporary && lex->drop_if_exists) &&
1132
all_tables_not_ok(session, all_tables))
1134
/* we warn the slave SQL thread */
1135
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
1142
When option readonly is set deny operations which change non-temporary
1143
tables. Except for the replication thread and the 'super' users.
1145
if (deny_updates_if_read_only_option(session, all_tables))
1147
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
1150
} /* endif unlikely slave */
1151
status_var_increment(session->status_var.com_stat[lex->sql_command]);
1153
assert(session->transaction.stmt.modified_non_trans_table == false);
1155
switch (lex->sql_command) {
1156
case SQLCOM_SHOW_STATUS:
1158
system_status_var old_status_var= session->status_var;
1159
session->initial_status_var= &old_status_var;
1160
res= execute_sqlcom_select(session, all_tables);
1161
/* Don't log SHOW STATUS commands to slow query log */
1162
session->server_status&= ~(SERVER_QUERY_NO_INDEX_USED |
1163
SERVER_QUERY_NO_GOOD_INDEX_USED);
1165
restore status variables, as we don't want 'show status' to cause
1168
pthread_mutex_lock(&LOCK_status);
1169
add_diff_to_status(&global_status_var, &session->status_var,
1171
session->status_var= old_status_var;
1172
pthread_mutex_unlock(&LOCK_status);
1175
case SQLCOM_SHOW_DATABASES:
1176
case SQLCOM_SHOW_TABLES:
1177
case SQLCOM_SHOW_TABLE_STATUS:
1178
case SQLCOM_SHOW_OPEN_TABLES:
1179
case SQLCOM_SHOW_FIELDS:
1180
case SQLCOM_SHOW_KEYS:
1181
case SQLCOM_SHOW_VARIABLES:
1184
session->status_var.last_query_cost= 0.0;
1185
res= execute_sqlcom_select(session, all_tables);
1188
case SQLCOM_EMPTY_QUERY:
1194
res = purge_master_logs(session, lex->to_log);
1197
case SQLCOM_PURGE_BEFORE:
1201
/* PURGE MASTER LOGS BEFORE 'data' */
1202
it= (Item *)lex->value_list.head();
1203
if ((!it->fixed && it->fix_fields(lex->session, &it)) ||
1206
my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE LOGS BEFORE");
1209
it= new Item_func_unix_timestamp(it);
1211
it is OK only emulate fix_fieds, because we need only
1214
it->quick_fix_field();
1215
res = purge_master_logs_before_date(session, (ulong)it->val_int());
1218
case SQLCOM_SHOW_WARNS:
1220
res= mysqld_show_warnings(session, (uint32_t)
1221
((1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_NOTE) |
1222
(1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_WARN) |
1223
(1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR)
1227
case SQLCOM_SHOW_ERRORS:
1229
res= mysqld_show_warnings(session, (uint32_t)
1230
(1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR));
1233
case SQLCOM_ASSIGN_TO_KEYCACHE:
1235
assert(first_table == all_tables && first_table != 0);
1236
res= mysql_assign_to_keycache(session, first_table, &lex->ident);
1239
case SQLCOM_CHANGE_MASTER:
1241
pthread_mutex_lock(&LOCK_active_mi);
1242
res = change_master(session,active_mi);
1243
pthread_mutex_unlock(&LOCK_active_mi);
1246
case SQLCOM_SHOW_SLAVE_STAT:
1248
pthread_mutex_lock(&LOCK_active_mi);
1249
if (active_mi != NULL)
1251
res = show_master_info(session, active_mi);
1255
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1256
"the master info structure does not exist");
1259
pthread_mutex_unlock(&LOCK_active_mi);
1262
case SQLCOM_SHOW_MASTER_STAT:
1264
res = show_binlog_info(session);
1268
case SQLCOM_SHOW_ENGINE_STATUS:
1270
res = ha_show_status(session, lex->create_info.db_type, HA_ENGINE_STATUS);
1273
case SQLCOM_CREATE_TABLE:
1275
/* If CREATE TABLE of non-temporary table, do implicit commit */
1276
if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE))
1278
if (end_active_trans(session))
1284
assert(first_table == all_tables && first_table != 0);
1286
// Skip first table, which is the table we are creating
1287
TableList *create_table= lex->unlink_first_table(&link_to_local);
1288
TableList *select_tables= lex->query_tables;
1290
Code below (especially in mysql_create_table() and select_create
1291
methods) may modify HA_CREATE_INFO structure in LEX, so we have to
1292
use a copy of this structure to make execution prepared statement-
1293
safe. A shallow copy is enough as this code won't modify any memory
1294
referenced from this structure.
1296
HA_CREATE_INFO create_info(lex->create_info);
1298
We need to copy alter_info for the same reasons of re-execution
1299
safety, only in case of Alter_info we have to do (almost) a deep
1302
Alter_info alter_info(lex->alter_info, session->mem_root);
1304
if (session->is_fatal_error)
1306
/* If out of memory when creating a copy of alter_info. */
1308
goto end_with_restore_list;
1311
if ((res= create_table_precheck(session, select_tables, create_table)))
1312
goto end_with_restore_list;
1314
/* Might have been updated in create_table_precheck */
1315
create_info.alias= create_table->alias;
1317
#ifdef HAVE_READLINK
1318
/* Fix names if symlinked tables */
1319
if (append_file_to_dir(session, &create_info.data_file_name,
1320
create_table->table_name) ||
1321
append_file_to_dir(session, &create_info.index_file_name,
1322
create_table->table_name))
1323
goto end_with_restore_list;
1326
If we are using SET CHARSET without DEFAULT, add an implicit
1327
DEFAULT to not confuse old users. (This may change).
1329
if ((create_info.used_fields &
1330
(HA_CREATE_USED_DEFAULT_CHARSET | HA_CREATE_USED_CHARSET)) ==
1331
HA_CREATE_USED_CHARSET)
1333
create_info.used_fields&= ~HA_CREATE_USED_CHARSET;
1334
create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
1335
create_info.default_table_charset= create_info.table_charset;
1336
create_info.table_charset= 0;
1339
The create-select command will open and read-lock the select table
1340
and then create, open and write-lock the new table. If a global
1341
read lock steps in, we get a deadlock. The write lock waits for
1342
the global read lock, while the global read lock waits for the
1343
select table to be closed. So we wait until the global readlock is
1344
gone before starting both steps. Note that
1345
wait_if_global_read_lock() sets a protection against a new global
1346
read lock when it succeeds. This needs to be released by
1347
start_waiting_global_read_lock(). We protect the normal CREATE
1348
TABLE in the same way. That way we avoid that a new table is
1349
created during a gobal read lock.
1351
if (!session->locked_tables &&
1352
!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
1355
goto end_with_restore_list;
1357
if (select_lex->item_list.elements) // With select
1359
select_result *result;
1361
select_lex->options|= SELECT_NO_UNLOCK;
1362
unit->set_limit(select_lex);
1364
if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
1366
lex->link_first_table_back(create_table, link_to_local);
1367
create_table->create= true;
1370
if (!(res= open_and_lock_tables(session, lex->query_tables)))
1373
Is table which we are changing used somewhere in other parts
1376
if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
1378
TableList *duplicate;
1379
create_table= lex->unlink_first_table(&link_to_local);
1380
if ((duplicate= unique_table(session, create_table, select_tables, 0)))
1382
update_non_unique_table_error(create_table, "CREATE", duplicate);
1384
goto end_with_restore_list;
1389
select_create is currently not re-execution friendly and
1390
needs to be created for every execution of a PS/SP.
1392
if ((result= new select_create(create_table,
1395
select_lex->item_list,
1401
CREATE from SELECT give its SELECT_LEX for SELECT,
1402
and item_list belong to SELECT
1404
res= handle_select(session, lex, result, 0);
1408
else if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
1409
create_table= lex->unlink_first_table(&link_to_local);
1414
/* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
1415
if (create_info.options & HA_LEX_CREATE_TMP_TABLE)
1416
session->options|= OPTION_KEEP_LOG;
1417
/* regular create */
1418
if (create_info.options & HA_LEX_CREATE_TABLE_LIKE)
1419
res= mysql_create_like_table(session, create_table, select_tables,
1423
res= mysql_create_table(session, create_table->db,
1424
create_table->table_name, &create_info,
1431
/* put tables back for PS rexecuting */
1432
end_with_restore_list:
1433
lex->link_first_table_back(create_table, link_to_local);
1436
case SQLCOM_CREATE_INDEX:
1438
case SQLCOM_DROP_INDEX:
1440
CREATE INDEX and DROP INDEX are implemented by calling ALTER
1441
TABLE with proper arguments.
1443
In the future ALTER TABLE will notice that the request is to
1444
only add indexes and create these one by one for the existing
1445
table without having to do a full rebuild.
1448
/* Prepare stack copies to be re-execution safe */
1449
HA_CREATE_INFO create_info;
1450
Alter_info alter_info(lex->alter_info, session->mem_root);
1452
if (session->is_fatal_error) /* out of memory creating a copy of alter_info */
1455
assert(first_table == all_tables && first_table != 0);
1456
if (end_active_trans(session))
1459
memset(&create_info, 0, sizeof(create_info));
1460
create_info.db_type= 0;
1461
create_info.row_type= ROW_TYPE_NOT_USED;
1462
create_info.default_table_charset= session->variables.collation_database;
1464
res= mysql_alter_table(session, first_table->db, first_table->table_name,
1465
&create_info, first_table, &alter_info,
1466
0, (order_st*) 0, 0);
1469
case SQLCOM_SLAVE_START:
1471
pthread_mutex_lock(&LOCK_active_mi);
1472
start_slave(session,active_mi,1 /* net report*/);
1473
pthread_mutex_unlock(&LOCK_active_mi);
1476
case SQLCOM_SLAVE_STOP:
1478
If the client thread has locked tables, a deadlock is possible.
1480
- the client thread does LOCK TABLE t READ.
1481
- then the master updates t.
1482
- then the SQL slave thread wants to update t,
1483
so it waits for the client thread because t is locked by it.
1484
- then the client thread does SLAVE STOP.
1485
SLAVE STOP waits for the SQL slave thread to terminate its
1486
update t, which waits for the client thread because t is locked by it.
1487
To prevent that, refuse SLAVE STOP if the
1488
client thread has locked tables
1490
if (session->locked_tables || session->active_transaction() || session->global_read_lock)
1492
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
1493
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
1497
pthread_mutex_lock(&LOCK_active_mi);
1498
stop_slave(session,active_mi,1/* net report*/);
1499
pthread_mutex_unlock(&LOCK_active_mi);
1503
case SQLCOM_ALTER_TABLE:
1504
assert(first_table == all_tables && first_table != 0);
1507
Code in mysql_alter_table() may modify its HA_CREATE_INFO argument,
1508
so we have to use a copy of this structure to make execution
1509
prepared statement- safe. A shallow copy is enough as no memory
1510
referenced from this structure will be modified.
1512
HA_CREATE_INFO create_info(lex->create_info);
1513
Alter_info alter_info(lex->alter_info, session->mem_root);
1515
if (session->is_fatal_error) /* out of memory creating a copy of alter_info */
1520
/* Must be set in the parser */
1521
assert(select_lex->db);
1523
{ // Rename of table
1524
TableList tmp_table;
1525
memset(&tmp_table, 0, sizeof(tmp_table));
1526
tmp_table.table_name= lex->name.str;
1527
tmp_table.db=select_lex->db;
1530
/* Don't yet allow changing of symlinks with ALTER TABLE */
1531
if (create_info.data_file_name)
1532
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1533
"DATA DIRECTORY option ignored");
1534
if (create_info.index_file_name)
1535
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1536
"INDEX DIRECTORY option ignored");
1537
create_info.data_file_name= create_info.index_file_name= NULL;
1538
/* ALTER TABLE ends previous transaction */
1539
if (end_active_trans(session))
1542
if (!session->locked_tables &&
1543
!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
1549
res= mysql_alter_table(session, select_lex->db, lex->name.str,
1553
select_lex->order_list.elements,
1554
(order_st *) select_lex->order_list.first,
1558
case SQLCOM_RENAME_TABLE:
1560
assert(first_table == all_tables && first_table != 0);
1562
for (table= first_table; table; table= table->next_local->next_local)
1564
TableList old_list, new_list;
1566
we do not need initialize old_list and new_list because we will
1567
come table[0] and table->next[0] there
1570
new_list= table->next_local[0];
1573
if (end_active_trans(session) || drizzle_rename_tables(session, first_table, 0))
1579
case SQLCOM_SHOW_BINLOGS:
1581
res = show_binlogs(session);
1584
case SQLCOM_SHOW_CREATE:
1585
assert(first_table == all_tables && first_table != 0);
1587
res= mysqld_show_create(session, first_table);
1590
case SQLCOM_CHECKSUM:
1592
assert(first_table == all_tables && first_table != 0);
1593
res = mysql_checksum_table(session, first_table, &lex->check_opt);
1598
assert(first_table == all_tables && first_table != 0);
1599
res= mysql_repair_table(session, first_table, &lex->check_opt);
1600
/* ! we write after unlocking the table */
1602
Presumably, REPAIR and binlog writing doesn't require synchronization
1604
write_bin_log(session, true, session->query, session->query_length);
1605
select_lex->table_list.first= (unsigned char*) first_table;
1606
lex->query_tables=all_tables;
1611
assert(first_table == all_tables && first_table != 0);
1612
res = mysql_check_table(session, first_table, &lex->check_opt);
1613
select_lex->table_list.first= (unsigned char*) first_table;
1614
lex->query_tables=all_tables;
1617
case SQLCOM_ANALYZE:
1619
assert(first_table == all_tables && first_table != 0);
1620
res= mysql_analyze_table(session, first_table, &lex->check_opt);
1621
/* ! we write after unlocking the table */
1622
write_bin_log(session, true, session->query, session->query_length);
1623
select_lex->table_list.first= (unsigned char*) first_table;
1624
lex->query_tables=all_tables;
1628
case SQLCOM_OPTIMIZE:
1630
assert(first_table == all_tables && first_table != 0);
1631
res= mysql_optimize_table(session, first_table, &lex->check_opt);
1632
/* ! we write after unlocking the table */
1633
write_bin_log(session, true, session->query, session->query_length);
1634
select_lex->table_list.first= (unsigned char*) first_table;
1635
lex->query_tables=all_tables;
1639
assert(first_table == all_tables && first_table != 0);
1640
if (update_precheck(session, all_tables))
1642
assert(select_lex->offset_limit == 0);
1643
unit->set_limit(select_lex);
1644
res= (up_result= mysql_update(session, all_tables,
1645
select_lex->item_list,
1648
select_lex->order_list.elements,
1649
(order_st *) select_lex->order_list.first,
1650
unit->select_limit_cnt,
1651
lex->duplicates, lex->ignore));
1652
/* mysql_update return 2 if we need to switch to multi-update */
1656
case SQLCOM_UPDATE_MULTI:
1658
assert(first_table == all_tables && first_table != 0);
1659
/* if we switched from normal update, rights are checked */
1662
if ((res= multi_update_precheck(session, all_tables)))
1668
res= mysql_multi_update_prepare(session);
1670
/* Check slave filtering rules */
1671
if (unlikely(session->slave_thread))
1673
if (all_tables_not_ok(session, all_tables))
1677
res= 0; /* don't care of prev failure */
1678
session->clear_error(); /* filters are of highest prior */
1680
/* we warn the slave SQL thread */
1681
my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
1692
some_non_temp_table_to_be_updated(session, all_tables))
1694
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
1699
res= mysql_multi_update(session, all_tables,
1700
&select_lex->item_list,
1703
select_lex->options,
1704
lex->duplicates, lex->ignore, unit, select_lex);
1707
case SQLCOM_REPLACE:
1710
assert(first_table == all_tables && first_table != 0);
1711
if ((res= insert_precheck(session, all_tables)))
1714
if (!session->locked_tables &&
1715
!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
1721
res= mysql_insert(session, all_tables, lex->field_list, lex->many_values,
1722
lex->update_list, lex->value_list,
1723
lex->duplicates, lex->ignore);
1727
case SQLCOM_REPLACE_SELECT:
1728
case SQLCOM_INSERT_SELECT:
1730
select_result *sel_result;
1731
assert(first_table == all_tables && first_table != 0);
1732
if ((res= insert_precheck(session, all_tables)))
1735
/* Fix lock for first table */
1736
if (first_table->lock_type == TL_WRITE_DELAYED)
1737
first_table->lock_type= TL_WRITE;
1739
/* Don't unlock tables until command is written to binary log */
1740
select_lex->options|= SELECT_NO_UNLOCK;
1742
unit->set_limit(select_lex);
1744
if (! session->locked_tables &&
1745
! (need_start_waiting= ! wait_if_global_read_lock(session, 0, 1)))
1751
if (!(res= open_and_lock_tables(session, all_tables)))
1753
/* Skip first table, which is the table we are inserting in */
1754
TableList *second_table= first_table->next_local;
1755
select_lex->table_list.first= (unsigned char*) second_table;
1756
select_lex->context.table_list=
1757
select_lex->context.first_name_resolution_table= second_table;
1758
res= mysql_insert_select_prepare(session);
1759
if (!res && (sel_result= new select_insert(first_table,
1767
res= handle_select(session, lex, sel_result, OPTION_SETUP_TABLES_DONE);
1769
Invalidate the table in the query cache if something changed
1770
after unlocking when changes become visible.
1771
TODO: this is workaround. right way will be move invalidating in
1772
the unlock procedure.
1774
if (first_table->lock_type == TL_WRITE_CONCURRENT_INSERT &&
1777
/* INSERT ... SELECT should invalidate only the very first table */
1778
TableList *save_table= first_table->next_local;
1779
first_table->next_local= 0;
1780
first_table->next_local= save_table;
1784
/* revert changes for SP */
1785
select_lex->table_list.first= (unsigned char*) first_table;
1790
case SQLCOM_TRUNCATE:
1791
if (end_active_trans(session))
1796
assert(first_table == all_tables && first_table != 0);
1798
Don't allow this within a transaction because we want to use
1801
if (session->locked_tables || session->active_transaction())
1803
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
1804
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
1808
res= mysql_truncate(session, first_table, 0);
1813
assert(first_table == all_tables && first_table != 0);
1814
assert(select_lex->offset_limit == 0);
1815
unit->set_limit(select_lex);
1817
if (!session->locked_tables &&
1818
!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
1824
res = mysql_delete(session, all_tables, select_lex->where,
1825
&select_lex->order_list,
1826
unit->select_limit_cnt, select_lex->options,
1830
case SQLCOM_DELETE_MULTI:
1832
assert(first_table == all_tables && first_table != 0);
1833
TableList *aux_tables=
1834
(TableList *)session->lex->auxiliary_table_list.first;
1835
multi_delete *del_result;
1837
if (!session->locked_tables &&
1838
!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
1844
if ((res= multi_delete_precheck(session, all_tables)))
1847
/* condition will be true on SP re-excuting */
1848
if (select_lex->item_list.elements != 0)
1849
select_lex->item_list.empty();
1850
if (add_item_to_list(session, new Item_null()))
1853
session->set_proc_info("init");
1854
if ((res= open_and_lock_tables(session, all_tables)))
1857
if ((res= mysql_multi_delete_prepare(session)))
1860
if (!session->is_fatal_error &&
1861
(del_result= new multi_delete(aux_tables, lex->table_count)))
1863
res= mysql_select(session, &select_lex->ref_pointer_array,
1864
select_lex->get_table_list(),
1865
select_lex->with_wild,
1866
select_lex->item_list,
1868
0, (order_st *)NULL, (order_st *)NULL, (Item *)NULL,
1870
select_lex->options | session->options |
1871
SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
1872
OPTION_SETUP_TABLES_DONE,
1873
del_result, unit, select_lex);
1874
res|= session->is_error();
1876
del_result->abort();
1883
case SQLCOM_DROP_TABLE:
1885
assert(first_table == all_tables && first_table != 0);
1886
if (!lex->drop_temporary)
1888
if (end_active_trans(session))
1894
If this is a slave thread, we may sometimes execute some
1895
DROP / * 40005 TEMPORARY * / TABLE
1896
that come from parts of binlogs (likely if we use RESET SLAVE or CHANGE
1897
MASTER TO), while the temporary table has already been dropped.
1898
To not generate such irrelevant "table does not exist errors",
1899
we silently add IF EXISTS if TEMPORARY was used.
1901
if (session->slave_thread)
1902
lex->drop_if_exists= 1;
1904
/* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
1905
session->options|= OPTION_KEEP_LOG;
1907
/* DDL and binlog write order protected by LOCK_open */
1908
res= mysql_rm_table(session, first_table, lex->drop_if_exists, lex->drop_temporary);
1911
case SQLCOM_SHOW_PROCESSLIST:
1912
mysqld_list_processes(session, NULL, lex->verbose);
1914
case SQLCOM_SHOW_ENGINE_LOGS:
1916
res= ha_show_status(session, lex->create_info.db_type, HA_ENGINE_LOGS);
1919
case SQLCOM_CHANGE_DB:
1921
LEX_STRING db_str= { (char *) select_lex->db, strlen(select_lex->db) };
1923
if (!mysql_change_db(session, &db_str, false))
1931
assert(first_table == all_tables && first_table != 0);
1932
if (lex->local_file)
1934
if (!(session->client_capabilities & CLIENT_LOCAL_FILES) ||
1937
my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), MYF(0));
1942
res= mysql_load(session, lex->exchange, first_table, lex->field_list,
1943
lex->update_list, lex->value_list, lex->duplicates,
1944
lex->ignore, (bool) lex->local_file);
1948
case SQLCOM_SET_OPTION:
1950
List<set_var_base> *lex_var_list= &lex->var_list;
1952
if (lex->autocommit && end_active_trans(session))
1955
if (open_and_lock_tables(session, all_tables))
1957
if (!(res= sql_set_variables(session, lex_var_list)))
1964
We encountered some sort of error, but no message was sent.
1965
Send something semi-generic here since we don't know which
1966
assignment in the list caused the error.
1968
if (!session->is_error())
1969
my_error(ER_WRONG_ARGUMENTS,MYF(0),"SET");
1976
case SQLCOM_UNLOCK_TABLES:
1978
It is critical for mysqldump --single-transaction --master-data that
1979
UNLOCK TABLES does not implicitely commit a connection which has only
1980
done FLUSH TABLES WITH READ LOCK + BEGIN. If this assumption becomes
1981
false, mysqldump will not work.
1983
unlock_locked_tables(session);
1984
if (session->options & OPTION_TABLE_LOCK)
1986
end_active_trans(session);
1987
session->options&= ~(OPTION_TABLE_LOCK);
1989
if (session->global_read_lock)
1990
unlock_global_read_lock(session);
1993
case SQLCOM_LOCK_TABLES:
1995
We try to take transactional locks if
1996
- only transactional locks are requested (lex->lock_transactional) and
1997
- no non-transactional locks exist (!session->locked_tables).
1999
if (lex->lock_transactional && !session->locked_tables)
2003
All requested locks are transactional and no non-transactional
2006
if ((rc= try_transactional_lock(session, all_tables)) == -1)
2014
Non-transactional locking has been requested or
2015
non-transactional locks exist already or transactional locks are
2016
not supported by all storage engines. Take non-transactional
2021
One or more requested locks are non-transactional and/or
2022
non-transactional locks exist or a storage engine does not support
2023
transactional locks. Check if at least one transactional lock is
2024
requested. If yes, warn about the conversion to non-transactional
2025
locks or abort in strict mode.
2027
if (check_transactional_lock(session, all_tables))
2029
unlock_locked_tables(session);
2030
/* we must end the trasaction first, regardless of anything */
2031
if (end_active_trans(session))
2033
session->in_lock_tables=1;
2034
session->options|= OPTION_TABLE_LOCK;
2036
if (!(res= simple_open_n_lock_tables(session, all_tables)))
2038
session->locked_tables=session->lock;
2040
(void) set_handler_table_locks(session, all_tables, false);
2046
Need to end the current transaction, so the storage engine (InnoDB)
2047
can free its locks if LOCK TABLES locked some tables before finding
2048
that it can't lock a table in its list
2050
ha_autocommit_or_rollback(session, 1);
2051
end_active_trans(session);
2052
session->options&= ~(OPTION_TABLE_LOCK);
2054
session->in_lock_tables=0;
2056
case SQLCOM_CREATE_DB:
2059
As mysql_create_db() may modify HA_CREATE_INFO structure passed to
2060
it, we need to use a copy of LEX::create_info to make execution
2061
prepared statement- safe.
2063
HA_CREATE_INFO create_info(lex->create_info);
2064
if (end_active_trans(session))
2070
if (!(alias=session->strmake(lex->name.str, lex->name.length)) ||
2071
check_db_name(&lex->name))
2073
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
2076
res= mysql_create_db(session,(lower_case_table_names == 2 ? alias :
2077
lex->name.str), &create_info, 0);
2080
case SQLCOM_DROP_DB:
2082
if (end_active_trans(session))
2087
if (check_db_name(&lex->name))
2089
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
2092
if (session->locked_tables || session->active_transaction())
2094
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
2095
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
2098
res= mysql_rm_db(session, lex->name.str, lex->drop_if_exists, 0);
2101
case SQLCOM_ALTER_DB:
2103
LEX_STRING *db= &lex->name;
2104
HA_CREATE_INFO create_info(lex->create_info);
2105
if (check_db_name(db))
2107
my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
2110
if (session->locked_tables || session->active_transaction())
2112
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
2113
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
2116
res= mysql_alter_db(session, db->str, &create_info);
2119
case SQLCOM_SHOW_CREATE_DB:
2121
if (check_db_name(&lex->name))
2123
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
2126
res= mysqld_show_create_db(session, lex->name.str, &lex->create_info);
2132
bool write_to_binlog;
2135
reload_cache() will tell us if we are allowed to write to the
2138
if (!reload_cache(session, lex->type, first_table, &write_to_binlog))
2141
We WANT to write and we CAN write.
2142
! we write after unlocking the table.
2145
Presumably, RESET and binlog writing doesn't require synchronization
2147
write_bin_log(session, false, session->query, session->query_length);
2155
Item *it= (Item *)lex->value_list.head();
2157
if (lex->table_or_sp_used())
2159
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "Usage of subqueries or stored "
2160
"function calls as part of this statement");
2164
if ((!it->fixed && it->fix_fields(lex->session, &it)) || it->check_cols(1))
2166
my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
2170
sql_kill(session, (ulong)it->val_int(), lex->type & ONLY_KILL_QUERY);
2174
if (session->transaction.xid_state.xa_state != XA_NOTR)
2176
my_error(ER_XAER_RMFAIL, MYF(0),
2177
xa_state_names[session->transaction.xid_state.xa_state]);
2181
Breakpoints for backup testing.
2183
if (begin_trans(session))
2188
if (end_trans(session, lex->tx_release ? COMMIT_RELEASE :
2189
lex->tx_chain ? COMMIT_AND_CHAIN : COMMIT))
2193
case SQLCOM_ROLLBACK:
2194
if (end_trans(session, lex->tx_release ? ROLLBACK_RELEASE :
2195
lex->tx_chain ? ROLLBACK_AND_CHAIN : ROLLBACK))
2199
case SQLCOM_RELEASE_SAVEPOINT:
2202
for (sv=session->transaction.savepoints; sv; sv=sv->prev)
2204
if (my_strnncoll(system_charset_info,
2205
(unsigned char *)lex->ident.str, lex->ident.length,
2206
(unsigned char *)sv->name, sv->length) == 0)
2211
if (ha_release_savepoint(session, sv))
2212
res= true; // cannot happen
2215
session->transaction.savepoints=sv->prev;
2218
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
2221
case SQLCOM_ROLLBACK_TO_SAVEPOINT:
2224
for (sv=session->transaction.savepoints; sv; sv=sv->prev)
2226
if (my_strnncoll(system_charset_info,
2227
(unsigned char *)lex->ident.str, lex->ident.length,
2228
(unsigned char *)sv->name, sv->length) == 0)
2233
if (ha_rollback_to_savepoint(session, sv))
2234
res= true; // cannot happen
2237
if (((session->options & OPTION_KEEP_LOG) ||
2238
session->transaction.all.modified_non_trans_table) &&
2239
!session->slave_thread)
2240
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2241
ER_WARNING_NOT_COMPLETE_ROLLBACK,
2242
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
2245
session->transaction.savepoints=sv;
2248
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
2251
case SQLCOM_SAVEPOINT:
2252
if (!(session->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) || !opt_using_transactions)
2256
SAVEPOINT **sv, *newsv;
2257
for (sv=&session->transaction.savepoints; *sv; sv=&(*sv)->prev)
2259
if (my_strnncoll(system_charset_info,
2260
(unsigned char *)lex->ident.str, lex->ident.length,
2261
(unsigned char *)(*sv)->name, (*sv)->length) == 0)
2264
if (*sv) /* old savepoint of the same name exists */
2267
ha_release_savepoint(session, *sv); // it cannot fail
2270
else if ((newsv=(SAVEPOINT *) alloc_root(&session->transaction.mem_root,
2271
savepoint_alloc_size)) == 0)
2273
my_error(ER_OUT_OF_RESOURCES, MYF(0));
2276
newsv->name=strmake_root(&session->transaction.mem_root,
2277
lex->ident.str, lex->ident.length);
2278
newsv->length=lex->ident.length;
2280
if we'll get an error here, don't add new savepoint to the list.
2281
we'll lose a little bit of memory in transaction mem_root, but it'll
2282
be free'd when transaction ends anyway
2284
if (ha_savepoint(session, newsv))
2288
newsv->prev=session->transaction.savepoints;
2289
session->transaction.savepoints=newsv;
2294
case SQLCOM_BINLOG_BASE64_EVENT:
2296
mysql_client_binlog_statement(session);
2300
assert(0); /* Impossible */
492
if (all_tables || ! session->lex().is_single_level_stmt())
494
drizzle_reset_errors(*session, 0);
497
assert(not session->transaction.stmt.hasModifiedNonTransData());
499
if (! (session->server_status & SERVER_STATUS_AUTOCOMMIT)
500
&& ! session->inTransaction()
501
&& session->lex().statement->isTransactional())
503
if (not session->startTransaction())
505
my_error(drizzled::ER_UNKNOWN_ERROR, MYF(0));
510
/* now we are ready to execute the statement */
511
res= session->lex().statement->execute();
2304
512
session->set_proc_info("query end");
2307
514
The return value for ROW_COUNT() is "implementation dependent" if the
2308
515
statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC
2309
516
wants. We also keep the last value in case of SQLCOM_CALL or
2312
if (!(sql_command_flags[lex->sql_command].test(CF_BIT_HAS_ROW_COUNT)))
519
if (! (sql_command_flags[session->lex().sql_command].test(CF_BIT_HAS_ROW_COUNT)))
2313
521
session->row_count_func= -1;
2321
if (need_start_waiting)
2324
Release the protection against the global read lock and wake
2325
everyone, who might want to set a global read lock.
2327
start_waiting_global_read_lock(session);
2329
return(res || session->is_error());
524
return (res || session->is_error());
2332
526
bool execute_sqlcom_select(Session *session, TableList *all_tables)
2334
LEX *lex= session->lex;
528
LEX *lex= &session->lex();
2335
529
select_result *result=lex->result;
2337
531
/* assign global limit variable if limit is not given */
2339
SELECT_LEX *param= lex->unit.global_parameters;
533
Select_Lex *param= lex->unit.global_parameters;
2340
534
if (!param->explicit_limit)
2341
535
param->select_limit=
2342
536
new Item_int((uint64_t) session->variables.select_limit);
2344
if (!(res= open_and_lock_tables(session, all_tables)))
540
&& ! (session->server_status & SERVER_STATUS_AUTOCOMMIT)
541
&& ! session->inTransaction()
542
&& ! lex->statement->isShow())
544
if (not session->startTransaction())
546
my_error(drizzled::ER_UNKNOWN_ERROR, MYF(0));
551
if (not (res= session->openTablesLock(all_tables)))
2346
553
if (lex->describe)