1
/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
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 */
17
#include "mysql_priv.h"
19
#include "rpl_filter.h"
20
#include "repl_failsafe.h"
29
#include "sql_trigger.h"
32
@defgroup Runtime_Environment Runtime Environment
36
/* Used in error handling only */
37
#define SP_TYPE_STRING(LP) \
38
((LP)->sphead->m_type == TYPE_ENUM_FUNCTION ? "FUNCTION" : "PROCEDURE")
39
#define SP_COM_STRING(LP) \
40
((LP)->sql_command == SQLCOM_CREATE_SPFUNCTION || \
41
(LP)->sql_command == SQLCOM_ALTER_FUNCTION || \
42
(LP)->sql_command == SQLCOM_SHOW_CREATE_FUNC || \
43
(LP)->sql_command == SQLCOM_DROP_FUNCTION ? \
44
"FUNCTION" : "PROCEDURE")
46
static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables);
47
static bool check_show_create_table_access(THD *thd, TABLE_LIST *table);
49
const char *any_db="*any*"; // Special symbol for check_access
51
const LEX_STRING command_name[]={
52
{ C_STRING_WITH_LEN("Sleep") },
53
{ C_STRING_WITH_LEN("Quit") },
54
{ C_STRING_WITH_LEN("Init DB") },
55
{ C_STRING_WITH_LEN("Query") },
56
{ C_STRING_WITH_LEN("Field List") },
57
{ C_STRING_WITH_LEN("Create DB") },
58
{ C_STRING_WITH_LEN("Drop DB") },
59
{ C_STRING_WITH_LEN("Refresh") },
60
{ C_STRING_WITH_LEN("Shutdown") },
61
{ C_STRING_WITH_LEN("Statistics") },
62
{ C_STRING_WITH_LEN("Processlist") },
63
{ C_STRING_WITH_LEN("Connect") },
64
{ C_STRING_WITH_LEN("Kill") },
65
{ C_STRING_WITH_LEN("Debug") },
66
{ C_STRING_WITH_LEN("Ping") },
67
{ C_STRING_WITH_LEN("Time") },
68
{ C_STRING_WITH_LEN("Delayed insert") },
69
{ C_STRING_WITH_LEN("Change user") },
70
{ C_STRING_WITH_LEN("Binlog Dump") },
71
{ C_STRING_WITH_LEN("Table Dump") },
72
{ C_STRING_WITH_LEN("Connect Out") },
73
{ C_STRING_WITH_LEN("Register Slave") },
74
{ C_STRING_WITH_LEN("Prepare") },
75
{ C_STRING_WITH_LEN("Execute") },
76
{ C_STRING_WITH_LEN("Long Data") },
77
{ C_STRING_WITH_LEN("Close stmt") },
78
{ C_STRING_WITH_LEN("Reset stmt") },
79
{ C_STRING_WITH_LEN("Set option") },
80
{ C_STRING_WITH_LEN("Fetch") },
81
{ C_STRING_WITH_LEN("Daemon") },
82
{ C_STRING_WITH_LEN("Error") } // Last command number
85
const char *xa_state_names[]={
86
"NON-EXISTING", "ACTIVE", "IDLE", "PREPARED", "ROLLBACK ONLY"
90
Mark a XA transaction as rollback-only if the RM unilaterally
91
rolled back the transaction branch.
93
@note If a rollback was requested by the RM, this function sets
94
the appropriate rollback error code and transits the state
97
@return TRUE if transaction was rolled back or if the transaction
98
state is XA_ROLLBACK_ONLY. FALSE otherwise.
100
static bool xa_trans_rolled_back(XID_STATE *xid_state)
102
if (xid_state->rm_error)
104
switch (xid_state->rm_error) {
105
case ER_LOCK_WAIT_TIMEOUT:
106
my_error(ER_XA_RBTIMEOUT, MYF(0));
108
case ER_LOCK_DEADLOCK:
109
my_error(ER_XA_RBDEADLOCK, MYF(0));
112
my_error(ER_XA_RBROLLBACK, MYF(0));
114
xid_state->xa_state= XA_ROLLBACK_ONLY;
117
return (xid_state->xa_state == XA_ROLLBACK_ONLY);
121
Rollback work done on behalf of at ransaction branch.
123
static bool xa_trans_rollback(THD *thd)
126
Resource Manager error is meaningless at this point, as we perform
127
explicit rollback request by user. We must reset rm_error before
128
calling ha_rollback(), so thd->transaction.xid structure gets reset
129
by ha_rollback()/THD::transaction::cleanup().
131
thd->transaction.xid_state.rm_error= 0;
133
bool status= test(ha_rollback(thd));
135
thd->options&= ~(ulong) OPTION_BEGIN;
136
thd->transaction.all.modified_non_trans_table= FALSE;
137
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
138
xid_cache_delete(&thd->transaction.xid_state);
139
thd->transaction.xid_state.xa_state= XA_NOTR;
144
static void unlock_locked_tables(THD *thd)
146
if (thd->locked_tables)
148
thd->lock=thd->locked_tables;
149
thd->locked_tables=0; // Will be automatically closed
150
close_thread_tables(thd); // Free tables
155
bool end_active_trans(THD *thd)
158
DBUG_ENTER("end_active_trans");
159
if (unlikely(thd->in_sub_stmt))
161
my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
164
if (thd->transaction.xid_state.xa_state != XA_NOTR)
166
my_error(ER_XAER_RMFAIL, MYF(0),
167
xa_state_names[thd->transaction.xid_state.xa_state]);
170
if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN |
173
DBUG_PRINT("info",("options: 0x%llx", thd->options));
174
/* Safety if one did "drop table" on locked tables */
175
if (!thd->locked_tables)
176
thd->options&= ~OPTION_TABLE_LOCK;
177
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
181
thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
182
thd->transaction.all.modified_non_trans_table= FALSE;
187
bool begin_trans(THD *thd)
190
if (unlikely(thd->in_sub_stmt))
192
my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
195
if (thd->locked_tables)
197
thd->lock=thd->locked_tables;
198
thd->locked_tables=0; // Will be automatically closed
199
close_thread_tables(thd); // Free tables
201
if (end_active_trans(thd))
205
thd->options|= OPTION_BEGIN;
206
thd->server_status|= SERVER_STATUS_IN_TRANS;
211
#ifdef HAVE_REPLICATION
213
Returns true if all tables should be ignored.
215
inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables)
217
return rpl_filter->is_on() && tables && !thd->spcont &&
218
!rpl_filter->tables_ok(thd->db, tables);
223
static bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables)
225
for (TABLE_LIST *table= tables; table; table= table->next_global)
227
DBUG_ASSERT(table->db && table->table_name);
228
if (table->updating &&
229
!find_temporary_table(thd, table->db, table->table_name))
237
Mark all commands that somehow changes a table.
239
This is used to check number of updates / hour.
241
sql_command is actually set to SQLCOM_END sometimes
242
so we need the +1 to include it in the array.
244
See COMMAND_FLAG_xxx for different type of commands
245
2 - query that returns meaningful ROW_COUNT() -
246
a number of modified rows
249
uint sql_command_flags[SQLCOM_END+1];
251
void init_update_queries(void)
253
bzero((uchar*) &sql_command_flags, sizeof(sql_command_flags));
255
sql_command_flags[SQLCOM_CREATE_TABLE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE;
256
sql_command_flags[SQLCOM_CREATE_INDEX]= CF_CHANGES_DATA;
257
sql_command_flags[SQLCOM_ALTER_TABLE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND;
258
sql_command_flags[SQLCOM_TRUNCATE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND;
259
sql_command_flags[SQLCOM_DROP_TABLE]= CF_CHANGES_DATA;
260
sql_command_flags[SQLCOM_LOAD]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE;
261
sql_command_flags[SQLCOM_CREATE_DB]= CF_CHANGES_DATA;
262
sql_command_flags[SQLCOM_DROP_DB]= CF_CHANGES_DATA;
263
sql_command_flags[SQLCOM_RENAME_TABLE]= CF_CHANGES_DATA;
264
sql_command_flags[SQLCOM_BACKUP_TABLE]= CF_CHANGES_DATA;
265
sql_command_flags[SQLCOM_RESTORE_TABLE]= CF_CHANGES_DATA;
266
sql_command_flags[SQLCOM_DROP_INDEX]= CF_CHANGES_DATA;
267
sql_command_flags[SQLCOM_CREATE_VIEW]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE;
268
sql_command_flags[SQLCOM_DROP_VIEW]= CF_CHANGES_DATA;
269
sql_command_flags[SQLCOM_CREATE_EVENT]= CF_CHANGES_DATA;
270
sql_command_flags[SQLCOM_ALTER_EVENT]= CF_CHANGES_DATA;
271
sql_command_flags[SQLCOM_DROP_EVENT]= CF_CHANGES_DATA;
273
sql_command_flags[SQLCOM_UPDATE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
274
CF_REEXECUTION_FRAGILE;
275
sql_command_flags[SQLCOM_UPDATE_MULTI]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
276
CF_REEXECUTION_FRAGILE;
277
sql_command_flags[SQLCOM_INSERT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
278
CF_REEXECUTION_FRAGILE;
279
sql_command_flags[SQLCOM_INSERT_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
280
CF_REEXECUTION_FRAGILE;
281
sql_command_flags[SQLCOM_DELETE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
282
CF_REEXECUTION_FRAGILE;
283
sql_command_flags[SQLCOM_DELETE_MULTI]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
284
CF_REEXECUTION_FRAGILE;
285
sql_command_flags[SQLCOM_REPLACE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
286
CF_REEXECUTION_FRAGILE;
287
sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
288
CF_REEXECUTION_FRAGILE;
289
sql_command_flags[SQLCOM_SELECT]= CF_REEXECUTION_FRAGILE;
290
sql_command_flags[SQLCOM_SET_OPTION]= CF_REEXECUTION_FRAGILE;
291
sql_command_flags[SQLCOM_DO]= CF_REEXECUTION_FRAGILE;
293
sql_command_flags[SQLCOM_SHOW_STATUS_PROC]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
294
sql_command_flags[SQLCOM_SHOW_STATUS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
295
sql_command_flags[SQLCOM_SHOW_DATABASES]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
296
sql_command_flags[SQLCOM_SHOW_TRIGGERS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
297
sql_command_flags[SQLCOM_SHOW_EVENTS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
298
sql_command_flags[SQLCOM_SHOW_OPEN_TABLES]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
299
sql_command_flags[SQLCOM_SHOW_PLUGINS]= CF_STATUS_COMMAND;
300
sql_command_flags[SQLCOM_SHOW_FIELDS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
301
sql_command_flags[SQLCOM_SHOW_KEYS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
302
sql_command_flags[SQLCOM_SHOW_VARIABLES]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
303
sql_command_flags[SQLCOM_SHOW_CHARSETS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
304
sql_command_flags[SQLCOM_SHOW_COLLATIONS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
305
sql_command_flags[SQLCOM_SHOW_NEW_MASTER]= CF_STATUS_COMMAND;
306
sql_command_flags[SQLCOM_SHOW_BINLOGS]= CF_STATUS_COMMAND;
307
sql_command_flags[SQLCOM_SHOW_SLAVE_HOSTS]= CF_STATUS_COMMAND;
308
sql_command_flags[SQLCOM_SHOW_BINLOG_EVENTS]= CF_STATUS_COMMAND;
309
sql_command_flags[SQLCOM_SHOW_COLUMN_TYPES]= CF_STATUS_COMMAND;
310
sql_command_flags[SQLCOM_SHOW_STORAGE_ENGINES]= CF_STATUS_COMMAND;
311
sql_command_flags[SQLCOM_SHOW_AUTHORS]= CF_STATUS_COMMAND;
312
sql_command_flags[SQLCOM_SHOW_CONTRIBUTORS]= CF_STATUS_COMMAND;
313
sql_command_flags[SQLCOM_SHOW_PRIVILEGES]= CF_STATUS_COMMAND;
314
sql_command_flags[SQLCOM_SHOW_WARNS]= CF_STATUS_COMMAND;
315
sql_command_flags[SQLCOM_SHOW_ERRORS]= CF_STATUS_COMMAND;
316
sql_command_flags[SQLCOM_SHOW_ENGINE_STATUS]= CF_STATUS_COMMAND;
317
sql_command_flags[SQLCOM_SHOW_ENGINE_MUTEX]= CF_STATUS_COMMAND;
318
sql_command_flags[SQLCOM_SHOW_ENGINE_LOGS]= CF_STATUS_COMMAND;
319
sql_command_flags[SQLCOM_SHOW_PROCESSLIST]= CF_STATUS_COMMAND;
320
sql_command_flags[SQLCOM_SHOW_GRANTS]= CF_STATUS_COMMAND;
321
sql_command_flags[SQLCOM_SHOW_CREATE_DB]= CF_STATUS_COMMAND;
322
sql_command_flags[SQLCOM_SHOW_CREATE]= CF_STATUS_COMMAND;
323
sql_command_flags[SQLCOM_SHOW_MASTER_STAT]= CF_STATUS_COMMAND;
324
sql_command_flags[SQLCOM_SHOW_SLAVE_STAT]= CF_STATUS_COMMAND;
325
sql_command_flags[SQLCOM_SHOW_CREATE_PROC]= CF_STATUS_COMMAND;
326
sql_command_flags[SQLCOM_SHOW_CREATE_FUNC]= CF_STATUS_COMMAND;
327
sql_command_flags[SQLCOM_SHOW_CREATE_TRIGGER]= CF_STATUS_COMMAND;
328
sql_command_flags[SQLCOM_SHOW_STATUS_FUNC]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
329
sql_command_flags[SQLCOM_SHOW_PROC_CODE]= CF_STATUS_COMMAND;
330
sql_command_flags[SQLCOM_SHOW_FUNC_CODE]= CF_STATUS_COMMAND;
331
sql_command_flags[SQLCOM_SHOW_CREATE_EVENT]= CF_STATUS_COMMAND;
332
sql_command_flags[SQLCOM_SHOW_PROFILES]= CF_STATUS_COMMAND;
333
sql_command_flags[SQLCOM_SHOW_PROFILE]= CF_STATUS_COMMAND;
335
sql_command_flags[SQLCOM_SHOW_TABLES]= (CF_STATUS_COMMAND |
336
CF_SHOW_TABLE_COMMAND |
337
CF_REEXECUTION_FRAGILE);
338
sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]= (CF_STATUS_COMMAND |
339
CF_SHOW_TABLE_COMMAND |
340
CF_REEXECUTION_FRAGILE);
343
The following is used to preserver CF_ROW_COUNT during the
344
a CALL or EXECUTE statement, so the value generated by the
345
last called (or executed) statement is preserved.
346
See mysql_execute_command() for how CF_ROW_COUNT is used.
348
sql_command_flags[SQLCOM_CALL]= CF_HAS_ROW_COUNT | CF_REEXECUTION_FRAGILE;
349
sql_command_flags[SQLCOM_EXECUTE]= CF_HAS_ROW_COUNT;
352
The following admin table operations are allowed
355
sql_command_flags[SQLCOM_REPAIR]= CF_WRITE_LOGS_COMMAND;
356
sql_command_flags[SQLCOM_OPTIMIZE]= CF_WRITE_LOGS_COMMAND;
357
sql_command_flags[SQLCOM_ANALYZE]= CF_WRITE_LOGS_COMMAND;
361
bool is_update_query(enum enum_sql_command command)
363
DBUG_ASSERT(command >= 0 && command <= SQLCOM_END);
364
return (sql_command_flags[command] & CF_CHANGES_DATA) != 0;
368
Check if a sql command is allowed to write to log tables.
369
@param command The SQL command
370
@return true if writing is allowed
372
bool is_log_table_write_query(enum enum_sql_command command)
374
DBUG_ASSERT(command >= 0 && command <= SQLCOM_END);
375
return (sql_command_flags[command] & CF_WRITE_LOGS_COMMAND) != 0;
378
void execute_init_command(THD *thd, sys_var_str *init_command_var,
379
rw_lock_t *var_mutex)
382
ulong save_client_capabilities;
384
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
385
thd->profiling.start_new_query();
386
thd->profiling.set_query_source(init_command_var->value,
387
init_command_var->value_length);
390
thd_proc_info(thd, "Execution of init_command");
392
We need to lock init_command_var because
393
during execution of init_command_var query
394
values of init_command_var can't be changed
396
rw_rdlock(var_mutex);
397
save_client_capabilities= thd->client_capabilities;
398
thd->client_capabilities|= CLIENT_MULTI_QUERIES;
400
We don't need return result of execution to client side.
401
To forbid this we should set thd->net.vio to 0.
403
save_vio= thd->net.vio;
405
dispatch_command(COM_QUERY, thd,
406
init_command_var->value,
407
init_command_var->value_length);
408
rw_unlock(var_mutex);
409
thd->client_capabilities= save_client_capabilities;
410
thd->net.vio= save_vio;
412
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
413
thd->profiling.finish_current_query();
418
static void handle_bootstrap_impl(THD *thd)
420
FILE *file=bootstrap_file;
422
const char* found_semicolon= NULL;
424
DBUG_ENTER("handle_bootstrap");
426
#ifndef EMBEDDED_LIBRARY
427
pthread_detach_this_thread();
428
thd->thread_stack= (char*) &thd;
429
#endif /* EMBEDDED_LIBRARY */
431
if (thd->variables.max_join_size == HA_POS_ERROR)
432
thd->options |= OPTION_BIG_SELECTS;
434
thd_proc_info(thd, 0);
435
thd->version=refresh_version;
436
thd->security_ctx->priv_user=
437
thd->security_ctx->user= (char*) my_strdup("boot", MYF(MY_WME));
438
thd->security_ctx->priv_host[0]=0;
440
Make the "client" handle multiple results. This is necessary
441
to enable stored procedures with SELECTs and Dynamic SQL
444
thd->client_capabilities|= CLIENT_MULTI_RESULTS;
446
buff= (char*) thd->net.buff;
447
thd->init_for_queries();
448
while (fgets(buff, thd->net.max_packet, file))
451
/* strlen() can't be deleted because fgets() doesn't return length */
452
ulong length= (ulong) strlen(buff);
453
while (buff[length-1] != '\n' && !feof(file))
456
We got only a part of the current string. Will try to increase
457
net buffer then read the rest of the current string.
459
/* purecov: begin tested */
460
if (net_realloc(&(thd->net), 2 * thd->net.max_packet))
462
net_end_statement(thd);
466
buff= (char*) thd->net.buff;
467
res= fgets(buff + length, thd->net.max_packet - length, file);
468
length+= (ulong) strlen(buff + length);
472
break; /* purecov: inspected */
474
while (length && (my_isspace(thd->charset(), buff[length-1]) ||
475
buff[length-1] == ';'))
479
/* Skip lines starting with delimiter */
480
if (strncmp(buff, STRING_WITH_LEN("delimiter")) == 0)
483
query= (char *) thd->memdup_w_gap(buff, length + 1,
485
QUERY_CACHE_FLAGS_SIZE);
486
thd->set_query(query, length);
487
DBUG_PRINT("query",("%-.4096s", thd->query()));
488
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
489
thd->profiling.start_new_query();
490
thd->profiling.set_query_source(thd->query(), length);
494
We don't need to obtain LOCK_thread_count here because in bootstrap
495
mode we have only one thread.
497
thd->query_id=next_query_id();
499
mysql_parse(thd, thd->query(), length, & found_semicolon);
500
close_thread_tables(thd); // Free tables
502
bootstrap_error= thd->is_error();
503
net_end_statement(thd);
505
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
506
thd->profiling.finish_current_query();
512
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
513
#ifdef USING_TRANSACTIONS
514
free_root(&thd->transaction.mem_root,MYF(MY_KEEP_PREALLOC));
523
Execute commands from bootstrap_file.
525
Used when creating the initial grant tables.
528
pthread_handler_t handle_bootstrap(void *arg)
532
/* The following must be called before DBUG_ENTER */
533
thd->thread_stack= (char*) &thd;
534
if (my_thread_init() || thd->store_globals())
536
#ifndef EMBEDDED_LIBRARY
537
close_connection(thd, ER_OUT_OF_RESOURCES, 1);
543
handle_bootstrap_impl(thd);
550
#ifndef EMBEDDED_LIBRARY
551
(void) pthread_mutex_lock(&LOCK_thread_count);
554
(void) pthread_cond_broadcast(&COND_thread_count);
555
(void) pthread_mutex_unlock(&LOCK_thread_count);
565
@brief Check access privs for a MERGE table and fix children lock types.
567
@param[in] thd thread handle
568
@param[in] db database name
569
@param[in,out] table_list list of child tables (merge_list)
570
lock_type and optionally db set per table
577
This function is used for write access to MERGE tables only
578
(CREATE TABLE, ALTER TABLE ... UNION=(...)). Set TL_WRITE for
579
every child. Set 'db' for every child if not present.
581
#ifndef NO_EMBEDDED_ACCESS_CHECKS
582
static bool check_merge_table_access(THD *thd, char *db,
583
TABLE_LIST *table_list)
589
/* Check that all tables use the current database */
592
for (tlist= table_list; tlist; tlist= tlist->next_local)
594
if (!tlist->db || !tlist->db[0])
595
tlist->db= db; /* purecov: inspected */
597
error= check_table_access(thd, SELECT_ACL | UPDATE_ACL | DELETE_ACL,
598
table_list, UINT_MAX, FALSE);
604
/* This works because items are allocated with sql_alloc() */
606
void free_items(Item *item)
609
DBUG_ENTER("free_items");
610
for (; item ; item=next)
619
This works because items are allocated with sql_alloc().
620
@note The function also handles null pointers (empty list).
622
void cleanup_items(Item *item)
624
DBUG_ENTER("cleanup_items");
625
for (; item ; item=item->next)
631
Handle COM_TABLE_DUMP command.
633
@param thd thread handle
634
@param db database name or an empty string. If empty,
635
the current database of the connection is used
636
@param tbl_name name of the table to dump
639
This function is written to handle one specific command only.
644
1 error, the error message is set in THD
648
int mysql_table_dump(THD *thd, LEX_STRING *db, char *tbl_name)
651
TABLE_LIST* table_list;
653
DBUG_ENTER("mysql_table_dump");
656
db->str= thd->db; /* purecov: inspected */
657
db->length= thd->db_length; /* purecov: inspected */
659
if (!(table_list = (TABLE_LIST*) thd->calloc(sizeof(TABLE_LIST))))
660
DBUG_RETURN(1); // out of memory
661
table_list->db= db->str;
662
table_list->table_name= table_list->alias= tbl_name;
663
table_list->lock_type= TL_READ_NO_INSERT;
664
table_list->prev_global= &table_list; // can be removed after merge with 4.1
666
if (check_db_name(db))
668
/* purecov: begin inspected */
669
my_error(ER_WRONG_DB_NAME ,MYF(0), db->str ? db->str : "NULL");
673
if (lower_case_table_names)
674
my_casedn_str(files_charset_info, tbl_name);
676
if (!(table=open_ltable(thd, table_list, TL_READ_NO_INSERT, 0)))
679
if (check_one_table_access(thd, SELECT_ACL, table_list))
682
thd->set_query(tbl_name, (uint) strlen(tbl_name));
683
if ((error = mysqld_dump_create_info(thd, table_list, -1)))
685
my_error(ER_GET_ERRNO, MYF(0), my_errno);
688
net_flush(&thd->net);
689
if ((error= table->file->dump(thd,-1)))
690
my_error(ER_GET_ERRNO, MYF(0), error);
697
Ends the current transaction and (maybe) begin the next.
699
@param thd Current thread
700
@param completion Completion type
706
int end_trans(THD *thd, enum enum_mysql_completiontype completion)
710
DBUG_ENTER("end_trans");
712
if (unlikely(thd->in_sub_stmt))
714
my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
717
if (thd->transaction.xid_state.xa_state != XA_NOTR)
719
my_error(ER_XAER_RMFAIL, MYF(0),
720
xa_state_names[thd->transaction.xid_state.xa_state]);
723
switch (completion) {
726
We don't use end_active_trans() here to ensure that this works
727
even if there is a problem with the OPTION_AUTO_COMMIT flag
728
(Which of course should never happen...)
730
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
732
thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
733
thd->transaction.all.modified_non_trans_table= FALSE;
736
do_release= 1; /* fall through */
737
case COMMIT_AND_CHAIN:
738
res= end_active_trans(thd);
739
if (!res && completion == COMMIT_AND_CHAIN)
740
res= begin_trans(thd);
742
case ROLLBACK_RELEASE:
743
do_release= 1; /* fall through */
745
case ROLLBACK_AND_CHAIN:
747
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
748
if (ha_rollback(thd))
750
thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
751
thd->transaction.all.modified_non_trans_table= FALSE;
752
if (!res && (completion == ROLLBACK_AND_CHAIN))
753
res= begin_trans(thd);
758
my_error(ER_UNKNOWN_COM_ERROR, MYF(0));
763
my_error(thd->killed_errno(), MYF(0));
764
else if ((res == 0) && do_release)
765
thd->killed= THD::KILL_CONNECTION;
770
#ifndef EMBEDDED_LIBRARY
773
Read one command from connection and execute it (query or simple command).
774
This function is called in loop from thread function.
776
For profiling to work, it must never be called recursively.
781
1 request of thread shutdown (see dispatch_command() description)
784
bool do_command(THD *thd)
790
enum enum_server_command command;
791
DBUG_ENTER("do_command");
794
indicator of uninitialized lex => normal flow of errors handling
797
thd->lex->current_select= 0;
800
This thread will do a blocking read from the client which
801
will be interrupted when the next command is received from
802
the client, the connection is closed or "net_wait_timeout"
803
number of seconds has passed
805
my_net_set_read_timeout(net, thd->variables.net_wait_timeout);
808
XXX: this code is here only to clear possible errors of init_connect.
809
Consider moving to init_connect() instead.
811
thd->clear_error(); // Clear error message
812
thd->main_da.reset_diagnostics_area();
814
net_new_transaction(net);
816
packet_length= my_net_read(net);
817
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
818
thd->profiling.start_new_query();
820
if (packet_length == packet_error)
822
DBUG_PRINT("info",("Got error %d reading command from socket %s",
824
vio_description(net->vio)));
826
/* Check if we can continue without closing the connection */
828
/* The error must be set. */
829
DBUG_ASSERT(thd->is_error());
830
net_end_statement(thd);
834
return_value= TRUE; // We have to close it.
843
packet= (char*) net->read_pos;
845
'packet_length' contains length of data, as it was stored in packet
846
header. In case of malformed header, my_net_read returns zero.
847
If packet_length is not zero, my_net_read ensures that the returned
848
number of bytes was actually read from network.
849
There is also an extra safety measure in my_net_read:
850
it sets packet[packet_length]= 0, but only for non-zero packets.
852
if (packet_length == 0) /* safety */
854
/* Initialize with COM_SLEEP packet */
855
packet[0]= (uchar) COM_SLEEP;
858
/* Do not rely on my_net_read, extra safety against programming errors. */
859
packet[packet_length]= '\0'; /* safety */
861
command= (enum enum_server_command) (uchar) packet[0];
863
if (command >= COM_END)
864
command= COM_END; // Wrong command
866
DBUG_PRINT("info",("Command on %s = %d (%s)",
867
vio_description(net->vio), command,
868
command_name[command].str));
870
/* Restore read timeout value */
871
my_net_set_read_timeout(net, thd->variables.net_read_timeout);
873
DBUG_ASSERT(packet_length);
874
return_value= dispatch_command(command, thd, packet+1, (uint) (packet_length-1));
877
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
878
thd->profiling.finish_current_query();
880
DBUG_RETURN(return_value);
882
#endif /* EMBEDDED_LIBRARY */
885
@brief Determine if an attempt to update a non-temporary table while the
886
read-only option was enabled has been made.
888
This is a helper function to mysql_execute_command.
890
@note SQLCOM_MULTI_UPDATE is an exception and delt with elsewhere.
892
@see mysql_execute_command
894
@retval TRUE The statement should be denied.
895
@retval FALSE The statement isn't updating any relevant tables.
898
static my_bool deny_updates_if_read_only_option(THD *thd,
899
TABLE_LIST *all_tables)
901
DBUG_ENTER("deny_updates_if_read_only_option");
908
const my_bool user_is_super=
909
((ulong)(thd->security_ctx->master_access & SUPER_ACL) ==
915
if (!(sql_command_flags[lex->sql_command] & CF_CHANGES_DATA))
918
/* Multi update is an exception and is dealt with later. */
919
if (lex->sql_command == SQLCOM_UPDATE_MULTI)
922
const my_bool create_temp_tables=
923
(lex->sql_command == SQLCOM_CREATE_TABLE) &&
924
(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE);
926
const my_bool drop_temp_tables=
927
(lex->sql_command == SQLCOM_DROP_TABLE) &&
930
const my_bool update_real_tables=
931
some_non_temp_table_to_be_updated(thd, all_tables) &&
932
!(create_temp_tables || drop_temp_tables);
935
const my_bool create_or_drop_databases=
936
(lex->sql_command == SQLCOM_CREATE_DB) ||
937
(lex->sql_command == SQLCOM_DROP_DB);
939
if (update_real_tables || create_or_drop_databases)
942
An attempt was made to modify one or more non-temporary tables.
948
/* Assuming that only temporary tables are modified. */
953
Perform one connection-level (COM_XXXX) command.
955
@param command type of command to perform
956
@param thd connection handle
957
@param packet data for the command, packet is always null-terminated
958
@param packet_length length of packet + 1 (to show that data is
959
null-terminated) except for COM_SLEEP, where it
963
set thd->lex->sql_command to SQLCOM_END here.
965
The following has to be changed to an 8 byte integer
970
1 request of thread shutdown, i. e. if command is
971
COM_QUIT/COM_SHUTDOWN
973
bool dispatch_command(enum enum_server_command command, THD *thd,
974
char* packet, uint packet_length)
978
DBUG_ENTER("dispatch_command");
979
DBUG_PRINT("info",("packet: '%*.s'; command: %d", packet_length, packet, command));
981
thd->command=command;
983
Commands which always take a long time are logged into
984
the slow log only if opt_log_slow_admin_statements is set.
986
thd->enable_slow_log= TRUE;
987
thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
989
VOID(pthread_mutex_lock(&LOCK_thread_count));
990
thd->query_id= global_query_id;
993
/* Ignore these statements. */
997
/* Only increase id on these statements but don't count them. */
998
case COM_STMT_PREPARE:
1000
case COM_STMT_RESET:
1003
/* Increase id and count all other statements. */
1005
statistic_increment(thd->status_var.questions, &LOCK_status);
1010
/* TODO: set thd->lex->sql_command to SQLCOM_END here */
1011
VOID(pthread_mutex_unlock(&LOCK_thread_count));
1014
Clear the set of flags that are expected to be cleared at the
1015
beginning of each command.
1017
thd->server_status&= ~SERVER_STATUS_CLEAR_SET;
1022
status_var_increment(thd->status_var.com_stat[SQLCOM_CHANGE_DB]);
1023
thd->convert_string(&tmp, system_charset_info,
1024
packet, packet_length, thd->charset());
1025
if (!mysql_change_db(thd, &tmp, FALSE))
1027
general_log_write(thd, command, thd->db, thd->db_length);
1032
#ifdef HAVE_REPLICATION
1033
case COM_REGISTER_SLAVE:
1035
if (!register_slave(thd, (uchar*)packet, packet_length))
1040
case COM_TABLE_DUMP:
1044
/* Safe because there is always a trailing \0 at the end of the packet */
1045
uint db_len= *(uchar*) packet;
1046
if (db_len + 1 > packet_length || db_len > NAME_LEN)
1048
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
1051
/* Safe because there is always a trailing \0 at the end of the packet */
1052
uint tbl_len= *(uchar*) (packet + db_len + 1);
1053
if (db_len + tbl_len + 2 > packet_length || tbl_len > NAME_LEN)
1055
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
1059
status_var_increment(thd->status_var.com_other);
1060
thd->enable_slow_log= opt_log_slow_admin_statements;
1061
db.str= (char*) thd->alloc(db_len + tbl_len + 2);
1064
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
1068
tbl_name= strmake(db.str, packet + 1, db_len)+1;
1069
strmake(tbl_name, packet + db_len + 2, tbl_len);
1070
if (mysql_table_dump(thd, &db, tbl_name) == 0)
1071
thd->main_da.disable_status();
1074
case COM_CHANGE_USER:
1076
status_var_increment(thd->status_var.com_other);
1077
char *user= (char*) packet, *packet_end= packet + packet_length;
1078
/* Safe because there is always a trailing \0 at the end of the packet */
1079
char *passwd= strend(user)+1;
1082
thd->clear_error(); // if errors from rollback
1085
Old clients send null-terminated string ('\0' for empty string) for
1086
password. New clients send the size (1 byte) + string (not null
1087
terminated, so also '\0' for empty string).
1089
Cast *passwd to an unsigned char, so that it doesn't extend the sign
1090
for *passwd > 127 and become 2**32-127 after casting to uint.
1092
char db_buff[NAME_LEN+1]; // buffer to store db in utf8
1096
If there is no password supplied, the packet must contain '\0',
1097
in any type of handshake (4.1 or pre-4.1).
1099
if (passwd >= packet_end)
1101
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
1104
uint passwd_len= (thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
1105
(uchar)(*passwd++) : strlen(passwd));
1106
uint dummy_errors, save_db_length, db_length;
1108
Security_context save_security_ctx= *thd->security_ctx;
1109
USER_CONN *save_user_connect;
1111
db+= passwd_len + 1;
1113
Database name is always NUL-terminated, so in case of empty database
1114
the packet must contain at least the trailing '\0'.
1116
if (db >= packet_end)
1118
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
1121
db_length= strlen(db);
1123
char *ptr= db + db_length + 1;
1126
if (ptr < packet_end)
1128
if (ptr + 2 > packet_end)
1130
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
1134
cs_number= uint2korr(ptr);
1137
/* Convert database name to utf8 */
1138
db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
1139
system_charset_info, db, db_length,
1140
thd->charset(), &dummy_errors)]= 0;
1143
/* Save user and privileges */
1144
save_db_length= thd->db_length;
1146
save_user_connect= thd->user_connect;
1148
if (!(thd->security_ctx->user= my_strdup(user, MYF(0))))
1150
thd->security_ctx->user= save_security_ctx.user;
1151
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
1155
/* Clear variables that are allocated */
1156
thd->user_connect= 0;
1157
thd->security_ctx->priv_user= thd->security_ctx->user;
1158
res= check_user(thd, COM_CHANGE_USER, passwd, passwd_len, db, FALSE);
1162
x_free(thd->security_ctx->user);
1163
*thd->security_ctx= save_security_ctx;
1164
thd->user_connect= save_user_connect;
1166
thd->db_length= save_db_length;
1170
#ifndef NO_EMBEDDED_ACCESS_CHECKS
1171
/* we've authenticated new user */
1172
if (save_user_connect)
1173
decrease_user_connections(save_user_connect);
1174
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
1176
x_free(save_security_ctx.user);
1180
thd_init_client_charset(thd, cs_number);
1181
thd->update_charset();
1186
case COM_STMT_EXECUTE:
1188
mysqld_stmt_execute(thd, packet, packet_length);
1191
case COM_STMT_FETCH:
1193
mysqld_stmt_fetch(thd, packet, packet_length);
1196
case COM_STMT_SEND_LONG_DATA:
1198
mysql_stmt_get_longdata(thd, packet, packet_length);
1201
case COM_STMT_PREPARE:
1203
mysqld_stmt_prepare(thd, packet, packet_length);
1206
case COM_STMT_CLOSE:
1208
mysqld_stmt_close(thd, packet);
1211
case COM_STMT_RESET:
1213
mysqld_stmt_reset(thd, packet);
1218
if (alloc_query(thd, packet, packet_length))
1219
break; // fatal error is set
1220
char *packet_end= thd->query() + thd->query_length();
1221
/* 'b' stands for 'buffer' parameter', special for 'my_snprintf' */
1222
const char* end_of_stmt= NULL;
1224
general_log_write(thd, command, thd->query(), thd->query_length());
1225
DBUG_PRINT("query",("%-.4096s",thd->query()));
1226
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
1227
thd->profiling.set_query_source(thd->query(), thd->query_length());
1230
if (!(specialflag & SPECIAL_NO_PRIOR))
1231
my_pthread_setprio(pthread_self(),QUERY_PRIOR);
1233
mysql_parse(thd, thd->query(), thd->query_length(), &end_of_stmt);
1235
while (!thd->killed && (end_of_stmt != NULL) && ! thd->is_error())
1237
char *beginning_of_next_stmt= (char*) end_of_stmt;
1239
net_end_statement(thd);
1240
query_cache_end_of_result(thd);
1242
Multiple queries exits, execute them individually
1244
close_thread_tables(thd);
1245
ulong length= (ulong)(packet_end - beginning_of_next_stmt);
1247
log_slow_statement(thd);
1249
/* Remove garbage at start of query */
1250
while (length > 0 && my_isspace(thd->charset(), *beginning_of_next_stmt))
1252
beginning_of_next_stmt++;
1256
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
1257
thd->profiling.finish_current_query();
1258
thd->profiling.start_new_query("continuing");
1259
thd->profiling.set_query_source(beginning_of_next_stmt, length);
1262
thd->set_query(beginning_of_next_stmt, length);
1263
VOID(pthread_mutex_lock(&LOCK_thread_count));
1265
Count each statement from the client.
1267
statistic_increment(thd->status_var.questions, &LOCK_status);
1268
thd->query_id= next_query_id();
1269
thd->set_time(); /* Reset the query start time. */
1270
/* TODO: set thd->lex->sql_command to SQLCOM_END here */
1271
VOID(pthread_mutex_unlock(&LOCK_thread_count));
1272
mysql_parse(thd, beginning_of_next_stmt, length, &end_of_stmt);
1275
if (!(specialflag & SPECIAL_NO_PRIOR))
1276
my_pthread_setprio(pthread_self(),WAIT_PRIOR);
1277
DBUG_PRINT("info",("query ready"));
1280
case COM_FIELD_LIST: // This isn't actually needed
1281
#ifdef DONT_ALLOW_SHOW_COMMANDS
1282
my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND),
1283
MYF(0)); /* purecov: inspected */
1287
char *fields, *packet_end= packet + packet_length, *arg_end;
1288
/* Locked closure of all tables */
1289
TABLE_LIST table_list;
1290
LEX_STRING conv_name;
1292
/* used as fields initializator */
1295
status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_FIELDS]);
1296
bzero((char*) &table_list,sizeof(table_list));
1297
if (thd->copy_db_to(&table_list.db, &table_list.db_length))
1300
We have name + wildcard in packet, separated by endzero
1302
arg_end= strend(packet);
1303
thd->convert_string(&conv_name, system_charset_info,
1304
packet, (uint) (arg_end - packet), thd->charset());
1305
table_list.alias= table_list.table_name= conv_name.str;
1306
packet= arg_end + 1;
1308
if (is_schema_db(table_list.db, table_list.db_length))
1310
ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, table_list.alias);
1312
table_list.schema_table= schema_table;
1315
uint query_length= (uint) (packet_end - packet); // Don't count end \0
1316
if (!(fields= (char *) thd->memdup(packet, query_length + 1)))
1318
thd->set_query(fields, query_length);
1319
general_log_print(thd, command, "%s %s", table_list.table_name, fields);
1320
if (lower_case_table_names)
1321
my_casedn_str(files_charset_info, table_list.table_name);
1323
if (check_access(thd,SELECT_ACL,table_list.db,&table_list.grant.privilege,
1324
0, 0, test(table_list.schema_table)))
1326
if (check_grant(thd, SELECT_ACL, &table_list, 2, UINT_MAX, 0))
1328
/* init structures for VIEW processing */
1329
table_list.select_lex= &(thd->lex->select_lex);
1332
mysql_reset_thd_for_next_command(thd);
1335
select_lex.table_list.link_in_list((uchar*) &table_list,
1336
(uchar**) &table_list.next_local);
1337
thd->lex->add_to_query_tables(&table_list);
1339
/* switch on VIEW optimisation: do not fill temporary tables */
1340
thd->lex->sql_command= SQLCOM_SHOW_FIELDS;
1341
mysqld_list_fields(thd,&table_list,fields);
1342
thd->lex->unit.cleanup();
1343
thd->cleanup_after_query();
1348
/* We don't calculate statistics for this command */
1349
general_log_print(thd, command, NullS);
1350
net->error=0; // Don't give 'abort' message
1351
thd->main_da.disable_status(); // Don't send anything back
1352
error=TRUE; // End server
1356
case COM_CREATE_DB: // QQ: To be removed
1358
LEX_STRING db, alias;
1359
HA_CREATE_INFO create_info;
1361
status_var_increment(thd->status_var.com_stat[SQLCOM_CREATE_DB]);
1362
if (thd->make_lex_string(&db, packet, packet_length, FALSE) ||
1363
thd->make_lex_string(&alias, db.str, db.length, FALSE) ||
1366
my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL");
1369
if (check_access(thd, CREATE_ACL, db.str , 0, 1, 0,
1370
is_schema_db(db.str, db.length)))
1372
general_log_print(thd, command, "%.*s", db.length, db.str);
1373
bzero(&create_info, sizeof(create_info));
1374
mysql_create_db(thd, (lower_case_table_names == 2 ? alias.str : db.str),
1378
case COM_DROP_DB: // QQ: To be removed
1380
status_var_increment(thd->status_var.com_stat[SQLCOM_DROP_DB]);
1383
if (thd->make_lex_string(&db, packet, packet_length, FALSE) ||
1386
my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL");
1389
if (check_access(thd, DROP_ACL, db.str, 0, 1, 0,
1390
is_schema_db(db.str, db.length)))
1392
if (thd->locked_tables || thd->active_transaction())
1394
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
1395
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
1398
general_log_write(thd, command, "%.*s", db.length, db.str);
1399
mysql_rm_db(thd, db.str, 0, 0);
1403
#ifndef EMBEDDED_LIBRARY
1404
case COM_BINLOG_DUMP:
1408
uint32 slave_server_id;
1410
status_var_increment(thd->status_var.com_other);
1411
thd->enable_slow_log= opt_log_slow_admin_statements;
1412
if (check_global_access(thd, REPL_SLAVE_ACL))
1415
/* TODO: The following has to be changed to an 8 byte integer */
1416
pos = uint4korr(packet);
1417
flags = uint2korr(packet + 4);
1418
thd->server_id=0; /* avoid suicide */
1419
if ((slave_server_id= uint4korr(packet+6))) // mysqlbinlog.server_id==0
1420
kill_zombie_dump_threads(slave_server_id);
1421
thd->server_id = slave_server_id;
1423
general_log_print(thd, command, "Log: '%s' Pos: %ld", packet+10,
1425
mysql_binlog_send(thd, thd->strdup(packet + 10), (my_off_t) pos, flags);
1426
unregister_slave(thd,1,1);
1427
/* fake COM_QUIT -- if we get here, the thread needs to terminate */
1435
status_var_increment(thd->status_var.com_stat[SQLCOM_FLUSH]);
1436
ulong options= (ulong) (uchar) packet[0];
1437
if (check_global_access(thd,RELOAD_ACL))
1439
general_log_print(thd, command, NullS);
1441
bool debug_simulate= FALSE;
1442
DBUG_EXECUTE_IF("simulate_detached_thread_refresh", debug_simulate= TRUE;);
1446
Simulate a reload without a attached thread session.
1447
Provides a environment similar to that of when the
1448
server receives a SIGHUP signal and reloads caches
1452
my_pthread_setspecific_ptr(THR_THD, NULL);
1453
res= reload_acl_and_cache(NULL, options | REFRESH_FAST,
1455
my_pthread_setspecific_ptr(THR_THD, thd);
1461
if (!reload_acl_and_cache(thd, options, NULL, ¬_used))
1465
#ifndef EMBEDDED_LIBRARY
1468
status_var_increment(thd->status_var.com_other);
1469
if (check_global_access(thd,SHUTDOWN_ACL))
1470
break; /* purecov: inspected */
1472
If the client is < 4.1.3, it is going to send us no argument; then
1473
packet_length is 0, packet[0] is the end 0 of the packet. Note that
1474
SHUTDOWN_DEFAULT is 0. If client is >= 4.1.3, the shutdown level is in
1477
enum mysql_enum_shutdown_level level=
1478
(enum mysql_enum_shutdown_level) (uchar) packet[0];
1479
if (level == SHUTDOWN_DEFAULT)
1480
level= SHUTDOWN_WAIT_ALL_BUFFERS; // soon default will be configurable
1481
else if (level != SHUTDOWN_WAIT_ALL_BUFFERS)
1483
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "this shutdown level");
1486
DBUG_PRINT("quit",("Got shutdown command for level %u", level));
1487
general_log_print(thd, command, NullS);
1489
close_thread_tables(thd); // Free before kill
1495
case COM_STATISTICS:
1497
STATUS_VAR current_global_status_var;
1500
ulonglong queries_per_second1000;
1502
uint buff_len= sizeof(buff);
1504
general_log_print(thd, command, NullS);
1505
status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS]);
1506
calc_sum_of_all_status(¤t_global_status_var);
1507
if (!(uptime= (ulong) (thd->start_time - server_start_time)))
1508
queries_per_second1000= 0;
1510
queries_per_second1000= thd->query_id * LL(1000) / uptime;
1512
length= my_snprintf((char*) buff, buff_len - 1,
1513
"Uptime: %lu Threads: %d Questions: %lu "
1514
"Slow queries: %lu Opens: %lu Flush tables: %lu "
1515
"Open tables: %u Queries per second avg: %u.%u",
1517
(int) thread_count, (ulong) thd->query_id,
1518
current_global_status_var.long_query_count,
1519
current_global_status_var.opened_tables,
1521
cached_open_tables(),
1522
(uint) (queries_per_second1000 / 1000),
1523
(uint) (queries_per_second1000 % 1000));
1524
#ifdef EMBEDDED_LIBRARY
1525
/* Store the buffer in permanent memory */
1526
my_ok(thd, 0, 0, buff);
1529
if (sf_malloc_cur_memory) // Using SAFEMALLOC
1531
char *end= buff + length;
1532
length+= my_snprintf(end, buff_len - length - 1,
1533
end," Memory in use: %ldK Max memory used: %ldK",
1534
(sf_malloc_cur_memory+1023L)/1024L,
1535
(sf_malloc_max_memory+1023L)/1024L);
1538
#ifndef EMBEDDED_LIBRARY
1539
VOID(my_net_write(net, (uchar*) buff, length));
1540
VOID(net_flush(net));
1541
thd->main_da.disable_status();
1546
status_var_increment(thd->status_var.com_other);
1547
my_ok(thd); // Tell client we are alive
1549
case COM_PROCESS_INFO:
1550
status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_PROCESSLIST]);
1551
if (!thd->security_ctx->priv_user[0] &&
1552
check_global_access(thd, PROCESS_ACL))
1554
general_log_print(thd, command, NullS);
1555
mysqld_list_processes(thd,
1556
thd->security_ctx->master_access & PROCESS_ACL ?
1557
NullS : thd->security_ctx->priv_user, 0);
1559
case COM_PROCESS_KILL:
1561
status_var_increment(thd->status_var.com_stat[SQLCOM_KILL]);
1562
ulong id=(ulong) uint4korr(packet);
1563
sql_kill(thd,id,false);
1566
case COM_SET_OPTION:
1568
status_var_increment(thd->status_var.com_stat[SQLCOM_SET_OPTION]);
1569
uint opt_command= uint2korr(packet);
1571
switch (opt_command) {
1572
case (int) MYSQL_OPTION_MULTI_STATEMENTS_ON:
1573
thd->client_capabilities|= CLIENT_MULTI_STATEMENTS;
1576
case (int) MYSQL_OPTION_MULTI_STATEMENTS_OFF:
1577
thd->client_capabilities&= ~CLIENT_MULTI_STATEMENTS;
1581
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
1587
status_var_increment(thd->status_var.com_other);
1588
if (check_global_access(thd, SUPER_ACL))
1589
break; /* purecov: inspected */
1590
mysql_print_status();
1591
general_log_print(thd, command, NullS);
1595
case COM_CONNECT: // Impossible here
1596
case COM_TIME: // Impossible from client
1597
case COM_DELAYED_INSERT:
1600
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
1604
/* report error issued during command execution */
1605
if (thd->killed_errno())
1607
if (! thd->main_da.is_set())
1608
thd->send_kill_message();
1610
if (thd->killed == THD::KILL_QUERY || thd->killed == THD::KILL_BAD_DATA)
1612
thd->killed= THD::NOT_KILLED;
1613
thd->mysys_var->abort= 0;
1616
/* If commit fails, we should be able to reset the OK status. */
1617
thd->main_da.can_overwrite_status= TRUE;
1618
ha_autocommit_or_rollback(thd, thd->is_error());
1619
thd->main_da.can_overwrite_status= FALSE;
1621
thd->transaction.stmt.reset();
1623
net_end_statement(thd);
1624
query_cache_end_of_result(thd);
1626
thd->proc_info= "closing tables";
1628
close_thread_tables(thd);
1630
log_slow_statement(thd);
1632
thd_proc_info(thd, "cleaning up");
1633
thd->set_query(NULL, 0);
1634
thd->command=COM_SLEEP;
1635
VOID(pthread_mutex_lock(&LOCK_thread_count)); // For process list
1637
VOID(pthread_mutex_unlock(&LOCK_thread_count));
1638
thd_proc_info(thd, 0);
1639
thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory
1640
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
1645
void log_slow_statement(THD *thd)
1647
DBUG_ENTER("log_slow_statement");
1650
The following should never be true with our current code base,
1651
but better to keep this here so we don't accidently try to log a
1652
statement in a trigger or stored function
1654
if (unlikely(thd->in_sub_stmt))
1655
DBUG_VOID_RETURN; // Don't set time for sub stmt
1658
Do not log administrative statements unless the appropriate option is
1661
if (thd->enable_slow_log)
1663
ulonglong end_utime_of_query= thd->current_utime();
1664
thd_proc_info(thd, "logging slow query");
1666
if (((end_utime_of_query - thd->utime_after_lock) >
1667
thd->variables.long_query_time ||
1668
((thd->server_status &
1669
(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) &&
1670
opt_log_queries_not_using_indexes &&
1671
!(sql_command_flags[thd->lex->sql_command] & CF_STATUS_COMMAND))) &&
1672
thd->examined_row_count >= thd->variables.min_examined_row_limit)
1674
thd_proc_info(thd, "logging slow query");
1675
thd->status_var.long_query_count++;
1676
slow_log_print(thd, thd->query(), thd->query_length(),
1677
end_utime_of_query);
1685
Create a TABLE_LIST object for an INFORMATION_SCHEMA table.
1687
This function is used in the parser to convert a SHOW or DESCRIBE
1688
table_name command to a SELECT from INFORMATION_SCHEMA.
1689
It prepares a SELECT_LEX and a TABLE_LIST object to represent the
1690
given command as a SELECT parse tree.
1692
@param thd thread handle
1693
@param lex current lex
1694
@param table_ident table alias if it's used
1695
@param schema_table_idx the type of the INFORMATION_SCHEMA table to be
1699
Due to the way this function works with memory and LEX it cannot
1700
be used outside the parser (parse tree transformations outside
1701
the parser break PS and SP).
1706
1 out of memory or SHOW commands are not allowed
1707
in this version of the server.
1710
int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
1711
enum enum_schema_tables schema_table_idx)
1713
SELECT_LEX *schema_select_lex= NULL;
1714
DBUG_ENTER("prepare_schema_table");
1716
switch (schema_table_idx) {
1718
#if defined(DONT_ALLOW_SHOW_COMMANDS)
1719
my_message(ER_NOT_ALLOWED_COMMAND,
1720
ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */
1726
case SCH_TABLE_NAMES:
1731
#ifdef DONT_ALLOW_SHOW_COMMANDS
1732
my_message(ER_NOT_ALLOWED_COMMAND,
1733
ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */
1739
if (lex->select_lex.db == NULL &&
1740
lex->copy_db_to(&lex->select_lex.db, &dummy))
1744
schema_select_lex= new SELECT_LEX();
1745
db.str= schema_select_lex->db= lex->select_lex.db;
1746
schema_select_lex->table_list.first= NULL;
1747
db.length= strlen(db.str);
1749
if (check_db_name(&db))
1751
my_error(ER_WRONG_DB_NAME, MYF(0), db.str);
1758
case SCH_STATISTICS:
1760
#ifdef DONT_ALLOW_SHOW_COMMANDS
1761
my_message(ER_NOT_ALLOWED_COMMAND,
1762
ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */
1765
DBUG_ASSERT(table_ident);
1766
TABLE_LIST **query_tables_last= lex->query_tables_last;
1767
schema_select_lex= new SELECT_LEX();
1768
/* 'parent_lex' is used in init_query() so it must be before it. */
1769
schema_select_lex->parent_lex= lex;
1770
schema_select_lex->init_query();
1771
if (!schema_select_lex->add_table_to_list(thd, table_ident, 0, 0, TL_READ))
1773
lex->query_tables_last= query_tables_last;
1779
Mark this current profiling record to be discarded. We don't
1780
wish to have SHOW commands show up in profiling.
1782
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
1783
thd->profiling.discard_current_query();
1786
case SCH_OPEN_TABLES:
1789
case SCH_PROCEDURES:
1792
case SCH_COLLATIONS:
1793
case SCH_COLLATION_CHARACTER_SET_APPLICABILITY:
1794
case SCH_USER_PRIVILEGES:
1795
case SCH_SCHEMA_PRIVILEGES:
1796
case SCH_TABLE_PRIVILEGES:
1797
case SCH_COLUMN_PRIVILEGES:
1798
case SCH_TABLE_CONSTRAINTS:
1799
case SCH_KEY_COLUMN_USAGE:
1804
SELECT_LEX *select_lex= lex->current_select;
1805
if (make_schema_select(thd, select_lex, schema_table_idx))
1809
TABLE_LIST *table_list= (TABLE_LIST*) select_lex->table_list.first;
1810
table_list->schema_select_lex= schema_select_lex;
1811
table_list->schema_table_reformed= 1;
1817
Read query from packet and store in thd->query.
1818
Used in COM_QUERY and COM_STMT_PREPARE.
1820
Sets the following THD variables:
1827
TRUE error; In this case thd->fatal_error is set
1830
bool alloc_query(THD *thd, const char *packet, uint packet_length)
1833
/* Remove garbage at start and end of query */
1834
while (packet_length > 0 && my_isspace(thd->charset(), packet[0]))
1839
const char *pos= packet + packet_length; // Point at end null
1840
while (packet_length > 0 &&
1841
(pos[-1] == ';' || my_isspace(thd->charset() ,pos[-1])))
1846
/* We must allocate some extra memory for query cache */
1847
if (! (query= (char*) thd->memdup_w_gap(packet,
1849
1 + thd->db_length +
1850
QUERY_CACHE_FLAGS_SIZE)))
1852
query[packet_length]= '\0';
1853
thd->set_query(query, packet_length);
1855
/* Reclaim some memory */
1856
thd->packet.shrink(thd->variables.net_buffer_length);
1857
thd->convert_buffer.shrink(thd->variables.net_buffer_length);
1862
static void reset_one_shot_variables(THD *thd)
1864
thd->variables.character_set_client=
1865
global_system_variables.character_set_client;
1866
thd->variables.collation_connection=
1867
global_system_variables.collation_connection;
1868
thd->variables.collation_database=
1869
global_system_variables.collation_database;
1870
thd->variables.collation_server=
1871
global_system_variables.collation_server;
1872
thd->update_charset();
1873
thd->variables.time_zone=
1874
global_system_variables.time_zone;
1875
thd->variables.lc_time_names= &my_locale_en_US;
1876
thd->one_shot_set= 0;
1881
bool sp_process_definer(THD *thd)
1883
DBUG_ENTER("sp_process_definer");
1888
If the definer is not specified, this means that CREATE-statement missed
1889
DEFINER-clause. DEFINER-clause can be missed in two cases:
1891
- The user submitted a statement w/o the clause. This is a normal
1892
case, we should assign CURRENT_USER as definer.
1894
- Our slave received an updated from the master, that does not
1895
replicate definer for stored rountines. We should also assign
1896
CURRENT_USER as definer here, but also we should mark this routine
1897
as NON-SUID. This is essential for the sake of backward
1900
The problem is the slave thread is running under "special" user (@),
1901
that actually does not exist. In the older versions we do not fail
1902
execution of a stored routine if its definer does not exist and
1903
continue the execution under the authorization of the invoker
1904
(BUG#13198). And now if we try to switch to slave-current-user (@),
1907
Actually, this leads to the inconsistent state of master and
1908
slave (different definers, different SUID behaviour), but it seems,
1909
this is the best we can do.
1914
Query_arena original_arena;
1915
Query_arena *ps_arena= thd->activate_stmt_arena_if_needed(&original_arena);
1917
lex->definer= create_default_definer(thd);
1920
thd->restore_active_arena(ps_arena, &original_arena);
1922
/* Error has been already reported. */
1923
if (lex->definer == NULL)
1926
if (thd->slave_thread && lex->sphead)
1927
lex->sphead->m_chistics->suid= SP_IS_NOT_SUID;
1932
If the specified definer differs from the current user, we
1933
should check that the current user has SUPER privilege (in order
1934
to create a stored routine under another user one must have
1937
if ((strcmp(lex->definer->user.str, thd->security_ctx->priv_user) ||
1938
my_strcasecmp(system_charset_info, lex->definer->host.str,
1939
thd->security_ctx->priv_host)) &&
1940
check_global_access(thd, SUPER_ACL))
1942
my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
1947
/* Check that the specified definer exists. Emit a warning if not. */
1949
#ifndef NO_EMBEDDED_ACCESS_CHECKS
1950
if (!is_acl_user(lex->definer->host.str, lex->definer->user.str))
1952
push_warning_printf(thd,
1953
MYSQL_ERROR::WARN_LEVEL_NOTE,
1955
ER(ER_NO_SUCH_USER),
1956
lex->definer->user.str,
1957
lex->definer->host.str);
1959
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
1966
Execute command saved in thd and lex->sql_command.
1968
Before every operation that can request a write lock for a table
1969
wait if a global read lock exists. However do not wait if this
1970
thread has locked tables already. No new locks can be requested
1971
until the other locks are released. The thread that requests the
1972
global read lock waits for write locked tables to become unlocked.
1974
Note that wait_if_global_read_lock() sets a protection against a new
1975
global read lock when it succeeds. This needs to be released by
1976
start_waiting_global_read_lock() after the operation.
1978
@param thd Thread handle
1981
- Invalidate the table in the query cache if something changed
1982
after unlocking when changes become visible.
1983
TODO: this is workaround. right way will be move invalidating in
1984
the unlock procedure.
1985
- TODO: use check_change_password()
1986
- JOIN is not supported yet. TODO
1987
- SUSPEND and FOR MIGRATE are not supported yet. TODO
1996
mysql_execute_command(THD *thd)
1999
bool need_start_waiting= FALSE; // have protection against global read lock
2002
/* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */
2003
SELECT_LEX *select_lex= &lex->select_lex;
2004
/* first table of first SELECT_LEX */
2005
TABLE_LIST *first_table= (TABLE_LIST*) select_lex->table_list.first;
2006
/* list of all tables in query */
2007
TABLE_LIST *all_tables;
2008
/* most outer SELECT_LEX_UNIT of query */
2009
SELECT_LEX_UNIT *unit= &lex->unit;
2010
#ifdef HAVE_REPLICATION
2011
/* have table map for update for multi-update statement (BUG#37051) */
2012
bool have_table_map_for_update= FALSE;
2014
/* Saved variable value */
2015
DBUG_ENTER("mysql_execute_command");
2016
#ifdef WITH_PARTITION_STORAGE_ENGINE
2017
thd->work_part_info= 0;
2021
In many cases first table of main SELECT_LEX have special meaning =>
2022
check that it is first table in global list and relink it first in
2023
queries_tables list if it is necessary (we need such relinking only
2024
for queries with subqueries in select list, in this case tables of
2025
subqueries will go to global list first)
2027
all_tables will differ from first_table only if most upper SELECT_LEX
2028
do not contain tables.
2030
Because of above in place where should be at least one table in most
2031
outer SELECT_LEX we have following check:
2032
DBUG_ASSERT(first_table == all_tables);
2033
DBUG_ASSERT(first_table == all_tables && first_table != 0);
2035
lex->first_lists_tables_same();
2036
/* should be assigned after making first tables same */
2037
all_tables= lex->query_tables;
2038
/* set context for commands which do not use setup_tables */
2040
context.resolve_in_table_list_only((TABLE_LIST*)select_lex->
2044
Reset warning count for each query that uses tables
2045
A better approach would be to reset this for any commands
2046
that is not a SHOW command or a select that only access local
2047
variables, but for now this is probably good enough.
2048
Don't reset warnings when executing a stored routine.
2050
if ((all_tables || !lex->is_single_level_stmt()) && !thd->spcont)
2051
mysql_reset_errors(thd, 0);
2053
#ifdef HAVE_REPLICATION
2054
if (unlikely(thd->slave_thread))
2056
if (lex->sql_command == SQLCOM_DROP_TRIGGER)
2059
When dropping a trigger, we need to load its table name
2060
before checking slave filter rules.
2062
add_table_for_trigger(thd, thd->lex->spname, 1, &all_tables);
2067
If table name cannot be loaded,
2068
it means the trigger does not exists possibly because
2069
CREATE TRIGGER was previously skipped for this trigger
2070
according to slave filtering rules.
2071
Returning success without producing any errors in this case.
2076
// force searching in slave.cc:tables_ok()
2077
all_tables->updating= 1;
2081
For fix of BUG#37051, the master stores the table map for update
2082
in the Query_log_event, and the value is assigned to
2083
thd->variables.table_map_for_update before executing the update
2086
If thd->variables.table_map_for_update is set, then we are
2087
replicating from a new master, we can use this value to apply
2088
filter rules without opening all the tables. However If
2089
thd->variables.table_map_for_update is not set, then we are
2090
replicating from an old master, so we just skip this and
2091
continue with the old method. And of course, the bug would still
2092
exist for old masters.
2094
if (lex->sql_command == SQLCOM_UPDATE_MULTI &&
2095
thd->table_map_for_update)
2097
have_table_map_for_update= TRUE;
2098
table_map table_map_for_update= thd->table_map_for_update;
2101
for (table=all_tables; table; table=table->next_global, nr++)
2103
if (table_map_for_update & ((table_map)1 << nr))
2104
table->updating= TRUE;
2106
table->updating= FALSE;
2109
if (all_tables_not_ok(thd, all_tables))
2111
/* we warn the slave SQL thread */
2112
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
2113
if (thd->one_shot_set)
2114
reset_one_shot_variables(thd);
2118
for (table=all_tables; table; table=table->next_global)
2119
table->updating= TRUE;
2123
Check if statment should be skipped because of slave filtering
2127
- UPDATE MULTI: For this statement, we want to check the filtering
2128
rules later in the code
2129
- SET: we always execute it (Not that many SET commands exists in
2130
the binary log anyway -- only 4.1 masters write SET statements,
2131
in 5.0 there are no SET statements in the binary log)
2132
- DROP TEMPORARY TABLE IF EXISTS: we always execute it (otherwise we
2133
have stale files on slave caused by exclusion of one tmp table).
2135
if (!(lex->sql_command == SQLCOM_UPDATE_MULTI) &&
2136
!(lex->sql_command == SQLCOM_SET_OPTION) &&
2137
!(lex->sql_command == SQLCOM_DROP_TABLE &&
2138
lex->drop_temporary && lex->drop_if_exists) &&
2139
all_tables_not_ok(thd, all_tables))
2141
/* we warn the slave SQL thread */
2142
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
2143
if (thd->one_shot_set)
2146
It's ok to check thd->one_shot_set here:
2148
The charsets in a MySQL 5.0 slave can change by both a binlogged
2149
SET ONE_SHOT statement and the event-internal charset setting,
2150
and these two ways to change charsets do not seems to work
2153
At least there seems to be problems in the rli cache for
2154
charsets if we are using ONE_SHOT. Note that this is normally no
2155
problem because either the >= 5.0 slave reads a 4.1 binlog (with
2156
ONE_SHOT) *or* or 5.0 binlog (without ONE_SHOT) but never both."
2158
reset_one_shot_variables(thd);
2165
#endif /* HAVE_REPLICATION */
2167
When option readonly is set deny operations which change non-temporary
2168
tables. Except for the replication thread and the 'super' users.
2170
if (deny_updates_if_read_only_option(thd, all_tables))
2172
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
2175
#ifdef HAVE_REPLICATION
2176
} /* endif unlikely slave */
2178
status_var_increment(thd->status_var.com_stat[lex->sql_command]);
2180
DBUG_ASSERT(thd->transaction.stmt.modified_non_trans_table == FALSE);
2182
switch (lex->sql_command) {
2184
case SQLCOM_SHOW_EVENTS:
2185
#ifndef HAVE_EVENT_SCHEDULER
2186
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "embedded server");
2189
case SQLCOM_SHOW_STATUS_PROC:
2190
case SQLCOM_SHOW_STATUS_FUNC:
2191
if (!(res= check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE)))
2192
res= execute_sqlcom_select(thd, all_tables);
2194
case SQLCOM_SHOW_STATUS:
2196
system_status_var old_status_var= thd->status_var;
2197
thd->initial_status_var= &old_status_var;
2198
if (!(res= check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE)))
2199
res= execute_sqlcom_select(thd, all_tables);
2200
/* Don't log SHOW STATUS commands to slow query log */
2201
thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED |
2202
SERVER_QUERY_NO_GOOD_INDEX_USED);
2204
restore status variables, as we don't want 'show status' to cause
2207
pthread_mutex_lock(&LOCK_status);
2208
add_diff_to_status(&global_status_var, &thd->status_var,
2210
thd->status_var= old_status_var;
2211
pthread_mutex_unlock(&LOCK_status);
2214
case SQLCOM_SHOW_DATABASES:
2215
case SQLCOM_SHOW_TABLES:
2216
case SQLCOM_SHOW_TRIGGERS:
2217
case SQLCOM_SHOW_TABLE_STATUS:
2218
case SQLCOM_SHOW_OPEN_TABLES:
2219
case SQLCOM_SHOW_PLUGINS:
2220
case SQLCOM_SHOW_FIELDS:
2221
case SQLCOM_SHOW_KEYS:
2222
case SQLCOM_SHOW_VARIABLES:
2223
case SQLCOM_SHOW_CHARSETS:
2224
case SQLCOM_SHOW_COLLATIONS:
2225
case SQLCOM_SHOW_STORAGE_ENGINES:
2226
case SQLCOM_SHOW_PROFILE:
2228
thd->status_var.last_query_cost= 0.0;
2231
res= check_table_access(thd,
2232
lex->exchange ? SELECT_ACL | FILE_ACL :
2234
all_tables, UINT_MAX, FALSE);
2237
res= check_access(thd,
2238
lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL,
2239
any_db, 0, 0, 0, 0);
2244
if (!thd->locked_tables && lex->protect_against_global_read_lock &&
2245
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
2248
res= execute_sqlcom_select(thd, all_tables);
2250
case SQLCOM_PREPARE:
2252
mysql_sql_stmt_prepare(thd);
2255
case SQLCOM_EXECUTE:
2257
mysql_sql_stmt_execute(thd);
2260
case SQLCOM_DEALLOCATE_PREPARE:
2262
mysql_sql_stmt_close(thd);
2266
if (check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE) ||
2267
open_and_lock_tables(thd, all_tables))
2270
res= mysql_do(thd, *lex->insert_list);
2273
case SQLCOM_EMPTY_QUERY:
2278
res= mysqld_help(thd,lex->help_arg);
2281
#ifndef EMBEDDED_LIBRARY
2284
if (check_global_access(thd, SUPER_ACL))
2286
/* PURGE MASTER LOGS TO 'file' */
2287
res = purge_master_logs(thd, lex->to_log);
2290
case SQLCOM_PURGE_BEFORE:
2294
if (check_global_access(thd, SUPER_ACL))
2296
/* PURGE MASTER LOGS BEFORE 'data' */
2297
it= (Item *)lex->value_list.head();
2298
if ((!it->fixed && it->fix_fields(lex->thd, &it)) ||
2301
my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE LOGS BEFORE");
2304
it= new Item_func_unix_timestamp(it);
2306
it is OK only emulate fix_fieds, because we need only
2309
it->quick_fix_field();
2310
res = purge_master_logs_before_date(thd, (ulong)it->val_int());
2314
case SQLCOM_SHOW_WARNS:
2316
res= mysqld_show_warnings(thd, (ulong)
2317
((1L << (uint) MYSQL_ERROR::WARN_LEVEL_NOTE) |
2318
(1L << (uint) MYSQL_ERROR::WARN_LEVEL_WARN) |
2319
(1L << (uint) MYSQL_ERROR::WARN_LEVEL_ERROR)
2323
case SQLCOM_SHOW_ERRORS:
2325
res= mysqld_show_warnings(thd, (ulong)
2326
(1L << (uint) MYSQL_ERROR::WARN_LEVEL_ERROR));
2329
case SQLCOM_SHOW_PROFILES:
2331
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
2332
thd->profiling.discard_current_query();
2333
res= thd->profiling.show_profiles();
2337
my_error(ER_FEATURE_DISABLED, MYF(0), "SHOW PROFILES", "enable-profiling");
2342
case SQLCOM_SHOW_NEW_MASTER:
2344
if (check_global_access(thd, REPL_SLAVE_ACL))
2346
/* This query don't work now. See comment in repl_failsafe.cc */
2347
#ifndef WORKING_NEW_MASTER
2348
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "SHOW NEW MASTER");
2351
res = show_new_master(thd);
2356
#ifdef HAVE_REPLICATION
2357
case SQLCOM_SHOW_SLAVE_HOSTS:
2359
if (check_global_access(thd, REPL_SLAVE_ACL))
2361
res = show_slave_hosts(thd);
2364
case SQLCOM_SHOW_BINLOG_EVENTS:
2366
if (check_global_access(thd, REPL_SLAVE_ACL))
2368
res = mysql_show_binlog_events(thd);
2373
case SQLCOM_BACKUP_TABLE:
2375
DBUG_ASSERT(first_table == all_tables && first_table != 0);
2376
if (check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE) ||
2377
check_global_access(thd, FILE_ACL))
2378
goto error; /* purecov: inspected */
2379
thd->enable_slow_log= opt_log_slow_admin_statements;
2380
res = mysql_backup_table(thd, first_table);
2381
select_lex->table_list.first= (uchar*) first_table;
2382
lex->query_tables=all_tables;
2385
case SQLCOM_RESTORE_TABLE:
2387
DBUG_ASSERT(first_table == all_tables && first_table != 0);
2388
if (check_table_access(thd, INSERT_ACL, all_tables, UINT_MAX, FALSE) ||
2389
check_global_access(thd, FILE_ACL))
2390
goto error; /* purecov: inspected */
2391
thd->enable_slow_log= opt_log_slow_admin_statements;
2392
res = mysql_restore_table(thd, first_table);
2393
select_lex->table_list.first= (uchar*) first_table;
2394
lex->query_tables=all_tables;
2397
case SQLCOM_ASSIGN_TO_KEYCACHE:
2399
DBUG_ASSERT(first_table == all_tables && first_table != 0);
2400
if (check_access(thd, INDEX_ACL, first_table->db,
2401
&first_table->grant.privilege, 0, 0,
2402
test(first_table->schema_table)))
2404
res= mysql_assign_to_keycache(thd, first_table, &lex->ident);
2407
case SQLCOM_PRELOAD_KEYS:
2409
DBUG_ASSERT(first_table == all_tables && first_table != 0);
2410
if (check_access(thd, INDEX_ACL, first_table->db,
2411
&first_table->grant.privilege, 0, 0,
2412
test(first_table->schema_table)))
2414
res = mysql_preload_keys(thd, first_table);
2417
#ifdef HAVE_REPLICATION
2418
case SQLCOM_CHANGE_MASTER:
2420
if (check_global_access(thd, SUPER_ACL))
2422
pthread_mutex_lock(&LOCK_active_mi);
2423
res = change_master(thd,active_mi);
2424
pthread_mutex_unlock(&LOCK_active_mi);
2427
case SQLCOM_SHOW_SLAVE_STAT:
2429
/* Accept one of two privileges */
2430
if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL))
2432
pthread_mutex_lock(&LOCK_active_mi);
2433
if (active_mi != NULL)
2435
res = show_master_info(thd, active_mi);
2439
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
2440
WARN_NO_MASTER_INFO, ER(WARN_NO_MASTER_INFO));
2443
pthread_mutex_unlock(&LOCK_active_mi);
2446
case SQLCOM_SHOW_MASTER_STAT:
2448
/* Accept one of two privileges */
2449
if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL))
2451
res = show_binlog_info(thd);
2455
case SQLCOM_LOAD_MASTER_DATA: // sync with master
2456
if (check_global_access(thd, SUPER_ACL))
2458
if (end_active_trans(thd))
2460
res = load_master_data(thd);
2462
#endif /* HAVE_REPLICATION */
2463
case SQLCOM_SHOW_ENGINE_STATUS:
2465
if (check_global_access(thd, PROCESS_ACL))
2467
res = ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_STATUS);
2470
case SQLCOM_SHOW_ENGINE_MUTEX:
2472
if (check_global_access(thd, PROCESS_ACL))
2474
res = ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_MUTEX);
2477
#ifdef HAVE_REPLICATION
2478
case SQLCOM_LOAD_MASTER_TABLE:
2480
DBUG_ASSERT(first_table == all_tables && first_table != 0);
2481
DBUG_ASSERT(first_table->db); /* Must be set in the parser */
2483
if (check_access(thd, CREATE_ACL, first_table->db,
2484
&first_table->grant.privilege, 0, 0,
2485
test(first_table->schema_table)))
2486
goto error; /* purecov: inspected */
2487
/* Check that the first table has CREATE privilege */
2488
if (check_grant(thd, CREATE_ACL, all_tables, 0, 1, 0))
2491
pthread_mutex_lock(&LOCK_active_mi);
2493
fetch_master_table will send the error to the client on failure.
2494
Give error if the table already exists.
2496
if (!fetch_master_table(thd, first_table->db, first_table->table_name,
2501
pthread_mutex_unlock(&LOCK_active_mi);
2504
#endif /* HAVE_REPLICATION */
2506
case SQLCOM_CREATE_TABLE:
2508
/* If CREATE TABLE of non-temporary table, do implicit commit */
2509
if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE))
2511
if (end_active_trans(thd))
2517
DBUG_ASSERT(first_table == all_tables && first_table != 0);
2519
// Skip first table, which is the table we are creating
2520
TABLE_LIST *create_table= lex->unlink_first_table(&link_to_local);
2521
TABLE_LIST *select_tables= lex->query_tables;
2523
Code below (especially in mysql_create_table() and select_create
2524
methods) may modify HA_CREATE_INFO structure in LEX, so we have to
2525
use a copy of this structure to make execution prepared statement-
2526
safe. A shallow copy is enough as this code won't modify any memory
2527
referenced from this structure.
2529
HA_CREATE_INFO create_info(lex->create_info);
2531
We need to copy alter_info for the same reasons of re-execution
2532
safety, only in case of Alter_info we have to do (almost) a deep
2535
Alter_info alter_info(lex->alter_info, thd->mem_root);
2537
if (thd->is_fatal_error)
2539
/* If out of memory when creating a copy of alter_info. */
2541
goto end_with_restore_list;
2544
if ((res= create_table_precheck(thd, select_tables, create_table)))
2545
goto end_with_restore_list;
2547
/* Might have been updated in create_table_precheck */
2548
create_info.alias= create_table->alias;
2550
#ifdef HAVE_READLINK
2551
/* Fix names if symlinked tables */
2552
if (append_file_to_dir(thd, &create_info.data_file_name,
2553
create_table->table_name) ||
2554
append_file_to_dir(thd, &create_info.index_file_name,
2555
create_table->table_name))
2556
goto end_with_restore_list;
2559
If we are using SET CHARSET without DEFAULT, add an implicit
2560
DEFAULT to not confuse old users. (This may change).
2562
if ((create_info.used_fields &
2563
(HA_CREATE_USED_DEFAULT_CHARSET | HA_CREATE_USED_CHARSET)) ==
2564
HA_CREATE_USED_CHARSET)
2566
create_info.used_fields&= ~HA_CREATE_USED_CHARSET;
2567
create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
2568
create_info.default_table_charset= create_info.table_charset;
2569
create_info.table_charset= 0;
2572
The create-select command will open and read-lock the select table
2573
and then create, open and write-lock the new table. If a global
2574
read lock steps in, we get a deadlock. The write lock waits for
2575
the global read lock, while the global read lock waits for the
2576
select table to be closed. So we wait until the global readlock is
2577
gone before starting both steps. Note that
2578
wait_if_global_read_lock() sets a protection against a new global
2579
read lock when it succeeds. This needs to be released by
2580
start_waiting_global_read_lock(). We protect the normal CREATE
2581
TABLE in the same way. That way we avoid that a new table is
2582
created during a gobal read lock.
2584
if (!thd->locked_tables &&
2585
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
2588
goto end_with_restore_list;
2590
#ifdef WITH_PARTITION_STORAGE_ENGINE
2592
partition_info *part_info= thd->lex->part_info;
2593
if (part_info && !(part_info= thd->lex->part_info->get_clone()))
2596
goto end_with_restore_list;
2598
thd->work_part_info= part_info;
2601
if (select_lex->item_list.elements) // With select
2603
select_result *result;
2607
a) we inside an SP and there was NAME_CONST substitution,
2608
b) binlogging is on (STMT mode),
2609
c) we log the SP as separate statements
2610
raise a warning, as it may cause problems
2611
(see 'NAME_CONST issues' in 'Binary Logging of Stored Programs')
2613
if (thd->query_name_consts &&
2614
mysql_bin_log.is_open() &&
2615
thd->variables.binlog_format == BINLOG_FORMAT_STMT &&
2616
!mysql_bin_log.is_query_in_union(thd, thd->query_id))
2618
List_iterator_fast<Item> it(select_lex->item_list);
2620
uint splocal_refs= 0;
2621
/* Count SP local vars in the top-level SELECT list */
2622
while ((item= it++))
2624
if (item->is_splocal())
2628
If it differs from number of NAME_CONST substitution applied,
2629
we may have a SOME_FUNC(NAME_CONST()) in the SELECT list,
2630
that may cause a problem with binary log (see BUG#35383),
2633
if (splocal_refs != thd->query_name_consts)
2635
MYSQL_ERROR::WARN_LEVEL_WARN,
2637
"Invoked routine ran a statement that may cause problems with "
2638
"binary log, see 'NAME_CONST issues' in 'Binary Logging of Stored Programs' "
2639
"section of the manual.");
2642
select_lex->options|= SELECT_NO_UNLOCK;
2643
unit->set_limit(select_lex);
2646
Disable non-empty MERGE tables with CREATE...SELECT. Too
2647
complicated. See Bug #26379. Empty MERGE tables are read-only
2648
and don't allow CREATE...SELECT anyway.
2650
if (create_info.used_fields & HA_CREATE_USED_UNION)
2652
my_error(ER_WRONG_OBJECT, MYF(0), create_table->db,
2653
create_table->table_name, "BASE TABLE");
2655
goto end_with_restore_list;
2658
if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
2660
lex->link_first_table_back(create_table, link_to_local);
2661
create_table->create= TRUE;
2662
/* Base table and temporary table are not in the same name space. */
2663
create_table->skip_temporary= 1;
2666
if (!(res= open_and_lock_tables(thd, lex->query_tables)))
2669
Is table which we are changing used somewhere in other parts
2672
if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
2674
TABLE_LIST *duplicate;
2675
create_table= lex->unlink_first_table(&link_to_local);
2676
if ((duplicate= unique_table(thd, create_table, select_tables, 0)))
2678
update_non_unique_table_error(create_table, "CREATE", duplicate);
2680
goto end_with_restore_list;
2683
/* If we create merge table, we have to test tables in merge, too */
2684
if (create_info.used_fields & HA_CREATE_USED_UNION)
2687
for (tab= (TABLE_LIST*) create_info.merge_list.first;
2689
tab= tab->next_local)
2691
TABLE_LIST *duplicate;
2692
if ((duplicate= unique_table(thd, tab, select_tables, 0)))
2694
update_non_unique_table_error(tab, "CREATE", duplicate);
2696
goto end_with_restore_list;
2702
select_create is currently not re-execution friendly and
2703
needs to be created for every execution of a PS/SP.
2705
if ((result= new select_create(create_table,
2708
select_lex->item_list,
2714
CREATE from SELECT give its SELECT_LEX for SELECT,
2715
and item_list belong to SELECT
2717
res= handle_select(thd, lex, result, 0);
2721
else if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
2722
create_table= lex->unlink_first_table(&link_to_local);
2727
/* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
2728
if (create_info.options & HA_LEX_CREATE_TMP_TABLE)
2729
thd->options|= OPTION_KEEP_LOG;
2730
/* regular create */
2731
if (create_info.options & HA_LEX_CREATE_TABLE_LIKE)
2732
res= mysql_create_like_table(thd, create_table, select_tables,
2736
res= mysql_create_table(thd, create_table->db,
2737
create_table->table_name, &create_info,
2744
/* put tables back for PS rexecuting */
2745
end_with_restore_list:
2746
lex->link_first_table_back(create_table, link_to_local);
2749
case SQLCOM_CREATE_INDEX:
2751
case SQLCOM_DROP_INDEX:
2753
CREATE INDEX and DROP INDEX are implemented by calling ALTER
2754
TABLE with proper arguments.
2756
In the future ALTER TABLE will notice that the request is to
2757
only add indexes and create these one by one for the existing
2758
table without having to do a full rebuild.
2761
/* Prepare stack copies to be re-execution safe */
2762
HA_CREATE_INFO create_info;
2763
Alter_info alter_info(lex->alter_info, thd->mem_root);
2765
if (thd->is_fatal_error) /* out of memory creating a copy of alter_info */
2768
DBUG_ASSERT(first_table == all_tables && first_table != 0);
2769
if (check_one_table_access(thd, INDEX_ACL, all_tables))
2770
goto error; /* purecov: inspected */
2771
if (end_active_trans(thd))
2774
Currently CREATE INDEX or DROP INDEX cause a full table rebuild
2775
and thus classify as slow administrative statements just like
2778
thd->enable_slow_log= opt_log_slow_admin_statements;
2780
bzero((char*) &create_info, sizeof(create_info));
2781
create_info.db_type= 0;
2782
create_info.row_type= ROW_TYPE_NOT_USED;
2783
create_info.default_table_charset= thd->variables.collation_database;
2785
res= mysql_alter_table(thd, first_table->db, first_table->table_name,
2786
&create_info, first_table, &alter_info,
2790
#ifdef HAVE_REPLICATION
2791
case SQLCOM_SLAVE_START:
2793
pthread_mutex_lock(&LOCK_active_mi);
2794
start_slave(thd,active_mi,1 /* net report*/);
2795
pthread_mutex_unlock(&LOCK_active_mi);
2798
case SQLCOM_SLAVE_STOP:
2800
If the client thread has locked tables, a deadlock is possible.
2802
- the client thread does LOCK TABLE t READ.
2803
- then the master updates t.
2804
- then the SQL slave thread wants to update t,
2805
so it waits for the client thread because t is locked by it.
2806
- then the client thread does SLAVE STOP.
2807
SLAVE STOP waits for the SQL slave thread to terminate its
2808
update t, which waits for the client thread because t is locked by it.
2809
To prevent that, refuse SLAVE STOP if the
2810
client thread has locked tables
2812
if (thd->locked_tables || thd->active_transaction() || thd->global_read_lock)
2814
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
2815
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
2819
pthread_mutex_lock(&LOCK_active_mi);
2820
stop_slave(thd,active_mi,1/* net report*/);
2821
pthread_mutex_unlock(&LOCK_active_mi);
2824
#endif /* HAVE_REPLICATION */
2826
case SQLCOM_ALTER_TABLE:
2827
DBUG_ASSERT(first_table == all_tables && first_table != 0);
2830
ulong priv_needed= ALTER_ACL;
2832
Code in mysql_alter_table() may modify its HA_CREATE_INFO argument,
2833
so we have to use a copy of this structure to make execution
2834
prepared statement- safe. A shallow copy is enough as no memory
2835
referenced from this structure will be modified.
2837
HA_CREATE_INFO create_info(lex->create_info);
2838
Alter_info alter_info(lex->alter_info, thd->mem_root);
2840
if (thd->is_fatal_error) /* out of memory creating a copy of alter_info */
2843
We also require DROP priv for ALTER TABLE ... DROP PARTITION, as well
2844
as for RENAME TO, as being done by SQLCOM_RENAME_TABLE
2846
if (alter_info.flags & (ALTER_DROP_PARTITION | ALTER_RENAME))
2847
priv_needed|= DROP_ACL;
2849
/* Must be set in the parser */
2850
DBUG_ASSERT(select_lex->db);
2851
if (check_access(thd, priv_needed, first_table->db,
2852
&first_table->grant.privilege, 0, 0,
2853
test(first_table->schema_table)) ||
2854
check_access(thd,INSERT_ACL | CREATE_ACL,select_lex->db,&priv,0,0,
2855
is_schema_db(select_lex->db))||
2856
check_merge_table_access(thd, first_table->db,
2858
create_info.merge_list.first))
2859
goto error; /* purecov: inspected */
2860
if (check_grant(thd, priv_needed, all_tables, 0, UINT_MAX, 0))
2862
if (lex->name.str && !test_all_bits(priv,INSERT_ACL | CREATE_ACL))
2863
{ // Rename of table
2864
TABLE_LIST tmp_table;
2865
bzero((char*) &tmp_table,sizeof(tmp_table));
2866
tmp_table.table_name= lex->name.str;
2867
tmp_table.db=select_lex->db;
2868
tmp_table.grant.privilege=priv;
2869
if (check_grant(thd, INSERT_ACL | CREATE_ACL, &tmp_table, 0,
2874
/* Don't yet allow changing of symlinks with ALTER TABLE */
2875
if (create_info.data_file_name)
2876
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
2877
WARN_OPTION_IGNORED, ER(WARN_OPTION_IGNORED),
2879
if (create_info.index_file_name)
2880
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
2881
WARN_OPTION_IGNORED, ER(WARN_OPTION_IGNORED),
2883
create_info.data_file_name= create_info.index_file_name= NULL;
2884
/* ALTER TABLE ends previous transaction */
2885
if (end_active_trans(thd))
2888
if (!thd->locked_tables &&
2889
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
2895
thd->enable_slow_log= opt_log_slow_admin_statements;
2896
res= mysql_alter_table(thd, select_lex->db, lex->name.str,
2900
select_lex->order_list.elements,
2901
(ORDER *) select_lex->order_list.first,
2905
case SQLCOM_RENAME_TABLE:
2907
DBUG_ASSERT(first_table == all_tables && first_table != 0);
2909
for (table= first_table; table; table= table->next_local->next_local)
2911
if (check_access(thd, ALTER_ACL | DROP_ACL, table->db,
2912
&table->grant.privilege,0,0, test(table->schema_table)) ||
2913
check_access(thd, INSERT_ACL | CREATE_ACL, table->next_local->db,
2914
&table->next_local->grant.privilege, 0, 0,
2915
test(table->next_local->schema_table)))
2917
TABLE_LIST old_list, new_list;
2919
we do not need initialize old_list and new_list because we will
2920
come table[0] and table->next[0] there
2923
new_list= table->next_local[0];
2924
if (check_grant(thd, ALTER_ACL | DROP_ACL, &old_list, 0, 1, 0) ||
2925
(!test_all_bits(table->next_local->grant.privilege,
2926
INSERT_ACL | CREATE_ACL) &&
2927
check_grant(thd, INSERT_ACL | CREATE_ACL, &new_list, 0, 1, 0)))
2931
if (end_active_trans(thd) || mysql_rename_tables(thd, first_table, 0))
2935
#ifndef EMBEDDED_LIBRARY
2936
case SQLCOM_SHOW_BINLOGS:
2937
#ifdef DONT_ALLOW_SHOW_COMMANDS
2938
my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND),
2939
MYF(0)); /* purecov: inspected */
2943
if (check_global_access(thd, SUPER_ACL))
2945
res = show_binlogs(thd);
2949
#endif /* EMBEDDED_LIBRARY */
2950
case SQLCOM_SHOW_CREATE:
2951
DBUG_ASSERT(first_table == all_tables && first_table != 0);
2952
#ifdef DONT_ALLOW_SHOW_COMMANDS
2953
my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND),
2954
MYF(0)); /* purecov: inspected */
2958
/* Ignore temporary tables if this is "SHOW CREATE VIEW" */
2960
first_table->skip_temporary= 1;
2961
if (check_show_create_table_access(thd, first_table))
2963
res= mysqld_show_create(thd, first_table);
2967
case SQLCOM_CHECKSUM:
2969
DBUG_ASSERT(first_table == all_tables && first_table != 0);
2970
if (check_table_access(thd, SELECT_ACL | EXTRA_ACL, all_tables,
2972
goto error; /* purecov: inspected */
2973
res = mysql_checksum_table(thd, first_table, &lex->check_opt);
2978
DBUG_ASSERT(first_table == all_tables && first_table != 0);
2979
if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables,
2981
goto error; /* purecov: inspected */
2982
thd->enable_slow_log= opt_log_slow_admin_statements;
2983
res= mysql_repair_table(thd, first_table, &lex->check_opt);
2984
/* ! we write after unlocking the table */
2985
if (!res && !lex->no_write_to_binlog)
2988
Presumably, REPAIR and binlog writing doesn't require synchronization
2990
res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
2992
select_lex->table_list.first= (uchar*) first_table;
2993
lex->query_tables=all_tables;
2998
DBUG_ASSERT(first_table == all_tables && first_table != 0);
2999
if (check_table_access(thd, SELECT_ACL | EXTRA_ACL , all_tables,
3001
goto error; /* purecov: inspected */
3002
thd->enable_slow_log= opt_log_slow_admin_statements;
3003
res = mysql_check_table(thd, first_table, &lex->check_opt);
3004
select_lex->table_list.first= (uchar*) first_table;
3005
lex->query_tables=all_tables;
3008
case SQLCOM_ANALYZE:
3010
DBUG_ASSERT(first_table == all_tables && first_table != 0);
3011
if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables,
3013
goto error; /* purecov: inspected */
3014
thd->enable_slow_log= opt_log_slow_admin_statements;
3015
res= mysql_analyze_table(thd, first_table, &lex->check_opt);
3016
/* ! we write after unlocking the table */
3017
if (!res && !lex->no_write_to_binlog)
3020
Presumably, ANALYZE and binlog writing doesn't require synchronization
3022
res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
3024
select_lex->table_list.first= (uchar*) first_table;
3025
lex->query_tables=all_tables;
3029
case SQLCOM_OPTIMIZE:
3031
DBUG_ASSERT(first_table == all_tables && first_table != 0);
3032
if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables,
3034
goto error; /* purecov: inspected */
3035
thd->enable_slow_log= opt_log_slow_admin_statements;
3036
res= (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) ?
3037
mysql_recreate_table(thd, first_table) :
3038
mysql_optimize_table(thd, first_table, &lex->check_opt);
3039
/* ! we write after unlocking the table */
3040
if (!res && !lex->no_write_to_binlog)
3043
Presumably, OPTIMIZE and binlog writing doesn't require synchronization
3045
res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
3047
select_lex->table_list.first= (uchar*) first_table;
3048
lex->query_tables=all_tables;
3052
DBUG_ASSERT(first_table == all_tables && first_table != 0);
3053
if (update_precheck(thd, all_tables))
3055
if (!thd->locked_tables &&
3056
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
3058
DBUG_ASSERT(select_lex->offset_limit == 0);
3059
unit->set_limit(select_lex);
3060
res= (up_result= mysql_update(thd, all_tables,
3061
select_lex->item_list,
3064
select_lex->order_list.elements,
3065
(ORDER *) select_lex->order_list.first,
3066
unit->select_limit_cnt,
3067
lex->duplicates, lex->ignore));
3068
/* mysql_update return 2 if we need to switch to multi-update */
3072
case SQLCOM_UPDATE_MULTI:
3074
DBUG_ASSERT(first_table == all_tables && first_table != 0);
3075
/* if we switched from normal update, rights are checked */
3078
if ((res= multi_update_precheck(thd, all_tables)))
3085
Protection might have already been risen if its a fall through
3086
from the SQLCOM_UPDATE case above.
3088
if (!thd->locked_tables &&
3089
lex->sql_command == SQLCOM_UPDATE_MULTI &&
3090
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
3093
res= mysql_multi_update_prepare(thd);
3095
#ifdef HAVE_REPLICATION
3096
/* Check slave filtering rules */
3097
if (unlikely(thd->slave_thread && !have_table_map_for_update))
3099
if (all_tables_not_ok(thd, all_tables))
3103
res= 0; /* don't care of prev failure */
3104
thd->clear_error(); /* filters are of highest prior */
3106
/* we warn the slave SQL thread */
3107
my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
3115
#endif /* HAVE_REPLICATION */
3119
!(thd->security_ctx->master_access & SUPER_ACL) &&
3120
some_non_temp_table_to_be_updated(thd, all_tables))
3122
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
3125
#ifdef HAVE_REPLICATION
3129
res= mysql_multi_update(thd, all_tables,
3130
&select_lex->item_list,
3133
select_lex->options,
3134
lex->duplicates, lex->ignore, unit, select_lex);
3137
case SQLCOM_REPLACE:
3139
if (mysql_bin_log.is_open())
3142
Generate an incident log event before writing the real event
3143
to the binary log. We put this event is before the statement
3144
since that makes it simpler to check that the statement was
3145
not executed on the slave (since incidents usually stop the
3148
Observe that any row events that are generated will be
3151
This is only for testing purposes and will not be present in a
3155
Incident incident= INCIDENT_NONE;
3156
DBUG_PRINT("debug", ("Just before generate_incident()"));
3157
DBUG_EXECUTE_IF("incident_database_resync_on_replace",
3158
incident= INCIDENT_LOST_EVENTS;);
3161
Incident_log_event ev(thd, incident);
3162
(void) mysql_bin_log.write(&ev); /* error is ignored */
3163
mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE);
3165
DBUG_PRINT("debug", ("Just after generate_incident()"));
3170
DBUG_ASSERT(first_table == all_tables && first_table != 0);
3171
if ((res= insert_precheck(thd, all_tables)))
3174
if (!thd->locked_tables &&
3175
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
3181
res= mysql_insert(thd, all_tables, lex->field_list, lex->many_values,
3182
lex->update_list, lex->value_list,
3183
lex->duplicates, lex->ignore);
3186
If we have inserted into a VIEW, and the base table has
3187
AUTO_INCREMENT column, but this column is not accessible through
3188
a view, then we should restore LAST_INSERT_ID to the value it
3189
had before the statement.
3191
if (first_table->view && !first_table->contain_auto_increment)
3192
thd->first_successful_insert_id_in_cur_stmt=
3193
thd->first_successful_insert_id_in_prev_stmt;
3197
case SQLCOM_REPLACE_SELECT:
3198
case SQLCOM_INSERT_SELECT:
3200
select_result *sel_result;
3201
DBUG_ASSERT(first_table == all_tables && first_table != 0);
3202
if ((res= insert_precheck(thd, all_tables)))
3205
/* Fix lock for first table */
3206
if (first_table->lock_type == TL_WRITE_DELAYED)
3207
first_table->lock_type= TL_WRITE;
3209
/* Don't unlock tables until command is written to binary log */
3210
select_lex->options|= SELECT_NO_UNLOCK;
3212
unit->set_limit(select_lex);
3214
if (! thd->locked_tables &&
3215
! (need_start_waiting= ! wait_if_global_read_lock(thd, 0, 1)))
3221
if (!(res= open_and_lock_tables(thd, all_tables)))
3223
/* Skip first table, which is the table we are inserting in */
3224
TABLE_LIST *second_table= first_table->next_local;
3225
select_lex->table_list.first= (uchar*) second_table;
3226
select_lex->context.table_list=
3227
select_lex->context.first_name_resolution_table= second_table;
3228
res= mysql_insert_select_prepare(thd);
3229
if (!res && (sel_result= new select_insert(first_table,
3237
res= handle_select(thd, lex, sel_result, OPTION_SETUP_TABLES_DONE);
3239
Invalidate the table in the query cache if something changed
3240
after unlocking when changes become visible.
3241
TODO: this is workaround. right way will be move invalidating in
3242
the unlock procedure.
3244
if (first_table->lock_type == TL_WRITE_CONCURRENT_INSERT &&
3247
/* INSERT ... SELECT should invalidate only the very first table */
3248
TABLE_LIST *save_table= first_table->next_local;
3249
first_table->next_local= 0;
3250
query_cache_invalidate3(thd, first_table, 1);
3251
first_table->next_local= save_table;
3255
/* revert changes for SP */
3256
select_lex->table_list.first= (uchar*) first_table;
3260
If we have inserted into a VIEW, and the base table has
3261
AUTO_INCREMENT column, but this column is not accessible through
3262
a view, then we should restore LAST_INSERT_ID to the value it
3263
had before the statement.
3265
if (first_table->view && !first_table->contain_auto_increment)
3266
thd->first_successful_insert_id_in_cur_stmt=
3267
thd->first_successful_insert_id_in_prev_stmt;
3271
case SQLCOM_TRUNCATE:
3272
if (end_active_trans(thd))
3277
DBUG_ASSERT(first_table == all_tables && first_table != 0);
3278
if (check_one_table_access(thd, DROP_ACL, all_tables))
3281
Don't allow this within a transaction because we want to use
3284
if (thd->locked_tables || thd->active_transaction())
3286
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
3287
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
3290
if (!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
3292
res= mysql_truncate(thd, first_table, 0);
3296
DBUG_ASSERT(first_table == all_tables && first_table != 0);
3297
if ((res= delete_precheck(thd, all_tables)))
3299
DBUG_ASSERT(select_lex->offset_limit == 0);
3300
unit->set_limit(select_lex);
3302
if (!thd->locked_tables &&
3303
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
3309
res = mysql_delete(thd, all_tables, select_lex->where,
3310
&select_lex->order_list,
3311
unit->select_limit_cnt, select_lex->options,
3315
case SQLCOM_DELETE_MULTI:
3317
DBUG_ASSERT(first_table == all_tables && first_table != 0);
3318
TABLE_LIST *aux_tables=
3319
(TABLE_LIST *)thd->lex->auxiliary_table_list.first;
3320
multi_delete *del_result;
3322
if (!thd->locked_tables &&
3323
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
3329
if ((res= multi_delete_precheck(thd, all_tables)))
3332
/* condition will be TRUE on SP re-excuting */
3333
if (select_lex->item_list.elements != 0)
3334
select_lex->item_list.empty();
3335
if (add_item_to_list(thd, new Item_null()))
3338
thd_proc_info(thd, "init");
3339
if ((res= open_and_lock_tables(thd, all_tables)))
3342
if ((res= mysql_multi_delete_prepare(thd)))
3345
if (!thd->is_fatal_error &&
3346
(del_result= new multi_delete(aux_tables, lex->table_count)))
3348
res= mysql_select(thd, &select_lex->ref_pointer_array,
3349
select_lex->get_table_list(),
3350
select_lex->with_wild,
3351
select_lex->item_list,
3353
0, (ORDER *)NULL, (ORDER *)NULL, (Item *)NULL,
3355
(select_lex->options | thd->options |
3356
SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
3357
OPTION_SETUP_TABLES_DONE) & ~OPTION_BUFFER_RESULT,
3358
del_result, unit, select_lex);
3359
res|= thd->is_error();
3361
del_result->abort();
3368
case SQLCOM_DROP_TABLE:
3370
DBUG_ASSERT(first_table == all_tables && first_table != 0);
3371
if (!lex->drop_temporary)
3373
if (check_table_access(thd, DROP_ACL, all_tables, UINT_MAX, FALSE))
3374
goto error; /* purecov: inspected */
3375
if (end_active_trans(thd))
3380
/* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
3381
thd->options|= OPTION_KEEP_LOG;
3383
/* DDL and binlog write order protected by LOCK_open */
3384
res= mysql_rm_table(thd, first_table, lex->drop_if_exists,
3385
lex->drop_temporary);
3388
case SQLCOM_SHOW_PROCESSLIST:
3389
if (!thd->security_ctx->priv_user[0] &&
3390
check_global_access(thd,PROCESS_ACL))
3392
mysqld_list_processes(thd,
3393
(thd->security_ctx->master_access & PROCESS_ACL ?
3395
thd->security_ctx->priv_user),
3398
case SQLCOM_SHOW_AUTHORS:
3399
res= mysqld_show_authors(thd);
3401
case SQLCOM_SHOW_CONTRIBUTORS:
3402
res= mysqld_show_contributors(thd);
3404
case SQLCOM_SHOW_PRIVILEGES:
3405
res= mysqld_show_privileges(thd);
3407
case SQLCOM_SHOW_COLUMN_TYPES:
3408
res= mysqld_show_column_types(thd);
3410
case SQLCOM_SHOW_ENGINE_LOGS:
3411
#ifdef DONT_ALLOW_SHOW_COMMANDS
3412
my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND),
3413
MYF(0)); /* purecov: inspected */
3417
if (check_access(thd, FILE_ACL, any_db,0,0,0,0))
3419
res= ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_LOGS);
3423
case SQLCOM_CHANGE_DB:
3425
LEX_STRING db_str= { (char *) select_lex->db, strlen(select_lex->db) };
3427
if (!mysql_change_db(thd, &db_str, FALSE))
3435
DBUG_ASSERT(first_table == all_tables && first_table != 0);
3436
uint privilege= (lex->duplicates == DUP_REPLACE ?
3437
INSERT_ACL | DELETE_ACL : INSERT_ACL) |
3438
(lex->local_file ? 0 : FILE_ACL);
3440
if (lex->local_file)
3442
if (!(thd->client_capabilities & CLIENT_LOCAL_FILES) ||
3445
my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), MYF(0));
3450
if (check_one_table_access(thd, privilege, all_tables))
3453
if (!thd->locked_tables &&
3454
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
3457
res= mysql_load(thd, lex->exchange, first_table, lex->field_list,
3458
lex->update_list, lex->value_list, lex->duplicates,
3459
lex->ignore, (bool) lex->local_file);
3463
case SQLCOM_SET_OPTION:
3465
List<set_var_base> *lex_var_list= &lex->var_list;
3467
if (lex->autocommit && end_active_trans(thd))
3470
if ((check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE) ||
3471
open_and_lock_tables(thd, all_tables)))
3473
if (lex->one_shot_set && not_all_support_one_shot(lex_var_list))
3475
my_error(ER_RESERVED_SYNTAX, MYF(0), "SET ONE_SHOT");
3478
if (!(res= sql_set_variables(thd, lex_var_list)))
3481
If the previous command was a SET ONE_SHOT, we don't want to forget
3482
about the ONE_SHOT property of that SET. So we use a |= instead of = .
3484
thd->one_shot_set|= lex->one_shot_set;
3490
We encountered some sort of error, but no message was sent.
3491
Send something semi-generic here since we don't know which
3492
assignment in the list caused the error.
3494
if (!thd->is_error())
3495
my_error(ER_WRONG_ARGUMENTS,MYF(0),"SET");
3502
case SQLCOM_UNLOCK_TABLES:
3504
It is critical for mysqldump --single-transaction --master-data that
3505
UNLOCK TABLES does not implicitely commit a connection which has only
3506
done FLUSH TABLES WITH READ LOCK + BEGIN. If this assumption becomes
3507
false, mysqldump will not work.
3509
unlock_locked_tables(thd);
3510
if (thd->options & OPTION_TABLE_LOCK)
3512
end_active_trans(thd);
3513
thd->options&= ~(OPTION_TABLE_LOCK);
3515
if (thd->global_read_lock)
3516
unlock_global_read_lock(thd);
3519
case SQLCOM_LOCK_TABLES:
3520
unlock_locked_tables(thd);
3521
/* we must end the trasaction first, regardless of anything */
3522
if (end_active_trans(thd))
3524
if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables,
3527
if (lex->protect_against_global_read_lock &&
3528
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
3530
thd->in_lock_tables=1;
3531
thd->options|= OPTION_TABLE_LOCK;
3533
if (!(res= simple_open_n_lock_tables(thd, all_tables)))
3535
#ifdef HAVE_QUERY_CACHE
3536
if (thd->variables.query_cache_wlock_invalidate)
3537
query_cache.invalidate_locked_for_write(first_table);
3538
#endif /*HAVE_QUERY_CACHE*/
3539
thd->locked_tables=thd->lock;
3546
Need to end the current transaction, so the storage engine (InnoDB)
3547
can free its locks if LOCK TABLES locked some tables before finding
3548
that it can't lock a table in its list
3550
ha_autocommit_or_rollback(thd, 1);
3551
end_active_trans(thd);
3552
thd->options&= ~(OPTION_TABLE_LOCK);
3554
thd->in_lock_tables=0;
3556
case SQLCOM_CREATE_DB:
3559
As mysql_create_db() may modify HA_CREATE_INFO structure passed to
3560
it, we need to use a copy of LEX::create_info to make execution
3561
prepared statement- safe.
3563
HA_CREATE_INFO create_info(lex->create_info);
3564
if (end_active_trans(thd))
3570
if (!(alias=thd->strmake(lex->name.str, lex->name.length)) ||
3571
check_db_name(&lex->name))
3573
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
3577
If in a slave thread :
3578
CREATE DATABASE DB was certainly not preceded by USE DB.
3579
For that reason, db_ok() in sql/slave.cc did not check the
3580
do_db/ignore_db. And as this query involves no tables, tables_ok()
3581
above was not called. So we have to check rules again here.
3583
#ifdef HAVE_REPLICATION
3584
if (thd->slave_thread &&
3585
(!rpl_filter->db_ok(lex->name.str) ||
3586
!rpl_filter->db_ok_with_wild_table(lex->name.str)))
3588
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
3592
if (check_access(thd,CREATE_ACL,lex->name.str, 0, 1, 0,
3593
is_schema_db(lex->name.str, lex->name.length)))
3595
res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias :
3596
lex->name.str), &create_info, 0);
3599
case SQLCOM_DROP_DB:
3601
if (end_active_trans(thd))
3606
if (check_db_name(&lex->name))
3608
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
3612
If in a slave thread :
3613
DROP DATABASE DB may not be preceded by USE DB.
3614
For that reason, maybe db_ok() in sql/slave.cc did not check the
3615
do_db/ignore_db. And as this query involves no tables, tables_ok()
3616
above was not called. So we have to check rules again here.
3618
#ifdef HAVE_REPLICATION
3619
if (thd->slave_thread &&
3620
(!rpl_filter->db_ok(lex->name.str) ||
3621
!rpl_filter->db_ok_with_wild_table(lex->name.str)))
3623
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
3627
if (check_access(thd,DROP_ACL,lex->name.str,0,1,0,
3628
is_schema_db(lex->name.str, lex->name.length)))
3630
if (thd->locked_tables || thd->active_transaction())
3632
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
3633
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
3636
res= mysql_rm_db(thd, lex->name.str, lex->drop_if_exists, 0);
3639
case SQLCOM_ALTER_DB_UPGRADE:
3641
LEX_STRING *db= & lex->name;
3642
if (end_active_trans(thd))
3647
#ifdef HAVE_REPLICATION
3648
if (thd->slave_thread &&
3649
(!rpl_filter->db_ok(db->str) ||
3650
!rpl_filter->db_ok_with_wild_table(db->str)))
3653
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
3657
if (check_db_name(db))
3659
my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
3662
if (check_access(thd, ALTER_ACL, db->str, 0, 1, 0,
3663
is_schema_db(db->str, db->length)) ||
3664
check_access(thd, DROP_ACL, db->str, 0, 1, 0,
3665
is_schema_db(db->str, db->length)) ||
3666
check_access(thd, CREATE_ACL, db->str, 0, 1, 0,
3667
is_schema_db(db->str, db->length)))
3672
if (thd->locked_tables || thd->active_transaction())
3675
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
3676
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
3680
res= mysql_upgrade_db(thd, db);
3685
case SQLCOM_ALTER_DB:
3687
LEX_STRING *db= &lex->name;
3688
HA_CREATE_INFO create_info(lex->create_info);
3689
if (check_db_name(db))
3691
my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
3695
If in a slave thread :
3696
ALTER DATABASE DB may not be preceded by USE DB.
3697
For that reason, maybe db_ok() in sql/slave.cc did not check the
3698
do_db/ignore_db. And as this query involves no tables, tables_ok()
3699
above was not called. So we have to check rules again here.
3701
#ifdef HAVE_REPLICATION
3702
if (thd->slave_thread &&
3703
(!rpl_filter->db_ok(db->str) ||
3704
!rpl_filter->db_ok_with_wild_table(db->str)))
3706
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
3710
if (check_access(thd, ALTER_ACL, db->str, 0, 1, 0,
3711
is_schema_db(db->str, db->length)))
3713
if (thd->locked_tables || thd->active_transaction())
3715
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
3716
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
3719
res= mysql_alter_db(thd, db->str, &create_info);
3722
case SQLCOM_SHOW_CREATE_DB:
3724
DBUG_EXECUTE_IF("4x_server_emul",
3725
my_error(ER_UNKNOWN_ERROR, MYF(0)); goto error;);
3726
if (check_db_name(&lex->name))
3728
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
3731
res= mysqld_show_create_db(thd, lex->name.str, &lex->create_info);
3734
case SQLCOM_CREATE_EVENT:
3735
case SQLCOM_ALTER_EVENT:
3736
#ifdef HAVE_EVENT_SCHEDULER
3739
DBUG_ASSERT(lex->event_parse_data);
3740
if (lex->table_or_sp_used())
3742
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "Usage of subqueries or stored "
3743
"function calls as part of this statement");
3747
res= sp_process_definer(thd);
3751
switch (lex->sql_command) {
3752
case SQLCOM_CREATE_EVENT:
3754
bool if_not_exists= (lex->create_info.options &
3755
HA_LEX_CREATE_IF_NOT_EXISTS);
3756
res= Events::create_event(thd, lex->event_parse_data, if_not_exists);
3759
case SQLCOM_ALTER_EVENT:
3760
res= Events::update_event(thd, lex->event_parse_data,
3761
lex->spname ? &lex->spname->m_db : NULL,
3762
lex->spname ? &lex->spname->m_name : NULL);
3767
DBUG_PRINT("info",("DDL error code=%d", res));
3772
/* Don't do it, if we are inside a SP */
3778
/* lex->unit.cleanup() is called outside, no need to call it here */
3780
case SQLCOM_SHOW_CREATE_EVENT:
3781
res= Events::show_create_event(thd, lex->spname->m_db,
3782
lex->spname->m_name);
3784
case SQLCOM_DROP_EVENT:
3785
if (!(res= Events::drop_event(thd,
3786
lex->spname->m_db, lex->spname->m_name,
3787
lex->drop_if_exists)))
3791
my_error(ER_NOT_SUPPORTED_YET,MYF(0),"embedded server");
3794
case SQLCOM_CREATE_FUNCTION: // UDF function
3796
if (check_access(thd,INSERT_ACL,"mysql",0,1,0,0))
3799
if (!(res = mysql_create_function(thd, &lex->udf)))
3802
my_error(ER_CANT_OPEN_LIBRARY, MYF(0), lex->udf.dl, 0, "feature disabled");
3807
#ifndef NO_EMBEDDED_ACCESS_CHECKS
3808
case SQLCOM_CREATE_USER:
3810
if (check_access(thd, INSERT_ACL, "mysql", 0, 1, 1, 0) &&
3811
check_global_access(thd,CREATE_USER_ACL))
3813
if (end_active_trans(thd))
3815
/* Conditionally writes to binlog */
3816
if (!(res= mysql_create_user(thd, lex->users_list)))
3820
case SQLCOM_DROP_USER:
3822
if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 1, 0) &&
3823
check_global_access(thd,CREATE_USER_ACL))
3825
if (end_active_trans(thd))
3827
/* Conditionally writes to binlog */
3828
if (!(res= mysql_drop_user(thd, lex->users_list)))
3832
case SQLCOM_RENAME_USER:
3834
if (check_access(thd, UPDATE_ACL, "mysql", 0, 1, 1, 0) &&
3835
check_global_access(thd,CREATE_USER_ACL))
3837
if (end_active_trans(thd))
3839
/* Conditionally writes to binlog */
3840
if (!(res= mysql_rename_user(thd, lex->users_list)))
3844
case SQLCOM_REVOKE_ALL:
3846
if (end_active_trans(thd))
3848
if (check_access(thd, UPDATE_ACL, "mysql", 0, 1, 1, 0) &&
3849
check_global_access(thd,CREATE_USER_ACL))
3851
/* Conditionally writes to binlog */
3852
if (!(res = mysql_revoke_all(thd, lex->users_list)))
3859
if (end_active_trans(thd))
3862
if (check_access(thd, lex->grant | lex->grant_tot_col | GRANT_ACL,
3863
first_table ? first_table->db : select_lex->db,
3864
first_table ? &first_table->grant.privilege : 0,
3865
first_table ? 0 : 1, 0,
3866
first_table ? (bool) first_table->schema_table :
3868
is_schema_db(select_lex->db) : 0))
3871
if (thd->security_ctx->user) // If not replication
3873
LEX_USER *user, *tmp_user;
3875
List_iterator <LEX_USER> user_list(lex->users_list);
3876
while ((tmp_user= user_list++))
3878
if (!(user= get_current_user(thd, tmp_user)))
3880
if (specialflag & SPECIAL_NO_RESOLVE &&
3881
hostname_requires_resolving(user->host.str))
3882
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
3883
ER_WARN_HOSTNAME_WONT_WORK,
3884
ER(ER_WARN_HOSTNAME_WONT_WORK),
3886
// Are we trying to change a password of another user
3887
DBUG_ASSERT(user->host.str != 0);
3888
if (strcmp(thd->security_ctx->user, user->user.str) ||
3889
my_strcasecmp(system_charset_info,
3890
user->host.str, thd->security_ctx->host_or_ip))
3892
// TODO: use check_change_password()
3893
if (is_acl_user(user->host.str, user->user.str) &&
3894
user->password.str &&
3895
check_access(thd, UPDATE_ACL,"mysql",0,1,1,0))
3897
my_message(ER_PASSWORD_NOT_ALLOWED,
3898
ER(ER_PASSWORD_NOT_ALLOWED), MYF(0));
3906
if (lex->type == TYPE_ENUM_PROCEDURE ||
3907
lex->type == TYPE_ENUM_FUNCTION)
3909
uint grants= lex->all_privileges
3910
? (PROC_ACLS & ~GRANT_ACL) | (lex->grant & GRANT_ACL)
3912
if (check_grant_routine(thd, grants | GRANT_ACL, all_tables,
3913
lex->type == TYPE_ENUM_PROCEDURE, 0))
3915
/* Conditionally writes to binlog */
3916
res= mysql_routine_grant(thd, all_tables,
3917
lex->type == TYPE_ENUM_PROCEDURE,
3918
lex->users_list, grants,
3919
lex->sql_command == SQLCOM_REVOKE, TRUE);
3925
if (check_grant(thd,(lex->grant | lex->grant_tot_col | GRANT_ACL),
3926
all_tables, 0, UINT_MAX, 0))
3928
/* Conditionally writes to binlog */
3929
res= mysql_table_grant(thd, all_tables, lex->users_list,
3930
lex->columns, lex->grant,
3931
lex->sql_command == SQLCOM_REVOKE);
3936
if (lex->columns.elements || lex->type)
3938
my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER(ER_ILLEGAL_GRANT_FOR_TABLE),
3943
/* Conditionally writes to binlog */
3944
res = mysql_grant(thd, select_lex->db, lex->users_list, lex->grant,
3945
lex->sql_command == SQLCOM_REVOKE);
3948
if (lex->sql_command == SQLCOM_GRANT)
3950
List_iterator <LEX_USER> str_list(lex->users_list);
3951
LEX_USER *user, *tmp_user;
3952
while ((tmp_user=str_list++))
3954
if (!(user= get_current_user(thd, tmp_user)))
3963
#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/
3966
RESET commands are never written to the binary log, so we have to
3967
initialize this variable because RESET shares the same code as FLUSH
3969
lex->no_write_to_binlog= 1;
3972
bool write_to_binlog;
3973
if (check_global_access(thd,RELOAD_ACL))
3977
reload_acl_and_cache() will tell us if we are allowed to write to the
3980
if (!reload_acl_and_cache(thd, lex->type, first_table, &write_to_binlog))
3983
We WANT to write and we CAN write.
3984
! we write after unlocking the table.
3987
Presumably, RESET and binlog writing doesn't require synchronization
3989
if (!lex->no_write_to_binlog && write_to_binlog)
3991
if ((res= write_bin_log(thd, FALSE, thd->query(), thd->query_length())))
4001
Item *it= (Item *)lex->value_list.head();
4003
if (lex->table_or_sp_used())
4005
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "Usage of subqueries or stored "
4006
"function calls as part of this statement");
4010
if ((!it->fixed && it->fix_fields(lex->thd, &it)) || it->check_cols(1))
4012
my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
4016
sql_kill(thd, (ulong)it->val_int(), lex->type & ONLY_KILL_QUERY);
4019
#ifndef NO_EMBEDDED_ACCESS_CHECKS
4020
case SQLCOM_SHOW_GRANTS:
4022
LEX_USER *grant_user= get_current_user(thd, lex->grant_user);
4025
if ((thd->security_ctx->priv_user &&
4026
!strcmp(thd->security_ctx->priv_user, grant_user->user.str)) ||
4027
!check_access(thd, SELECT_ACL, "mysql",0,1,0,0))
4029
res = mysql_show_grants(thd, grant_user);
4034
case SQLCOM_HA_OPEN:
4035
DBUG_ASSERT(first_table == all_tables && first_table != 0);
4036
if (check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE))
4038
res= mysql_ha_open(thd, first_table, 0);
4040
case SQLCOM_HA_CLOSE:
4041
DBUG_ASSERT(first_table == all_tables && first_table != 0);
4042
res= mysql_ha_close(thd, first_table);
4044
case SQLCOM_HA_READ:
4045
DBUG_ASSERT(first_table == all_tables && first_table != 0);
4047
There is no need to check for table permissions here, because
4048
if a user has no permissions to read a table, he won't be
4049
able to open it (with SQLCOM_HA_OPEN) in the first place.
4051
unit->set_limit(select_lex);
4052
res= mysql_ha_read(thd, first_table, lex->ha_read_mode, lex->ident.str,
4053
lex->insert_list, lex->ha_rkey_mode, select_lex->where,
4054
unit->select_limit_cnt, unit->offset_limit_cnt);
4058
if (thd->transaction.xid_state.xa_state != XA_NOTR)
4060
my_error(ER_XAER_RMFAIL, MYF(0),
4061
xa_state_names[thd->transaction.xid_state.xa_state]);
4064
if (begin_trans(thd))
4066
if (lex->start_transaction_opt & MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT)
4068
if (ha_start_consistent_snapshot(thd))
4074
if (end_trans(thd, lex->tx_release ? COMMIT_RELEASE :
4075
lex->tx_chain ? COMMIT_AND_CHAIN : COMMIT))
4079
case SQLCOM_ROLLBACK:
4080
if (end_trans(thd, lex->tx_release ? ROLLBACK_RELEASE :
4081
lex->tx_chain ? ROLLBACK_AND_CHAIN : ROLLBACK))
4085
case SQLCOM_RELEASE_SAVEPOINT:
4088
for (sv=thd->transaction.savepoints; sv; sv=sv->prev)
4090
if (my_strnncoll(system_charset_info,
4091
(uchar *)lex->ident.str, lex->ident.length,
4092
(uchar *)sv->name, sv->length) == 0)
4097
if (ha_release_savepoint(thd, sv))
4098
res= TRUE; // cannot happen
4101
thd->transaction.savepoints=sv->prev;
4104
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
4107
case SQLCOM_ROLLBACK_TO_SAVEPOINT:
4110
for (sv=thd->transaction.savepoints; sv; sv=sv->prev)
4112
if (my_strnncoll(system_charset_info,
4113
(uchar *)lex->ident.str, lex->ident.length,
4114
(uchar *)sv->name, sv->length) == 0)
4119
if (ha_rollback_to_savepoint(thd, sv))
4120
res= TRUE; // cannot happen
4123
if (((thd->options & OPTION_KEEP_LOG) ||
4124
thd->transaction.all.modified_non_trans_table) &&
4126
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
4127
ER_WARNING_NOT_COMPLETE_ROLLBACK,
4128
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
4131
thd->transaction.savepoints=sv;
4134
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
4137
case SQLCOM_SAVEPOINT:
4138
if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) ||
4139
thd->in_sub_stmt) || !opt_using_transactions)
4143
SAVEPOINT **sv, *newsv;
4144
for (sv=&thd->transaction.savepoints; *sv; sv=&(*sv)->prev)
4146
if (my_strnncoll(system_charset_info,
4147
(uchar *)lex->ident.str, lex->ident.length,
4148
(uchar *)(*sv)->name, (*sv)->length) == 0)
4151
if (*sv) /* old savepoint of the same name exists */
4154
ha_release_savepoint(thd, *sv); // it cannot fail
4157
else if ((newsv=(SAVEPOINT *) alloc_root(&thd->transaction.mem_root,
4158
savepoint_alloc_size)) == 0)
4160
my_error(ER_OUT_OF_RESOURCES, MYF(0));
4163
newsv->name=strmake_root(&thd->transaction.mem_root,
4164
lex->ident.str, lex->ident.length);
4165
newsv->length=lex->ident.length;
4167
if we'll get an error here, don't add new savepoint to the list.
4168
we'll lose a little bit of memory in transaction mem_root, but it'll
4169
be free'd when transaction ends anyway
4171
if (ha_savepoint(thd, newsv))
4175
newsv->prev=thd->transaction.savepoints;
4176
thd->transaction.savepoints=newsv;
4181
case SQLCOM_CREATE_PROCEDURE:
4182
case SQLCOM_CREATE_SPFUNCTION:
4186
int sp_result= SP_INTERNAL_ERROR;
4188
DBUG_ASSERT(lex->sphead != 0);
4189
DBUG_ASSERT(lex->sphead->m_db.str); /* Must be initialized in the parser */
4191
Verify that the database name is allowed, optionally
4194
if (check_db_name(&lex->sphead->m_db))
4196
my_error(ER_WRONG_DB_NAME, MYF(0), lex->sphead->m_db.str);
4197
goto create_sp_error;
4201
Check that a database directory with this name
4202
exists. Design note: This won't work on virtual databases
4203
like information_schema.
4205
if (check_db_dir_existence(lex->sphead->m_db.str))
4207
my_error(ER_BAD_DB_ERROR, MYF(0), lex->sphead->m_db.str);
4208
goto create_sp_error;
4211
if (check_access(thd, CREATE_PROC_ACL, lex->sphead->m_db.str, 0, 0, 0,
4212
is_schema_db(lex->sphead->m_db.str,
4213
lex->sphead->m_db.length)))
4214
goto create_sp_error;
4216
if (end_active_trans(thd))
4217
goto create_sp_error;
4219
name= lex->sphead->name(&namelen);
4221
if (lex->sphead->m_type == TYPE_ENUM_FUNCTION)
4223
udf_func *udf = find_udf(name, namelen);
4227
my_error(ER_UDF_EXISTS, MYF(0), name);
4228
goto create_sp_error;
4233
if (sp_process_definer(thd))
4234
goto create_sp_error;
4236
res= (sp_result= lex->sphead->create(thd));
4237
switch (sp_result) {
4239
#ifndef NO_EMBEDDED_ACCESS_CHECKS
4240
/* only add privileges if really neccessary */
4242
Security_context security_context;
4243
bool restore_backup_context= false;
4244
Security_context *backup= NULL;
4245
LEX_USER *definer= thd->lex->definer;
4247
Check if the definer exists on slave,
4248
then use definer privilege to insert routine privileges to mysql.procs_priv.
4250
For current user of SQL thread has GLOBAL_ACL privilege,
4251
which doesn't any check routine privileges,
4252
so no routine privilege record will insert into mysql.procs_priv.
4254
if (thd->slave_thread && is_acl_user(definer->host.str, definer->user.str))
4256
security_context.change_security_context(thd,
4257
&thd->lex->definer->user,
4258
&thd->lex->definer->host,
4259
&thd->lex->sphead->m_db,
4261
restore_backup_context= true;
4264
if (sp_automatic_privileges && !opt_noacl &&
4265
check_routine_access(thd, DEFAULT_CREATE_PROC_ACLS,
4266
lex->sphead->m_db.str, name,
4267
lex->sql_command == SQLCOM_CREATE_PROCEDURE, 1))
4269
if (sp_grant_privileges(thd, lex->sphead->m_db.str, name,
4270
lex->sql_command == SQLCOM_CREATE_PROCEDURE))
4271
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
4272
ER_PROC_AUTO_GRANT_FAIL,
4273
ER(ER_PROC_AUTO_GRANT_FAIL));
4277
Restore current user with GLOBAL_ACL privilege of SQL thread
4279
if (restore_backup_context)
4281
DBUG_ASSERT(thd->slave_thread == 1);
4282
thd->security_ctx->restore_security_context(thd, backup);
4288
case SP_WRITE_ROW_FAILED:
4289
my_error(ER_SP_ALREADY_EXISTS, MYF(0), SP_TYPE_STRING(lex), name);
4291
case SP_BAD_IDENTIFIER:
4292
my_error(ER_TOO_LONG_IDENT, MYF(0), name);
4294
case SP_BODY_TOO_LONG:
4295
my_error(ER_TOO_LONG_BODY, MYF(0), name);
4297
case SP_FLD_STORE_FAILED:
4298
my_error(ER_CANT_CREATE_SROUTINE, MYF(0), name);
4301
my_error(ER_SP_STORE_FAILED, MYF(0), SP_TYPE_STRING(lex), name);
4306
Capture all errors within this CASE and
4307
clean up the environment.
4310
if (sp_result != SP_OK )
4313
break; /* break super switch */
4314
} /* end case group bracket */
4320
This will cache all SP and SF and open and lock all tables
4321
required for execution.
4323
if (check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE) ||
4324
open_and_lock_tables(thd, all_tables))
4328
By this moment all needed SPs should be in cache so no need to look
4331
if (!(sp= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, lex->spname,
4332
&thd->sp_proc_cache, TRUE)))
4334
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PROCEDURE",
4335
lex->spname->m_qname.str);
4340
ha_rows select_limit;
4341
/* bits that should be cleared in thd->server_status */
4342
uint bits_to_be_cleared= 0;
4344
Check that the stored procedure doesn't contain Dynamic SQL
4345
and doesn't return result sets: such stored procedures can't
4346
be called from a function or trigger.
4348
if (thd->in_sub_stmt)
4350
const char *where= (thd->in_sub_stmt & SUB_STMT_TRIGGER ?
4351
"trigger" : "function");
4352
if (sp->is_not_allowed_in_function(where))
4356
if (sp->m_flags & sp_head::MULTI_RESULTS)
4358
if (! (thd->client_capabilities & CLIENT_MULTI_RESULTS))
4361
The client does not support multiple result sets being sent
4364
my_error(ER_SP_BADSELECT, MYF(0), sp->m_qname.str);
4368
If SERVER_MORE_RESULTS_EXISTS is not set,
4369
then remember that it should be cleared
4371
bits_to_be_cleared= (~thd->server_status &
4372
SERVER_MORE_RESULTS_EXISTS);
4373
thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
4376
if (check_routine_access(thd, EXECUTE_ACL,
4377
sp->m_db.str, sp->m_name.str, TRUE, FALSE))
4381
select_limit= thd->variables.select_limit;
4382
thd->variables.select_limit= HA_POS_ERROR;
4385
We never write CALL statements into binlog:
4386
- If the mode is non-prelocked, each statement will be logged
4388
- If the mode is prelocked, the invoking statement will care
4389
about writing into binlog.
4390
So just execute the statement.
4392
res= sp->execute_procedure(thd, &lex->value_list);
4394
If warnings have been cleared, we have to clear total_warn_count
4395
too, otherwise the clients get confused.
4397
if (thd->warn_list.is_empty())
4398
thd->total_warn_count= 0;
4400
thd->variables.select_limit= select_limit;
4402
thd->server_status&= ~bits_to_be_cleared;
4405
my_ok(thd, (ulong) (thd->row_count_func < 0 ? 0 :
4406
thd->row_count_func));
4409
DBUG_ASSERT(thd->is_error() || thd->killed);
4410
goto error; // Substatement should already have sent error
4415
case SQLCOM_ALTER_PROCEDURE:
4416
case SQLCOM_ALTER_FUNCTION:
4420
st_sp_chistics chistics;
4422
memcpy(&chistics, &lex->sp_chistics, sizeof(chistics));
4423
if (lex->sql_command == SQLCOM_ALTER_PROCEDURE)
4424
sp= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, lex->spname,
4425
&thd->sp_proc_cache, FALSE);
4427
sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, lex->spname,
4428
&thd->sp_func_cache, FALSE);
4429
mysql_reset_errors(thd, 0);
4432
if (lex->spname->m_db.str)
4433
sp_result= SP_KEY_NOT_FOUND;
4436
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
4442
if (check_routine_access(thd, ALTER_PROC_ACL, sp->m_db.str,
4444
lex->sql_command == SQLCOM_ALTER_PROCEDURE, 0))
4447
if (end_active_trans(thd))
4449
memcpy(&lex->sp_chistics, &chistics, sizeof(lex->sp_chistics));
4450
if ((sp->m_type == TYPE_ENUM_FUNCTION) &&
4451
!trust_function_creators && mysql_bin_log.is_open() &&
4452
!sp->m_chistics->detistic &&
4453
(chistics.daccess == SP_CONTAINS_SQL ||
4454
chistics.daccess == SP_MODIFIES_SQL_DATA))
4456
my_message(ER_BINLOG_UNSAFE_ROUTINE,
4457
ER(ER_BINLOG_UNSAFE_ROUTINE), MYF(0));
4458
sp_result= SP_INTERNAL_ERROR;
4463
Note that if you implement the capability of ALTER FUNCTION to
4464
alter the body of the function, this command should be made to
4465
follow the restrictions that log-bin-trust-function-creators=0
4466
already puts on CREATE FUNCTION.
4468
/* Conditionally writes to binlog */
4470
int type= lex->sql_command == SQLCOM_ALTER_PROCEDURE ?
4471
TYPE_ENUM_PROCEDURE :
4474
sp_result= sp_update_routine(thd,
4485
case SP_KEY_NOT_FOUND:
4486
my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
4487
SP_COM_STRING(lex), lex->spname->m_qname.str);
4490
my_error(ER_SP_CANT_ALTER, MYF(0),
4491
SP_COM_STRING(lex), lex->spname->m_qname.str);
4496
case SQLCOM_DROP_PROCEDURE:
4497
case SQLCOM_DROP_FUNCTION:
4500
int type= (lex->sql_command == SQLCOM_DROP_PROCEDURE ?
4501
TYPE_ENUM_PROCEDURE : TYPE_ENUM_FUNCTION);
4503
sp_result= sp_routine_exists_in_table(thd, type, lex->spname);
4504
mysql_reset_errors(thd, 0);
4505
if (sp_result == SP_OK)
4507
char *db= lex->spname->m_db.str;
4508
char *name= lex->spname->m_name.str;
4510
if (check_routine_access(thd, ALTER_PROC_ACL, db, name,
4511
lex->sql_command == SQLCOM_DROP_PROCEDURE, 0))
4514
if (end_active_trans(thd))
4516
#ifndef NO_EMBEDDED_ACCESS_CHECKS
4517
if (sp_automatic_privileges && !opt_noacl &&
4518
sp_revoke_privileges(thd, db, name,
4519
lex->sql_command == SQLCOM_DROP_PROCEDURE))
4521
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
4522
ER_PROC_AUTO_REVOKE_FAIL,
4523
ER(ER_PROC_AUTO_REVOKE_FAIL));
4526
/* Conditionally writes to binlog */
4528
int type= lex->sql_command == SQLCOM_DROP_PROCEDURE ?
4529
TYPE_ENUM_PROCEDURE :
4532
sp_result= sp_drop_routine(thd, type, lex->spname);
4537
if (lex->sql_command == SQLCOM_DROP_FUNCTION)
4539
udf_func *udf = find_udf(lex->spname->m_name.str,
4540
lex->spname->m_name.length);
4543
if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 0, 0))
4546
if (!(res = mysql_drop_function(thd, &lex->spname->m_name)))
4554
if (lex->spname->m_db.str)
4555
sp_result= SP_KEY_NOT_FOUND;
4558
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
4563
switch (sp_result) {
4567
case SP_KEY_NOT_FOUND:
4568
if (lex->drop_if_exists)
4570
res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
4571
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
4572
ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST),
4573
SP_COM_STRING(lex), lex->spname->m_name.str);
4578
my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
4579
SP_COM_STRING(lex), lex->spname->m_qname.str);
4582
my_error(ER_SP_DROP_FAILED, MYF(0),
4583
SP_COM_STRING(lex), lex->spname->m_qname.str);
4588
case SQLCOM_SHOW_CREATE_PROC:
4590
if (sp_show_create_routine(thd, TYPE_ENUM_PROCEDURE, lex->spname))
4592
my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
4593
SP_COM_STRING(lex), lex->spname->m_name.str);
4598
case SQLCOM_SHOW_CREATE_FUNC:
4600
if (sp_show_create_routine(thd, TYPE_ENUM_FUNCTION, lex->spname))
4602
my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
4603
SP_COM_STRING(lex), lex->spname->m_name.str);
4609
case SQLCOM_SHOW_PROC_CODE:
4610
case SQLCOM_SHOW_FUNC_CODE:
4614
if (lex->sql_command == SQLCOM_SHOW_PROC_CODE)
4615
sp= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, lex->spname,
4616
&thd->sp_proc_cache, FALSE);
4618
sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, lex->spname,
4619
&thd->sp_func_cache, FALSE);
4620
if (!sp || sp->show_routine_code(thd))
4622
/* We don't distinguish between errors for now */
4623
my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
4624
SP_COM_STRING(lex), lex->spname->m_name.str);
4629
#endif // ifndef DBUG_OFF
4630
case SQLCOM_SHOW_CREATE_TRIGGER:
4632
if (lex->spname->m_name.length > NAME_LEN)
4634
my_error(ER_TOO_LONG_IDENT, MYF(0), lex->spname->m_name.str);
4638
if (show_create_trigger(thd, lex->spname))
4639
goto error; /* Error has been already logged. */
4643
case SQLCOM_CREATE_VIEW:
4646
Note: SQLCOM_CREATE_VIEW also handles 'ALTER VIEW' commands
4647
as specified through the thd->lex->create_view_mode flag.
4649
if (end_active_trans(thd))
4652
res= mysql_create_view(thd, first_table, thd->lex->create_view_mode);
4655
case SQLCOM_DROP_VIEW:
4657
if (check_table_access(thd, DROP_ACL, all_tables, UINT_MAX, FALSE) ||
4658
end_active_trans(thd))
4660
/* Conditionally writes to binlog. */
4661
res= mysql_drop_view(thd, first_table, thd->lex->drop_mode);
4664
case SQLCOM_CREATE_TRIGGER:
4666
if (end_active_trans(thd))
4669
/* Conditionally writes to binlog. */
4670
res= mysql_create_or_drop_trigger(thd, all_tables, 1);
4674
case SQLCOM_DROP_TRIGGER:
4676
if (end_active_trans(thd))
4679
/* Conditionally writes to binlog. */
4680
res= mysql_create_or_drop_trigger(thd, all_tables, 0);
4683
case SQLCOM_XA_START:
4684
if (thd->transaction.xid_state.xa_state == XA_IDLE &&
4685
thd->lex->xa_opt == XA_RESUME)
4687
if (! thd->transaction.xid_state.xid.eq(thd->lex->xid))
4689
my_error(ER_XAER_NOTA, MYF(0));
4692
thd->transaction.xid_state.xa_state=XA_ACTIVE;
4696
if (thd->lex->xa_opt != XA_NONE)
4697
{ // JOIN is not supported yet. TODO
4698
my_error(ER_XAER_INVAL, MYF(0));
4701
if (thd->transaction.xid_state.xa_state != XA_NOTR)
4703
my_error(ER_XAER_RMFAIL, MYF(0),
4704
xa_state_names[thd->transaction.xid_state.xa_state]);
4707
if (thd->active_transaction() || thd->locked_tables)
4709
my_error(ER_XAER_OUTSIDE, MYF(0));
4712
if (xid_cache_search(thd->lex->xid))
4714
my_error(ER_XAER_DUPID, MYF(0));
4717
DBUG_ASSERT(thd->transaction.xid_state.xid.is_null());
4718
thd->transaction.xid_state.xa_state=XA_ACTIVE;
4719
thd->transaction.xid_state.rm_error= 0;
4720
thd->transaction.xid_state.xid.set(thd->lex->xid);
4721
xid_cache_insert(&thd->transaction.xid_state);
4722
thd->transaction.all.modified_non_trans_table= FALSE;
4723
thd->options= ((thd->options & ~(OPTION_KEEP_LOG)) | OPTION_BEGIN);
4724
thd->server_status|= SERVER_STATUS_IN_TRANS;
4729
if (thd->lex->xa_opt != XA_NONE)
4730
{ // SUSPEND and FOR MIGRATE are not supported yet. TODO
4731
my_error(ER_XAER_INVAL, MYF(0));
4734
if (thd->transaction.xid_state.xa_state != XA_ACTIVE)
4736
my_error(ER_XAER_RMFAIL, MYF(0),
4737
xa_state_names[thd->transaction.xid_state.xa_state]);
4740
if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
4742
my_error(ER_XAER_NOTA, MYF(0));
4745
if (xa_trans_rolled_back(&thd->transaction.xid_state))
4747
thd->transaction.xid_state.xa_state=XA_IDLE;
4750
case SQLCOM_XA_PREPARE:
4751
if (thd->transaction.xid_state.xa_state != XA_IDLE)
4753
my_error(ER_XAER_RMFAIL, MYF(0),
4754
xa_state_names[thd->transaction.xid_state.xa_state]);
4757
if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
4759
my_error(ER_XAER_NOTA, MYF(0));
4762
if (ha_prepare(thd))
4764
my_error(ER_XA_RBROLLBACK, MYF(0));
4765
xid_cache_delete(&thd->transaction.xid_state);
4766
thd->transaction.xid_state.xa_state=XA_NOTR;
4769
thd->transaction.xid_state.xa_state=XA_PREPARED;
4772
case SQLCOM_XA_COMMIT:
4773
if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
4775
XID_STATE *xs=xid_cache_search(thd->lex->xid);
4776
if (!xs || xs->in_thd)
4777
my_error(ER_XAER_NOTA, MYF(0));
4778
else if (xa_trans_rolled_back(xs))
4780
ha_commit_or_rollback_by_xid(thd->lex->xid, 0);
4781
xid_cache_delete(xs);
4786
ha_commit_or_rollback_by_xid(thd->lex->xid, 1);
4787
xid_cache_delete(xs);
4792
if (xa_trans_rolled_back(&thd->transaction.xid_state))
4794
xa_trans_rollback(thd);
4797
if (thd->transaction.xid_state.xa_state == XA_IDLE &&
4798
thd->lex->xa_opt == XA_ONE_PHASE)
4801
if ((r= ha_commit(thd)))
4802
my_error(r == 1 ? ER_XA_RBROLLBACK : ER_XAER_RMERR, MYF(0));
4806
else if (thd->transaction.xid_state.xa_state == XA_PREPARED &&
4807
thd->lex->xa_opt == XA_NONE)
4809
if (wait_if_global_read_lock(thd, 0, 0))
4812
my_error(ER_XAER_RMERR, MYF(0));
4816
if (ha_commit_one_phase(thd, 1))
4817
my_error(ER_XAER_RMERR, MYF(0));
4820
start_waiting_global_read_lock(thd);
4825
my_error(ER_XAER_RMFAIL, MYF(0),
4826
xa_state_names[thd->transaction.xid_state.xa_state]);
4829
thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
4830
thd->transaction.all.modified_non_trans_table= FALSE;
4831
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
4832
xid_cache_delete(&thd->transaction.xid_state);
4833
thd->transaction.xid_state.xa_state=XA_NOTR;
4835
case SQLCOM_XA_ROLLBACK:
4836
if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
4838
XID_STATE *xs=xid_cache_search(thd->lex->xid);
4839
if (!xs || xs->in_thd)
4840
my_error(ER_XAER_NOTA, MYF(0));
4843
bool ok= !xa_trans_rolled_back(xs);
4844
ha_commit_or_rollback_by_xid(thd->lex->xid, 0);
4845
xid_cache_delete(xs);
4851
if (thd->transaction.xid_state.xa_state != XA_IDLE &&
4852
thd->transaction.xid_state.xa_state != XA_PREPARED &&
4853
thd->transaction.xid_state.xa_state != XA_ROLLBACK_ONLY)
4855
my_error(ER_XAER_RMFAIL, MYF(0),
4856
xa_state_names[thd->transaction.xid_state.xa_state]);
4859
if (xa_trans_rollback(thd))
4860
my_error(ER_XAER_RMERR, MYF(0));
4864
case SQLCOM_XA_RECOVER:
4865
res= mysql_xa_recover(thd);
4867
case SQLCOM_ALTER_TABLESPACE:
4868
if (check_access(thd, ALTER_ACL, thd->db, 0, 1, 0,
4869
thd->db ? is_schema_db(thd->db, thd->db_length) : 0))
4871
if (!(res= mysql_alter_tablespace(thd, lex->alter_tablespace_info)))
4874
case SQLCOM_INSTALL_PLUGIN:
4875
if (! (res= mysql_install_plugin(thd, &thd->lex->comment,
4879
case SQLCOM_UNINSTALL_PLUGIN:
4880
if (! (res= mysql_uninstall_plugin(thd, &thd->lex->comment)))
4883
case SQLCOM_BINLOG_BASE64_EVENT:
4885
#ifndef EMBEDDED_LIBRARY
4886
mysql_client_binlog_statement(thd);
4887
#else /* EMBEDDED_LIBRARY */
4888
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "embedded");
4889
#endif /* EMBEDDED_LIBRARY */
4892
case SQLCOM_CREATE_SERVER:
4896
DBUG_PRINT("info", ("case SQLCOM_CREATE_SERVER"));
4898
if (check_global_access(thd, SUPER_ACL))
4901
if ((error= create_server(thd, &lex->server_options)))
4903
DBUG_PRINT("info", ("problem creating server <%s>",
4904
lex->server_options.server_name));
4905
my_error(error, MYF(0), lex->server_options.server_name);
4911
case SQLCOM_ALTER_SERVER:
4915
DBUG_PRINT("info", ("case SQLCOM_ALTER_SERVER"));
4917
if (check_global_access(thd, SUPER_ACL))
4920
if ((error= alter_server(thd, &lex->server_options)))
4922
DBUG_PRINT("info", ("problem altering server <%s>",
4923
lex->server_options.server_name));
4924
my_error(error, MYF(0), lex->server_options.server_name);
4930
case SQLCOM_DROP_SERVER:
4934
DBUG_PRINT("info", ("case SQLCOM_DROP_SERVER"));
4936
if (check_global_access(thd, SUPER_ACL))
4939
if ((err_code= drop_server(thd, &lex->server_options)))
4941
if (! lex->drop_if_exists && err_code == ER_FOREIGN_SERVER_DOESNT_EXIST)
4943
DBUG_PRINT("info", ("problem dropping server %s",
4944
lex->server_options.server_name));
4945
my_error(err_code, MYF(0), lex->server_options.server_name);
4957
#ifndef EMBEDDED_LIBRARY
4958
DBUG_ASSERT(0); /* Impossible */
4963
thd_proc_info(thd, "query end");
4966
Binlog-related cleanup:
4967
Reset system variables temporarily modified by SET ONE SHOT.
4969
Exception: If this is a SET, do nothing. This is to allow
4970
mysqlbinlog to print many SET commands (in this case we want the
4971
charset temp setting to live until the real query). This is also
4972
needed so that SET CHARACTER_SET_CLIENT... does not cancel itself
4975
if (thd->one_shot_set && lex->sql_command != SQLCOM_SET_OPTION)
4976
reset_one_shot_variables(thd);
4979
The return value for ROW_COUNT() is "implementation dependent" if the
4980
statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC
4981
wants. We also keep the last value in case of SQLCOM_CALL or
4984
if (!(sql_command_flags[lex->sql_command] & CF_HAS_ROW_COUNT))
4985
thd->row_count_func= -1;
4993
if (need_start_waiting)
4996
Release the protection against the global read lock and wake
4997
everyone, who might want to set a global read lock.
4999
start_waiting_global_read_lock(thd);
5001
DBUG_RETURN(res || thd->is_error());
5005
static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
5008
select_result *result=lex->result;
5010
/* assign global limit variable if limit is not given */
5012
SELECT_LEX *param= lex->unit.global_parameters;
5013
if (!param->explicit_limit)
5014
param->select_limit=
5015
new Item_int((ulonglong) thd->variables.select_limit);
5017
if (!(res= open_and_lock_tables(thd, all_tables)))
5022
We always use select_send for EXPLAIN, even if it's an EXPLAIN
5023
for SELECT ... INTO OUTFILE: a user application should be able
5024
to prepend EXPLAIN to any query and receive output for it,
5025
even if the query itself redirects the output.
5027
if (!(result= new select_send()))
5028
return 1; /* purecov: inspected */
5029
thd->send_explain_fields(result);
5030
res= mysql_explain_union(thd, &thd->lex->unit, result);
5031
if (lex->describe & DESCRIBE_EXTENDED)
5034
String str(buff,(uint32) sizeof(buff), system_charset_info);
5036
thd->lex->unit.print(&str, QT_ORDINARY);
5038
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
5049
if (!result && !(result= new select_send()))
5050
return 1; /* purecov: inspected */
5051
query_cache_store_query(thd, all_tables);
5052
res= handle_select(thd, lex, result, 0);
5053
if (result != lex->result)
5061
#ifndef NO_EMBEDDED_ACCESS_CHECKS
5063
Check grants for commands which work only with one table.
5065
@param thd Thread handler
5066
@param privilege requested privilege
5067
@param all_tables global table list of query
5068
@param no_errors FALSE/TRUE - report/don't report error to
5069
the client (using my_error() call).
5074
1 access denied, error is sent to client
5077
bool check_single_table_access(THD *thd, ulong privilege,
5078
TABLE_LIST *all_tables, bool no_errors)
5080
Security_context * backup_ctx= thd->security_ctx;
5082
/* we need to switch to the saved context (if any) */
5083
if (all_tables->security_ctx)
5084
thd->security_ctx= all_tables->security_ctx;
5086
const char *db_name;
5087
if ((all_tables->view || all_tables->field_translation) &&
5088
!all_tables->schema_table)
5089
db_name= all_tables->view_db.str;
5091
db_name= all_tables->db;
5093
if (check_access(thd, privilege, db_name,
5094
&all_tables->grant.privilege, 0, no_errors,
5095
test(all_tables->schema_table)))
5098
/* Show only 1 table for check_grant */
5099
if (!(all_tables->belong_to_view &&
5100
(thd->lex->sql_command == SQLCOM_SHOW_FIELDS)) &&
5101
check_grant(thd, privilege, all_tables, 0, 1, no_errors))
5104
thd->security_ctx= backup_ctx;
5108
thd->security_ctx= backup_ctx;
5113
Check grants for commands which work only with one table and all other
5114
tables belonging to subselects or implicitly opened tables.
5116
@param thd Thread handler
5117
@param privilege requested privilege
5118
@param all_tables global table list of query
5123
1 access denied, error is sent to client
5126
bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *all_tables)
5128
if (check_single_table_access (thd,privilege,all_tables, FALSE))
5131
/* Check rights on tables of subselects and implictly opened tables */
5132
TABLE_LIST *subselects_tables, *view= all_tables->view ? all_tables : 0;
5133
if ((subselects_tables= all_tables->next_global))
5136
Access rights asked for the first table of a view should be the same
5139
if (view && subselects_tables->belong_to_view == view)
5141
if (check_single_table_access (thd, privilege, subselects_tables, FALSE))
5143
subselects_tables= subselects_tables->next_global;
5145
if (subselects_tables &&
5146
(check_table_access(thd, SELECT_ACL, subselects_tables, UINT_MAX, FALSE)))
5154
Get the user (global) and database privileges for all used tables.
5156
@param save_priv In this we store global and db level grants for the
5157
table. Note that we don't store db level grants if the
5158
global grants is enough to satisfy the request and the
5159
global grants contains a SELECT grant.
5162
The idea of EXTRA_ACL is that one will be granted access to the table if
5163
one has the asked privilege on any column combination of the table; For
5164
example to be able to check a table one needs to have SELECT privilege on
5165
any column of the table.
5170
1 If we can't get the privileges and we don't use table/column
5174
check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
5175
bool dont_check_global_grants, bool no_errors, bool schema_db)
5177
Security_context *sctx= thd->security_ctx;
5181
In case of database level grant the database name may be a pattern,
5182
in case of table|column level grant the database name can not be a pattern.
5183
We use 'dont_check_global_grants' as a flag to determine
5184
if it's database level grant command
5185
(see SQLCOM_GRANT case, mysql_execute_command() function) and
5186
set db_is_pattern according to 'dont_check_global_grants' value.
5188
bool db_is_pattern= (test(want_access & GRANT_ACL) &&
5189
dont_check_global_grants);
5191
DBUG_ENTER("check_access");
5192
DBUG_PRINT("enter",("db: %s want_access: %lu master_access: %lu",
5193
db ? db : "", want_access, sctx->master_access));
5199
thd_proc_info(thd, "checking permissions");
5200
if ((!db || !db[0]) && !thd->db && !dont_check_global_grants)
5202
DBUG_PRINT("error",("No database"));
5204
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR),
5205
MYF(0)); /* purecov: tested */
5206
DBUG_RETURN(TRUE); /* purecov: tested */
5211
if ((!(sctx->master_access & FILE_ACL) && (want_access & FILE_ACL)) ||
5212
(want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL)))
5216
const char *db_name= db ? db : thd->db;
5217
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
5218
sctx->priv_user, sctx->priv_host, db_name);
5224
*save_priv= SELECT_ACL;
5229
if ((sctx->master_access & want_access) == want_access)
5232
If we don't have a global SELECT privilege, we have to get the database
5233
specific access rights to be able to handle queries of type
5234
UPDATE t1 SET a=1 WHERE b > 0
5236
db_access= sctx->db_access;
5237
if (!(sctx->master_access & SELECT_ACL) &&
5238
(db && (!thd->db || db_is_pattern || strcmp(db,thd->db))))
5239
db_access=acl_get(sctx->host, sctx->ip, sctx->priv_user, db,
5241
*save_priv=sctx->master_access | db_access;
5244
if (((want_access & ~sctx->master_access) & ~(DB_ACLS | EXTRA_ACL)) ||
5245
(! db && dont_check_global_grants))
5246
{ // We can never grant this
5247
DBUG_PRINT("error",("No possible access"));
5249
my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
5254
ER(ER_NO))); /* purecov: tested */
5255
DBUG_RETURN(TRUE); /* purecov: tested */
5259
DBUG_RETURN(FALSE); // Allow select on anything
5261
if (db && (!thd->db || db_is_pattern || strcmp(db,thd->db)))
5262
db_access= acl_get(sctx->host, sctx->ip, sctx->priv_user, db,
5265
db_access= sctx->db_access;
5266
DBUG_PRINT("info",("db_access: %lu", db_access));
5267
/* Remove SHOW attribute and access rights we already have */
5268
want_access &= ~(sctx->master_access | EXTRA_ACL);
5269
DBUG_PRINT("info",("db_access: %lu want_access: %lu",
5270
db_access, want_access));
5271
db_access= ((*save_priv=(db_access | sctx->master_access)) & want_access);
5273
if (db_access == want_access ||
5274
(!dont_check_global_grants &&
5275
!(want_access & ~(db_access | TABLE_ACLS | PROC_ACLS))))
5276
DBUG_RETURN(FALSE); /* Ok */
5278
DBUG_PRINT("error",("Access denied"));
5280
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
5281
sctx->priv_user, sctx->priv_host,
5282
(db ? db : (thd->db ?
5284
"unknown"))); /* purecov: tested */
5285
DBUG_RETURN(TRUE); /* purecov: tested */
5289
static bool check_show_access(THD *thd, TABLE_LIST *table)
5291
switch (get_schema_table_idx(table->schema_table)) {
5293
return (specialflag & SPECIAL_SKIP_SHOW_DB) &&
5294
check_global_access(thd, SHOW_DB_ACL);
5296
case SCH_TABLE_NAMES:
5302
const char *dst_db_name= table->schema_select_lex->db;
5304
DBUG_ASSERT(dst_db_name);
5306
if (check_access(thd, SELECT_ACL, dst_db_name,
5307
&thd->col_access, FALSE, FALSE,
5308
is_schema_db(dst_db_name)))
5311
if (!thd->col_access && check_grant_db(thd, dst_db_name))
5313
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
5314
thd->security_ctx->priv_user,
5315
thd->security_ctx->priv_host,
5324
case SCH_STATISTICS:
5326
TABLE_LIST *dst_table;
5327
dst_table= (TABLE_LIST *) table->schema_select_lex->table_list.first;
5329
DBUG_ASSERT(dst_table);
5331
if (check_access(thd, SELECT_ACL | EXTRA_ACL,
5333
&dst_table->grant.privilege,
5335
test(dst_table->schema_table)))
5338
return (check_grant(thd, SELECT_ACL, dst_table, 2, UINT_MAX, FALSE));
5349
Check the privilege for all used tables.
5351
@param thd Thread context
5352
@param want_access Privileges requested
5353
@param tables List of tables to be checked
5354
@param number Check at most this number of tables.
5355
@param no_errors FALSE/TRUE - report/don't report error to
5356
the client (using my_error() call).
5359
Table privileges are cached in the table list for GRANT checking.
5360
This functions assumes that table list used and
5361
thd->lex->query_tables_own_last value correspond to each other
5362
(the latter should be either 0 or point to next_global member
5363
of one of elements of this table list).
5366
@retval TRUE Access denied
5370
check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
5371
uint number, bool no_errors)
5373
TABLE_LIST *org_tables= tables;
5374
TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table();
5376
Security_context *sctx= thd->security_ctx, *backup_ctx= thd->security_ctx;
5378
The check that first_not_own_table is not reached is for the case when
5379
the given table list refers to the list for prelocking (contains tables
5380
of other queries). For simple queries first_not_own_table is 0.
5382
for (; i < number && tables != first_not_own_table;
5383
tables= tables->next_global, i++)
5385
if (tables->security_ctx)
5386
sctx= tables->security_ctx;
5390
if (tables->schema_table &&
5391
(want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL)))
5394
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
5395
sctx->priv_user, sctx->priv_host,
5396
INFORMATION_SCHEMA_NAME.str);
5400
Register access for view underlying table.
5401
Remove SHOW_VIEW_ACL, because it will be checked during making view
5403
tables->grant.orig_want_privilege= (want_access & ~SHOW_VIEW_ACL);
5405
if (tables->schema_table_reformed)
5407
if (check_show_access(thd, tables))
5413
if (tables->is_anonymous_derived_table() ||
5414
(tables->table && (int)tables->table->s->tmp_table))
5416
thd->security_ctx= sctx;
5417
if ((sctx->master_access & want_access) ==
5418
(want_access & ~EXTRA_ACL) &&
5420
tables->grant.privilege= want_access;
5421
else if (tables->db && thd->db && strcmp(tables->db, thd->db) == 0)
5423
if (check_access(thd, want_access, tables->get_db_name(),
5424
&tables->grant.privilege, 0, no_errors,
5425
test(tables->schema_table)))
5426
goto deny; // Access denied
5428
else if (check_access(thd, want_access, tables->get_db_name(),
5429
&tables->grant.privilege, 0, no_errors,
5430
test(tables->schema_table)))
5433
thd->security_ctx= backup_ctx;
5434
return check_grant(thd,want_access & ~EXTRA_ACL,org_tables,
5435
test(want_access & EXTRA_ACL), number, no_errors);
5437
thd->security_ctx= backup_ctx;
5443
check_routine_access(THD *thd, ulong want_access,char *db, char *name,
5444
bool is_proc, bool no_errors)
5446
TABLE_LIST tables[1];
5448
bzero((char *)tables, sizeof(TABLE_LIST));
5450
tables->table_name= tables->alias= name;
5453
The following test is just a shortcut for check_access() (to avoid
5454
calculating db_access) under the assumption that it's common to
5455
give persons global right to execute all stored SP (but not
5456
necessary to create them).
5458
if ((thd->security_ctx->master_access & want_access) == want_access)
5459
tables->grant.privilege= want_access;
5460
else if (check_access(thd,want_access,db,&tables->grant.privilege,
5464
return check_grant_routine(thd, want_access, tables, is_proc, no_errors);
5469
Check if the routine has any of the routine privileges.
5471
@param thd Thread handler
5472
@param db Database name
5473
@param name Routine name
5481
bool check_some_routine_access(THD *thd, const char *db, const char *name,
5485
if (thd->security_ctx->master_access & SHOW_PROC_ACLS)
5488
There are no routines in information_schema db. So we can safely
5489
pass zero to last paramter of check_access function
5491
if (!check_access(thd, SHOW_PROC_ACLS, db, &save_priv, 0, 1, 0) ||
5492
(save_priv & SHOW_PROC_ACLS))
5494
return check_routine_level_acl(thd, db, name, is_proc);
5499
Check if the given table has any of the asked privileges
5501
@param thd Thread handler
5502
@param want_access Bitmap of possible privileges to check for
5510
bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table)
5513
DBUG_ENTER("check_some_access");
5515
/* This loop will work as long as we have less than 32 privileges */
5516
for (access= 1; access < want_access ; access<<= 1)
5518
if (access & want_access)
5520
if (!check_access(thd, access, table->db,
5521
&table->grant.privilege, 0, 1,
5522
test(table->schema_table)) &&
5523
!check_grant(thd, access, table, 0, 1, 1))
5527
DBUG_PRINT("exit",("no matching access rights"));
5531
#endif /*NO_EMBEDDED_ACCESS_CHECKS*/
5535
check for global access and give descriptive error message if it fails.
5537
@param thd Thread handler
5538
@param want_access Use should have any of these global rights
5541
One gets access right if one has ANY of the rights in want_access.
5542
This is useful as one in most cases only need one global right,
5543
but in some case we want to check if the user has SUPER or
5544
REPL_CLIENT_ACL rights.
5549
1 Access denied. In this case an error is sent to the client
5552
bool check_global_access(THD *thd, ulong want_access)
5554
#ifndef NO_EMBEDDED_ACCESS_CHECKS
5556
if ((thd->security_ctx->master_access & want_access))
5558
get_privilege_desc(command, sizeof(command), want_access);
5559
my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command);
5566
/****************************************************************************
5567
Check stack size; Send error if there isn't enough stack to continue
5568
****************************************************************************/
5570
#ifndef EMBEDDED_LIBRARY
5572
#if STACK_DIRECTION < 0
5573
#define used_stack(A,B) (long) (A - B)
5575
#define used_stack(A,B) (long) (B - A)
5579
long max_stack_used;
5584
Note: The 'buf' parameter is necessary, even if it is unused here.
5585
- fix_fields functions has a "dummy" buffer large enough for the
5586
corresponding exec. (Thus we only have to check in fix_fields.)
5587
- Passing to check_stack_overrun() prevents the compiler from removing it.
5589
bool check_stack_overrun(THD *thd, long margin,
5590
uchar *buf __attribute__((unused)))
5593
DBUG_ASSERT(thd == current_thd);
5594
if ((stack_used=used_stack(thd->thread_stack,(char*) &stack_used)) >=
5595
(long) (my_thread_stack_size - margin))
5597
char ebuff[MYSQL_ERRMSG_SIZE];
5598
my_snprintf(ebuff, sizeof(ebuff), ER(ER_STACK_OVERRUN_NEED_MORE),
5599
stack_used, my_thread_stack_size, margin);
5600
my_message(ER_STACK_OVERRUN_NEED_MORE, ebuff, MYF(ME_FATALERROR));
5605
max_stack_used= max(max_stack_used, stack_used);
5609
#endif /* EMBEDDED_LIBRARY */
5611
#define MY_YACC_INIT 1000 // Start with big alloc
5612
#define MY_YACC_MAX 32000 // Because of 'short'
5614
bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, ulong *yystacksize)
5616
Yacc_state *state= & current_thd->m_parser_state->m_yacc;
5619
if ((uint) *yystacksize >= MY_YACC_MAX)
5621
if (!state->yacc_yyvs)
5622
old_info= *yystacksize;
5623
*yystacksize= set_zone((*yystacksize)*2,MY_YACC_INIT,MY_YACC_MAX);
5624
if (!(state->yacc_yyvs= (uchar*)
5625
my_realloc(state->yacc_yyvs,
5626
*yystacksize*sizeof(**yyvs),
5627
MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))) ||
5628
!(state->yacc_yyss= (uchar*)
5629
my_realloc(state->yacc_yyss,
5630
*yystacksize*sizeof(**yyss),
5631
MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))))
5636
Only copy the old stack on the first call to my_yyoverflow(),
5637
when replacing a static stack (YYINITDEPTH) by a dynamic stack.
5638
For subsequent calls, my_realloc already did preserve the old stack.
5640
memcpy(state->yacc_yyss, *yyss, old_info*sizeof(**yyss));
5641
memcpy(state->yacc_yyvs, *yyvs, old_info*sizeof(**yyvs));
5643
*yyss= (short*) state->yacc_yyss;
5644
*yyvs= (YYSTYPE*) state->yacc_yyvs;
5650
Reset THD part responsible for command processing state.
5652
This needs to be called before execution of every statement
5653
(prepared or conventional).
5654
It is not called by substatements of routines.
5657
Make it a method of THD and align its name with the rest of
5658
reset/end/start/init methods.
5660
Call it after we use THD for queries, not before.
5663
void mysql_reset_thd_for_next_command(THD *thd)
5665
DBUG_ENTER("mysql_reset_thd_for_next_command");
5666
DBUG_ASSERT(!thd->spcont); /* not for substatements of routines */
5667
DBUG_ASSERT(! thd->in_sub_stmt);
5669
thd->select_number= 1;
5671
Those two lines below are theoretically unneeded as
5672
THD::cleanup_after_query() should take care of this already.
5674
thd->auto_inc_intervals_in_cur_stmt_for_binlog.empty();
5675
thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
5677
thd->query_start_used= 0;
5678
thd->is_fatal_error= thd->time_zone_used= 0;
5680
Clear the status flag that are expected to be cleared at the
5681
beginning of each SQL statement.
5683
thd->server_status&= ~SERVER_STATUS_CLEAR_SET;
5685
If in autocommit mode and not in a transaction, reset
5686
OPTION_STATUS_NO_TRANS_UPDATE | OPTION_KEEP_LOG to not get warnings
5687
in ha_rollback_trans() about some tables couldn't be rolled back.
5689
if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
5691
thd->options&= ~OPTION_KEEP_LOG;
5692
thd->transaction.all.modified_non_trans_table= FALSE;
5694
DBUG_ASSERT(thd->security_ctx== &thd->main_security_ctx);
5695
thd->thread_specific_used= FALSE;
5699
reset_dynamic(&thd->user_var_events);
5700
thd->user_var_events_alloc= thd->mem_root;
5703
thd->main_da.reset_diagnostics_area();
5704
thd->total_warn_count=0; // Warnings for this query
5706
thd->sent_row_count= thd->examined_row_count= 0;
5709
Because we come here only for start of top-statements, binlog format is
5710
constant inside a complex statement (using stored functions) etc.
5712
thd->reset_current_stmt_binlog_row_based();
5715
("current_stmt_binlog_row_based: %d",
5716
thd->current_stmt_binlog_row_based));
5723
Resets the lex->current_select object.
5724
@note It is assumed that lex->current_select != NULL
5726
This function is a wrapper around select_lex->init_select() with an added
5727
check for the special situation when using INTO OUTFILE and LOAD DATA.
5731
mysql_init_select(LEX *lex)
5733
SELECT_LEX *select_lex= lex->current_select;
5734
select_lex->init_select();
5736
if (select_lex == &lex->select_lex)
5738
DBUG_ASSERT(lex->result == 0);
5745
Used to allocate a new SELECT_LEX object on the current thd mem_root and
5746
link it into the relevant lists.
5748
This function is always followed by mysql_init_select.
5750
@see mysql_init_select
5752
@retval TRUE An error occurred
5753
@retval FALSE The new SELECT_LEX was successfully allocated.
5757
mysql_new_select(LEX *lex, bool move_down)
5759
SELECT_LEX *select_lex;
5761
DBUG_ENTER("mysql_new_select");
5763
if (!(select_lex= new (thd->mem_root) SELECT_LEX()))
5765
select_lex->select_number= ++thd->select_number;
5766
select_lex->parent_lex= lex; /* Used in init_query. */
5767
select_lex->init_query();
5768
select_lex->init_select();
5770
if (lex->nest_level > (int) MAX_SELECT_NESTING)
5772
my_error(ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT,MYF(0),MAX_SELECT_NESTING);
5775
select_lex->nest_level= lex->nest_level;
5777
Don't evaluate this subquery during statement prepare even if
5778
it's a constant one. The flag is switched off in the end of
5779
mysqld_stmt_prepare.
5781
if (thd->stmt_arena->is_stmt_prepare())
5782
select_lex->uncacheable|= UNCACHEABLE_PREPARE;
5785
SELECT_LEX_UNIT *unit;
5786
lex->subqueries= TRUE;
5787
/* first select_lex of subselect or derived table */
5788
if (!(unit= new (thd->mem_root) SELECT_LEX_UNIT()))
5792
unit->init_select();
5794
unit->include_down(lex->current_select);
5797
unit->return_to= lex->current_select;
5798
select_lex->include_down(unit);
5800
By default we assume that it is usual subselect and we have outer name
5801
resolution context, if no we will assign it to 0 later
5803
select_lex->context.outer_context= &select_lex->outer_select()->context;
5807
if (lex->current_select->order_list.first && !lex->current_select->braces)
5809
my_error(ER_WRONG_USAGE, MYF(0), "UNION", "ORDER BY");
5812
select_lex->include_neighbour(lex->current_select);
5813
SELECT_LEX_UNIT *unit= select_lex->master_unit();
5814
if (!unit->fake_select_lex && unit->add_fake_select_lex(lex->thd))
5816
select_lex->context.outer_context=
5817
unit->first_select()->context.outer_context;
5820
select_lex->master_unit()->global_parameters= select_lex;
5821
select_lex->include_global((st_select_lex_node**)&lex->all_selects_list);
5822
lex->current_select= select_lex;
5824
in subquery is SELECT query and we allow resolution of names in SELECT
5827
select_lex->context.resolve_in_select_list= TRUE;
5832
Create a select to return the same output as 'SELECT @@var_name'.
5834
Used for SHOW COUNT(*) [ WARNINGS | ERROR].
5836
This will crash with a core dump if the variable doesn't exists.
5838
@param var_name Variable name
5841
void create_select_for_variable(const char *var_name)
5845
LEX_STRING tmp, null_lex_string;
5847
char buff[MAX_SYS_VAR_LENGTH*2+4+8], *end;
5848
DBUG_ENTER("create_select_for_variable");
5852
mysql_init_select(lex);
5853
lex->sql_command= SQLCOM_SELECT;
5854
tmp.str= (char*) var_name;
5855
tmp.length=strlen(var_name);
5856
bzero((char*) &null_lex_string.str, sizeof(null_lex_string));
5858
We set the name of Item to @@session.var_name because that then is used
5859
as the column name in the output.
5861
if ((var= get_system_var(thd, OPT_SESSION, tmp, null_lex_string)))
5863
end= strxmov(buff, "@@session.", var_name, NullS);
5864
var->set_name(buff, end-buff, system_charset_info);
5865
add_item_to_list(thd, var);
5871
void mysql_init_multi_delete(LEX *lex)
5873
lex->sql_command= SQLCOM_DELETE_MULTI;
5874
mysql_init_select(lex);
5875
lex->select_lex.select_limit= 0;
5876
lex->unit.select_limit_cnt= HA_POS_ERROR;
5877
lex->select_lex.table_list.save_and_clear(&lex->auxiliary_table_list);
5878
lex->lock_option= TL_READ_DEFAULT;
5879
lex->query_tables= 0;
5880
lex->query_tables_last= &lex->query_tables;
5885
When you modify mysql_parse(), you may need to mofify
5886
mysql_test_parse_for_slave() in this same file.
5892
@param thd Current thread
5893
@param inBuf Begining of the query text
5894
@param length Length of the query text
5895
@param[out] found_semicolon For multi queries, position of the character of
5896
the next query in the query text.
5899
void mysql_parse(THD *thd, const char *inBuf, uint length,
5900
const char ** found_semicolon)
5902
DBUG_ENTER("mysql_parse");
5904
DBUG_EXECUTE_IF("parser_debug", turn_parser_debug_on(););
5908
The purpose of query_cache_send_result_to_client() is to lookup the
5909
query in the query cache first, to avoid parsing and executing it.
5910
So, the natural implementation would be to:
5911
- first, call query_cache_send_result_to_client,
5912
- second, if caching failed, initialise the lexical and syntactic parser.
5913
The problem is that the query cache depends on a clean initialization
5914
of (among others) lex->safe_to_cache_query and thd->server_status,
5915
which are reset respectively in
5917
- mysql_reset_thd_for_next_command()
5918
So, initializing the lexical analyser *before* using the query cache
5919
is required for the cache to work properly.
5920
FIXME: cleanup the dependencies in the code to simplify this.
5923
mysql_reset_thd_for_next_command(thd);
5925
if (query_cache_send_result_to_client(thd, (char*) inBuf, length) <= 0)
5929
sp_cache_flush_obsolete(&thd->sp_proc_cache);
5930
sp_cache_flush_obsolete(&thd->sp_func_cache);
5932
Parser_state parser_state(thd, inBuf, length);
5934
bool err= parse_sql(thd, & parser_state, NULL);
5935
*found_semicolon= parser_state.m_lip.found_semicolon;
5939
#ifndef NO_EMBEDDED_ACCESS_CHECKS
5940
if (mqh_used && thd->user_connect &&
5941
check_mqh(thd, lex->sql_command))
5948
if (! thd->is_error())
5951
Binlog logs a string starting from thd->query and having length
5952
thd->query_length; so we set thd->query_length correctly (to not
5953
log several statements in one event, when we executed only first).
5954
We set it to not see the ';' (otherwise it would get into binlog
5955
and Query_log_event::print() would give ';;' output).
5956
This also helps display only the current query in SHOW
5958
Note that we don't need LOCK_thread_count to modify query_length.
5960
if (*found_semicolon && (ulong) (*found_semicolon - thd->query()))
5961
thd->set_query_inner(thd->query(),
5962
(uint32) (*found_semicolon -
5964
/* Actually execute the query */
5965
if (*found_semicolon)
5967
lex->safe_to_cache_query= 0;
5968
thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
5970
lex->set_trg_event_type_for_tables();
5971
mysql_execute_command(thd);
5977
DBUG_ASSERT(thd->is_error());
5978
DBUG_PRINT("info",("Command aborted. Fatal_error: %d",
5979
thd->is_fatal_error));
5981
query_cache_abort(&thd->net);
5983
if (thd->lex->sphead)
5985
delete thd->lex->sphead;
5986
thd->lex->sphead= 0;
5988
lex->unit.cleanup();
5989
thd_proc_info(thd, "freeing items");
5990
thd->end_statement();
5991
thd->cleanup_after_query();
5992
DBUG_ASSERT(thd->change_list.is_empty());
5996
/* There are no multi queries in the cache. */
5997
*found_semicolon= NULL;
6004
#ifdef HAVE_REPLICATION
6006
Usable by the replication SQL thread only: just parse a query to know if it
6007
can be ignored because of replicate-*-table rules.
6015
bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length)
6019
DBUG_ENTER("mysql_test_parse_for_slave");
6021
Parser_state parser_state(thd, inBuf, length);
6023
mysql_reset_thd_for_next_command(thd);
6025
if (!parse_sql(thd, & parser_state, NULL) &&
6026
all_tables_not_ok(thd,(TABLE_LIST*) lex->select_lex.table_list.first))
6027
error= 1; /* Ignore question */
6028
thd->end_statement();
6029
thd->cleanup_after_query();
6037
Store field definition for create.
6043
bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type,
6044
char *length, char *decimals,
6046
Item *default_value, Item *on_update_value,
6047
LEX_STRING *comment,
6049
List<String> *interval_list, CHARSET_INFO *cs,
6050
uint uint_geom_type)
6052
register Create_field *new_field;
6054
DBUG_ENTER("add_field_to_list");
6056
if (check_string_char_length(field_name, "", NAME_CHAR_LEN,
6057
system_charset_info, 1))
6059
my_error(ER_TOO_LONG_IDENT, MYF(0), field_name->str); /* purecov: inspected */
6060
DBUG_RETURN(1); /* purecov: inspected */
6062
if (type_modifier & PRI_KEY_FLAG)
6065
lex->col_list.push_back(new Key_part_spec(field_name->str, 0));
6066
key= new Key(Key::PRIMARY, NullS,
6067
&default_key_create_info,
6069
lex->alter_info.key_list.push_back(key);
6070
lex->col_list.empty();
6072
if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG))
6075
lex->col_list.push_back(new Key_part_spec(field_name->str, 0));
6076
key= new Key(Key::UNIQUE, NullS,
6077
&default_key_create_info, 0,
6079
lex->alter_info.key_list.push_back(key);
6080
lex->col_list.empty();
6086
Default value should be literal => basic constants =>
6087
no need fix_fields()
6089
We allow only one function as part of default value -
6090
NOW() as default for TIMESTAMP type.
6092
if (default_value->type() == Item::FUNC_ITEM &&
6093
!(((Item_func*)default_value)->functype() == Item_func::NOW_FUNC &&
6094
type == MYSQL_TYPE_TIMESTAMP))
6096
my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
6099
else if (default_value->type() == Item::NULL_ITEM)
6102
if ((type_modifier & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) ==
6105
my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
6109
else if (type_modifier & AUTO_INCREMENT_FLAG)
6111
my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
6116
if (on_update_value && type != MYSQL_TYPE_TIMESTAMP)
6118
my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name->str);
6122
if (type == MYSQL_TYPE_TIMESTAMP && length)
6124
/* Display widths are no longer supported for TIMSTAMP as of MySQL 4.1.
6125
In other words, for declarations such as TIMESTAMP(2), TIMESTAMP(4),
6126
and so on, the display width is ignored.
6129
my_snprintf(buf, sizeof(buf), "TIMESTAMP(%s)", length);
6130
WARN_DEPRECATED(thd, "6.0", buf, "'TIMESTAMP'");
6133
if (!(new_field= new Create_field()) ||
6134
new_field->init(thd, field_name->str, type, length, decimals, type_modifier,
6135
default_value, on_update_value, comment, change,
6136
interval_list, cs, uint_geom_type))
6139
lex->alter_info.create_list.push_back(new_field);
6140
lex->last_field=new_field;
6145
/** Store position for column in ALTER TABLE .. ADD column. */
6147
void store_position_for_column(const char *name)
6149
current_thd->lex->last_field->after=my_const_cast(char*) (name);
6153
add_proc_to_list(THD* thd, Item *item)
6158
if (!(order = (ORDER *) thd->alloc(sizeof(ORDER)+sizeof(Item*))))
6160
item_ptr = (Item**) (order+1);
6162
order->item=item_ptr;
6164
thd->lex->proc_list.link_in_list((uchar*) order,(uchar**) &order->next);
6170
save order by and tables in own lists.
6173
bool add_to_list(THD *thd, SQL_LIST &list,Item *item,bool asc)
6176
DBUG_ENTER("add_to_list");
6177
if (!(order = (ORDER *) thd->alloc(sizeof(ORDER))))
6179
order->item_ptr= item;
6180
order->item= &order->item_ptr;
6184
order->counter_used= 0;
6185
list.link_in_list((uchar*) order,(uchar**) &order->next);
6191
Add a table to list of used tables.
6193
@param table Table to add
6194
@param alias alias for table (or null if no alias)
6195
@param table_options A set of the following bits:
6196
- TL_OPTION_UPDATING : Table will be updated
6197
- TL_OPTION_FORCE_INDEX : Force usage of index
6198
- TL_OPTION_ALIAS : an alias in multi table DELETE
6199
@param lock_type How table should be locked
6200
@param use_index List of indexed used in USE INDEX
6201
@param ignore_index List of indexed used in IGNORE INDEX
6206
\# Pointer to TABLE_LIST element added to the total table list
6209
TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
6212
ulong table_options,
6213
thr_lock_type lock_type,
6214
List<Index_hint> *index_hints_arg,
6217
register TABLE_LIST *ptr;
6218
TABLE_LIST *previous_table_ref; /* The table preceding the current one. */
6221
DBUG_ENTER("add_table_to_list");
6222
LINT_INIT(previous_table_ref);
6225
DBUG_RETURN(0); // End of memory
6226
alias_str= alias ? alias->str : table->table.str;
6227
if (!test(table_options & TL_OPTION_ALIAS) &&
6228
check_table_name(table->table.str, table->table.length))
6230
my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
6234
if (table->is_derived_table() == FALSE && table->db.str &&
6235
check_db_name(&table->db))
6237
my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str);
6241
if (!alias) /* Alias is case sensitive */
6245
my_message(ER_DERIVED_MUST_HAVE_ALIAS,
6246
ER(ER_DERIVED_MUST_HAVE_ALIAS), MYF(0));
6249
if (!(alias_str= (char*) thd->memdup(alias_str,table->table.length+1)))
6252
if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
6253
DBUG_RETURN(0); /* purecov: inspected */
6256
ptr->db= table->db.str;
6257
ptr->db_length= table->db.length;
6259
else if (lex->copy_db_to(&ptr->db, &ptr->db_length))
6262
ptr->alias= alias_str;
6263
if (lower_case_table_names && table->table.length)
6264
table->table.length= my_casedn_str(files_charset_info, table->table.str);
6265
ptr->table_name=table->table.str;
6266
ptr->table_name_length=table->table.length;
6267
ptr->lock_type= lock_type;
6268
ptr->updating= test(table_options & TL_OPTION_UPDATING);
6269
/* TODO: remove TL_OPTION_FORCE_INDEX as it looks like it's not used */
6270
ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX);
6271
ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES);
6272
ptr->derived= table->sel;
6273
if (!ptr->derived && is_schema_db(ptr->db, ptr->db_length))
6275
ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, ptr->table_name);
6276
if (!schema_table ||
6277
(schema_table->hidden &&
6278
((sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0 ||
6280
this check is used for show columns|keys from I_S hidden table
6282
lex->sql_command == SQLCOM_SHOW_FIELDS ||
6283
lex->sql_command == SQLCOM_SHOW_KEYS)))
6285
my_error(ER_UNKNOWN_TABLE, MYF(0),
6286
ptr->table_name, INFORMATION_SCHEMA_NAME.str);
6289
ptr->schema_table_name= ptr->table_name;
6290
ptr->schema_table= schema_table;
6292
ptr->select_lex= lex->current_select;
6293
ptr->cacheable_table= 1;
6294
ptr->index_hints= index_hints_arg;
6295
ptr->option= option ? option->str : 0;
6296
/* check that used name is unique */
6297
if (lock_type != TL_IGNORE)
6299
TABLE_LIST *first_table= (TABLE_LIST*) table_list.first;
6300
if (lex->sql_command == SQLCOM_CREATE_VIEW)
6301
first_table= first_table ? first_table->next_local : NULL;
6302
for (TABLE_LIST *tables= first_table ;
6304
tables=tables->next_local)
6306
if (!my_strcasecmp(table_alias_charset, alias_str, tables->alias) &&
6307
!strcmp(ptr->db, tables->db))
6309
my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str); /* purecov: tested */
6310
DBUG_RETURN(0); /* purecov: tested */
6314
/* Store the table reference preceding the current one. */
6315
if (table_list.elements > 0)
6318
table_list.next points to the last inserted TABLE_LIST->next_local'
6320
We don't use the offsetof() macro here to avoid warnings from gcc
6322
previous_table_ref= (TABLE_LIST*) ((char*) table_list.next -
6323
((char*) &(ptr->next_local) -
6326
Set next_name_resolution_table of the previous table reference to point
6327
to the current table reference. In effect the list
6328
TABLE_LIST::next_name_resolution_table coincides with
6329
TABLE_LIST::next_local. Later this may be changed in
6330
store_top_level_join_columns() for NATURAL/USING joins.
6332
previous_table_ref->next_name_resolution_table= ptr;
6336
Link the current table reference in a local list (list for current select).
6337
Notice that as a side effect here we set the next_local field of the
6338
previous table reference to 'ptr'. Here we also add one element to the
6341
table_list.link_in_list((uchar*) ptr, (uchar**) &ptr->next_local);
6342
ptr->next_name_resolution_table= NULL;
6343
/* Link table in global list (all used tables) */
6344
lex->add_to_query_tables(ptr);
6350
Initialize a new table list for a nested join.
6352
The function initializes a structure of the TABLE_LIST type
6353
for a nested join. It sets up its nested join list as empty.
6354
The created structure is added to the front of the current
6355
join list in the st_select_lex object. Then the function
6356
changes the current nest level for joins to refer to the newly
6357
created empty list after having saved the info on the old level
6358
in the initialized structure.
6360
@param thd current thread
6368
bool st_select_lex::init_nested_join(THD *thd)
6371
NESTED_JOIN *nested_join;
6372
DBUG_ENTER("init_nested_join");
6374
if (!(ptr= (TABLE_LIST*) thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST))+
6375
sizeof(NESTED_JOIN))))
6377
nested_join= ptr->nested_join=
6378
((NESTED_JOIN*) ((uchar*) ptr + ALIGN_SIZE(sizeof(TABLE_LIST))));
6380
join_list->push_front(ptr);
6381
ptr->embedding= embedding;
6382
ptr->join_list= join_list;
6383
ptr->alias= (char*) "(nested_join)";
6385
join_list= &nested_join->join_list;
6392
End a nested join table list.
6394
The function returns to the previous join nest level.
6395
If the current level contains only one member, the function
6396
moves it one level up, eliminating the nest.
6398
@param thd current thread
6401
- Pointer to TABLE_LIST element added to the total table list, if success
6405
TABLE_LIST *st_select_lex::end_nested_join(THD *thd)
6408
NESTED_JOIN *nested_join;
6409
DBUG_ENTER("end_nested_join");
6411
DBUG_ASSERT(embedding);
6413
join_list= ptr->join_list;
6414
embedding= ptr->embedding;
6415
nested_join= ptr->nested_join;
6416
if (nested_join->join_list.elements == 1)
6418
TABLE_LIST *embedded= nested_join->join_list.head();
6420
embedded->join_list= join_list;
6421
embedded->embedding= embedding;
6422
join_list->push_front(embedded);
6425
else if (nested_join->join_list.elements == 0)
6428
ptr= 0; // return value
6435
Nest last join operation.
6437
The function nest last join operation as if it was enclosed in braces.
6439
@param thd current thread
6444
\# Pointer to TABLE_LIST element created for the new nested join
6447
TABLE_LIST *st_select_lex::nest_last_join(THD *thd)
6450
NESTED_JOIN *nested_join;
6451
List<TABLE_LIST> *embedded_list;
6452
DBUG_ENTER("nest_last_join");
6454
if (!(ptr= (TABLE_LIST*) thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST))+
6455
sizeof(NESTED_JOIN))))
6457
nested_join= ptr->nested_join=
6458
((NESTED_JOIN*) ((uchar*) ptr + ALIGN_SIZE(sizeof(TABLE_LIST))));
6460
ptr->embedding= embedding;
6461
ptr->join_list= join_list;
6462
ptr->alias= (char*) "(nest_last_join)";
6463
embedded_list= &nested_join->join_list;
6464
embedded_list->empty();
6466
for (uint i=0; i < 2; i++)
6468
TABLE_LIST *table= join_list->pop();
6469
table->join_list= embedded_list;
6470
table->embedding= ptr;
6471
embedded_list->push_back(table);
6472
if (table->natural_join)
6474
ptr->is_natural_join= TRUE;
6476
If this is a JOIN ... USING, move the list of joined fields to the
6477
table reference that describes the join.
6479
if (prev_join_using)
6480
ptr->join_using_fields= prev_join_using;
6483
join_list->push_front(ptr);
6484
nested_join->used_tables= nested_join->not_null_tables= (table_map) 0;
6490
Add a table to the current join list.
6492
The function puts a table in front of the current join list
6493
of st_select_lex object.
6494
Thus, joined tables are put into this list in the reverse order
6495
(the most outer join operation follows first).
6497
@param table the table to add
6503
void st_select_lex::add_joined_table(TABLE_LIST *table)
6505
DBUG_ENTER("add_joined_table");
6506
join_list->push_front(table);
6507
table->join_list= join_list;
6508
table->embedding= embedding;
6514
Convert a right join into equivalent left join.
6516
The function takes the current join list t[0],t[1] ... and
6517
effectively converts it into the list t[1],t[0] ...
6518
Although the outer_join flag for the new nested table contains
6519
JOIN_TYPE_RIGHT, it will be handled as the inner table of a left join
6524
SELECT * FROM t1 RIGHT JOIN t2 ON on_expr =>
6525
SELECT * FROM t2 LEFT JOIN t1 ON on_expr
6527
SELECT * FROM t1,t2 RIGHT JOIN t3 ON on_expr =>
6528
SELECT * FROM t1,t3 LEFT JOIN t2 ON on_expr
6530
SELECT * FROM t1,t2 RIGHT JOIN (t3,t4) ON on_expr =>
6531
SELECT * FROM t1,(t3,t4) LEFT JOIN t2 ON on_expr
6533
SELECT * FROM t1 LEFT JOIN t2 ON on_expr1 RIGHT JOIN t3 ON on_expr2 =>
6534
SELECT * FROM t3 LEFT JOIN (t1 LEFT JOIN t2 ON on_expr2) ON on_expr1
6537
@param thd current thread
6540
- Pointer to the table representing the inner table, if success
6544
TABLE_LIST *st_select_lex::convert_right_join()
6546
TABLE_LIST *tab2= join_list->pop();
6547
TABLE_LIST *tab1= join_list->pop();
6548
DBUG_ENTER("convert_right_join");
6550
join_list->push_front(tab2);
6551
join_list->push_front(tab1);
6552
tab1->outer_join|= JOIN_TYPE_RIGHT;
6558
Set lock for all tables in current select level.
6560
@param lock_type Lock to set for tables
6563
If lock is a write lock, then tables->updating is set 1
6564
This is to get tables_ok to know that the table is updated by the
6568
void st_select_lex::set_lock_for_tables(thr_lock_type lock_type)
6570
bool for_update= lock_type >= TL_READ_NO_INSERT;
6571
DBUG_ENTER("set_lock_for_tables");
6572
DBUG_PRINT("enter", ("lock_type: %d for_update: %d", lock_type,
6574
for (TABLE_LIST *tables= (TABLE_LIST*) table_list.first;
6576
tables= tables->next_local)
6578
tables->lock_type= lock_type;
6579
tables->updating= for_update;
6586
Create a fake SELECT_LEX for a unit.
6588
The method create a fake SELECT_LEX object for a unit.
6589
This object is created for any union construct containing a union
6590
operation and also for any single select union construct of the form
6592
(SELECT ... ORDER BY order_list [LIMIT n]) ORDER BY ...
6596
(SELECT ... ORDER BY LIMIT n) ORDER BY ...
6599
@param thd_arg thread handle
6602
The object is used to retrieve rows from the temporary table
6603
where the result on the union is obtained.
6606
1 on failure to create the object
6611
bool st_select_lex_unit::add_fake_select_lex(THD *thd_arg)
6613
SELECT_LEX *first_sl= first_select();
6614
DBUG_ENTER("add_fake_select_lex");
6615
DBUG_ASSERT(!fake_select_lex);
6617
if (!(fake_select_lex= new (thd_arg->mem_root) SELECT_LEX()))
6619
fake_select_lex->include_standalone(this,
6620
(SELECT_LEX_NODE**)&fake_select_lex);
6621
fake_select_lex->select_number= INT_MAX;
6622
fake_select_lex->parent_lex= thd_arg->lex; /* Used in init_query. */
6623
fake_select_lex->make_empty_select();
6624
fake_select_lex->linkage= GLOBAL_OPTIONS_TYPE;
6625
fake_select_lex->select_limit= 0;
6627
fake_select_lex->context.outer_context=first_sl->context.outer_context;
6628
/* allow item list resolving in fake select for ORDER BY */
6629
fake_select_lex->context.resolve_in_select_list= TRUE;
6630
fake_select_lex->context.select_lex= fake_select_lex;
6636
(SELECT ... ORDER BY list [LIMIT n]) ORDER BY order_list [LIMIT m],
6637
(SELECT ... LIMIT n) ORDER BY order_list [LIMIT m]
6638
just before the parser starts processing order_list
6640
global_parameters= fake_select_lex;
6641
fake_select_lex->no_table_names_allowed= 1;
6642
thd_arg->lex->current_select= fake_select_lex;
6644
thd_arg->lex->pop_context();
6650
Push a new name resolution context for a JOIN ... ON clause to the
6651
context stack of a query block.
6653
Create a new name resolution context for a JOIN ... ON clause,
6654
set the first and last leaves of the list of table references
6655
to be used for name resolution, and push the newly created
6656
context to the stack of contexts of the query.
6658
@param thd pointer to current thread
6659
@param left_op left operand of the JOIN
6660
@param right_op rigth operand of the JOIN
6665
TRUE if a memory allocation error occured
6669
push_new_name_resolution_context(THD *thd,
6670
TABLE_LIST *left_op, TABLE_LIST *right_op)
6672
Name_resolution_context *on_context;
6673
if (!(on_context= new (thd->mem_root) Name_resolution_context))
6676
on_context->first_name_resolution_table=
6677
left_op->first_leaf_for_name_resolution();
6678
on_context->last_name_resolution_table=
6679
right_op->last_leaf_for_name_resolution();
6680
return thd->lex->push_context(on_context);
6685
Add an ON condition to the second operand of a JOIN ... ON.
6687
Add an ON condition to the right operand of a JOIN ... ON clause.
6689
@param b the second operand of a JOIN ... ON
6690
@param expr the condition to be added to the ON clause
6693
FALSE if there was some error
6698
void add_join_on(TABLE_LIST *b, Item *expr)
6707
If called from the parser, this happens if you have both a
6708
right and left join. If called later, it happens if we add more
6709
than one condition to the ON clause.
6711
b->on_expr= new Item_cond_and(b->on_expr,expr);
6713
b->on_expr->top_level_item();
6719
Mark that there is a NATURAL JOIN or JOIN ... USING between two
6722
This function marks that table b should be joined with a either via
6723
a NATURAL JOIN or via JOIN ... USING. Both join types are special
6724
cases of each other, so we treat them together. The function
6725
setup_conds() creates a list of equal condition between all fields
6726
of the same name for NATURAL JOIN or the fields in 'using_fields'
6727
for JOIN ... USING. The list of equality conditions is stored
6728
either in b->on_expr, or in JOIN::conds, depending on whether there
6733
SELECT * FROM t1 NATURAL LEFT JOIN t2
6735
SELECT * FROM t1 LEFT JOIN t2 ON (t1.i=t2.i and t1.j=t2.j ... )
6737
SELECT * FROM t1 NATURAL JOIN t2 WHERE <some_cond>
6739
SELECT * FROM t1, t2 WHERE (t1.i=t2.i and t1.j=t2.j and <some_cond>)
6741
SELECT * FROM t1 JOIN t2 USING(j) WHERE <some_cond>
6743
SELECT * FROM t1, t2 WHERE (t1.j=t2.j and <some_cond>)
6746
@param a Left join argument
6747
@param b Right join argument
6748
@param using_fields Field names from USING clause
6751
void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List<String> *using_fields,
6755
lex->prev_join_using= using_fields;
6760
Reload/resets privileges and the different caches.
6762
@param thd Thread handler (can be NULL!)
6763
@param options What should be reset/reloaded (tables, privileges, slave...)
6764
@param tables Tables to flush (if any)
6765
@param write_to_binlog True if we can write to the binlog.
6767
@note Depending on 'options', it may be very bad to write the
6768
query to the binlog (e.g. FLUSH SLAVE); this is a
6769
pointer where reload_acl_and_cache() will put 0 if
6770
it thinks we really should not write to the binlog.
6771
Otherwise it will put 1.
6773
@return Error status code
6775
@retval !=0 Error; thd->killed is set or thd->is_error() is true
6778
bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
6779
bool *write_to_binlog)
6782
select_errors=0; /* Write if more errors */
6783
bool tmp_write_to_binlog= 1;
6785
DBUG_ASSERT(!thd || !thd->in_sub_stmt);
6787
#ifndef NO_EMBEDDED_ACCESS_CHECKS
6788
if (options & REFRESH_GRANT)
6792
If reload_acl_and_cache() is called from SIGHUP handler we have to
6793
allocate temporary THD for execution of acl_reload()/grant_reload().
6795
if (!thd && (thd= (tmp_thd= new THD)))
6797
thd->thread_stack= (char*) &tmp_thd;
6798
thd->store_globals();
6804
bool reload_acl_failed= acl_reload(thd);
6805
bool reload_grants_failed= grant_reload(thd);
6806
bool reload_servers_failed= servers_reload(thd);
6808
if (reload_acl_failed || reload_grants_failed || reload_servers_failed)
6812
When an error is returned, my_message may have not been called and
6813
the client will hang waiting for a response.
6815
my_error(ER_UNKNOWN_ERROR, MYF(0), "FLUSH PRIVILEGES failed");
6822
/* Remember that we don't have a THD */
6823
my_pthread_setspecific_ptr(THR_THD, 0);
6826
reset_mqh((LEX_USER *)NULL, TRUE);
6829
if (options & REFRESH_LOG)
6832
Flush the normal query log, the update log, the binary log,
6833
the slow query log, the relay log (if it exists) and the log
6838
Writing this command to the binlog may result in infinite loops
6839
when doing mysqlbinlog|mysql, and anyway it does not really make
6840
sense to log it automatically (would cause more trouble to users
6841
than it would help them)
6843
tmp_write_to_binlog= 0;
6844
if( mysql_bin_log.is_open() )
6846
mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE);
6848
#ifdef HAVE_REPLICATION
6849
pthread_mutex_lock(&LOCK_active_mi);
6850
rotate_relay_log(active_mi);
6851
pthread_mutex_unlock(&LOCK_active_mi);
6854
/* flush slow and general logs */
6855
logger.flush_logs(thd);
6857
if (ha_flush_logs(NULL))
6859
if (flush_error_log())
6862
#ifdef HAVE_QUERY_CACHE
6863
if (options & REFRESH_QUERY_CACHE_FREE)
6865
query_cache.pack(); // FLUSH QUERY CACHE
6866
options &= ~REFRESH_QUERY_CACHE; // Don't flush cache, just free memory
6868
if (options & (REFRESH_TABLES | REFRESH_QUERY_CACHE))
6870
query_cache.flush(); // RESET QUERY CACHE
6872
#endif /*HAVE_QUERY_CACHE*/
6874
Note that if REFRESH_READ_LOCK bit is set then REFRESH_TABLES is set too
6877
if (options & (REFRESH_TABLES | REFRESH_READ_LOCK))
6879
if ((options & REFRESH_READ_LOCK) && thd)
6882
We must not try to aspire a global read lock if we have a write
6883
locked table. This would lead to a deadlock when trying to
6884
reopen (and re-lock) the table after the flush.
6886
if (thd->locked_tables)
6888
THR_LOCK_DATA **lock_p= thd->locked_tables->locks;
6889
THR_LOCK_DATA **end_p= lock_p + thd->locked_tables->lock_count;
6891
for (; lock_p < end_p; lock_p++)
6893
if ((*lock_p)->type >= TL_WRITE_ALLOW_WRITE)
6895
my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
6901
Writing to the binlog could cause deadlocks, as we don't log
6904
tmp_write_to_binlog= 0;
6905
if (lock_global_read_lock(thd))
6907
if (close_cached_tables(thd, tables, FALSE, (options & REFRESH_FAST) ?
6908
FALSE : TRUE, TRUE))
6911
if (make_global_read_lock_block_commit(thd)) // Killed
6913
/* Don't leave things in a half-locked state */
6914
unlock_global_read_lock(thd);
6920
if (close_cached_tables(thd, tables, FALSE, (options & REFRESH_FAST) ?
6921
FALSE : TRUE, FALSE))
6926
if (options & REFRESH_HOSTS)
6927
hostname_cache_refresh();
6928
if (thd && (options & REFRESH_STATUS))
6929
refresh_status(thd);
6930
if (options & REFRESH_THREADS)
6931
flush_thread_cache();
6932
#ifdef HAVE_REPLICATION
6933
if (options & REFRESH_MASTER)
6936
tmp_write_to_binlog= 0;
6937
if (reset_master(thd))
6944
if (options & REFRESH_DES_KEY_FILE)
6946
if (des_key_file && load_des_key_file(des_key_file))
6950
#ifdef HAVE_REPLICATION
6951
if (options & REFRESH_SLAVE)
6953
tmp_write_to_binlog= 0;
6954
pthread_mutex_lock(&LOCK_active_mi);
6955
if (reset_slave(thd, active_mi))
6957
pthread_mutex_unlock(&LOCK_active_mi);
6960
if (options & REFRESH_USER_RESOURCES)
6961
reset_mqh((LEX_USER *) NULL, 0); /* purecov: inspected */
6962
*write_to_binlog= tmp_write_to_binlog;
6964
If the query was killed then this function must fail.
6966
return result || (thd ? thd->killed : 0);
6973
@param thd Thread class
6975
@param only_kill_query Should it kill the query or the connection
6978
This is written such that we have a short lock on LOCK_thread_count
6981
uint kill_one_thread(THD *thd, ulong id, bool only_kill_query)
6984
uint error=ER_NO_SUCH_THREAD;
6985
DBUG_ENTER("kill_one_thread");
6986
DBUG_PRINT("enter", ("id=%lu only_kill=%d", id, only_kill_query));
6987
VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
6988
I_List_iterator<THD> it(threads);
6991
if (tmp->command == COM_DAEMON)
6993
if (tmp->thread_id == id)
6995
pthread_mutex_lock(&tmp->LOCK_thd_data); // Lock from delete
6999
VOID(pthread_mutex_unlock(&LOCK_thread_count));
7004
If we're SUPER, we can KILL anything, including system-threads.
7007
KILLer: thd->security_ctx->user could in theory be NULL while
7008
we're still in "unauthenticated" state. This is a theoretical
7009
case (the code suggests this could happen, so we play it safe).
7011
KILLee: tmp->security_ctx->user will be NULL for system threads.
7012
We need to check so Jane Random User doesn't crash the server
7013
when trying to kill a) system threads or b) unauthenticated users'
7014
threads (Bug#43748).
7016
If user of both killer and killee are non-NULL, proceed with
7017
slayage if both are string-equal.
7020
if ((thd->security_ctx->master_access & SUPER_ACL) ||
7021
thd->security_ctx->user_matches(tmp->security_ctx))
7023
tmp->awake(only_kill_query ? THD::KILL_QUERY : THD::KILL_CONNECTION);
7027
error=ER_KILL_DENIED_ERROR;
7028
pthread_mutex_unlock(&tmp->LOCK_thd_data);
7030
DBUG_PRINT("exit", ("%d", error));
7036
kills a thread and sends response
7042
only_kill_query Should it kill the query or the connection
7045
void sql_kill(THD *thd, ulong id, bool only_kill_query)
7048
if (!(error= kill_one_thread(thd, id, only_kill_query)))
7051
my_error(error, MYF(0), id);
7055
/** If pointer is not a null pointer, append filename to it. */
7057
bool append_file_to_dir(THD *thd, const char **filename_ptr,
7058
const char *table_name)
7060
char buff[FN_REFLEN],*ptr, *end;
7062
return 0; // nothing to do
7064
/* Check that the filename is not too long and it's a hard path */
7065
if (strlen(*filename_ptr)+strlen(table_name) >= FN_REFLEN-1 ||
7066
!test_if_hard_path(*filename_ptr))
7068
my_error(ER_WRONG_TABLE_NAME, MYF(0), *filename_ptr);
7071
/* Fix is using unix filename format on dos */
7072
strmov(buff,*filename_ptr);
7073
end=convert_dirname(buff, *filename_ptr, NullS);
7074
if (!(ptr= (char*) thd->alloc((size_t) (end-buff) + strlen(table_name)+1)))
7075
return 1; // End of memory
7077
strxmov(ptr,buff,table_name,NullS);
7083
Check if the select is a simple select (not an union).
7088
1 error ; In this case the error messege is sent to the client
7091
bool check_simple_select()
7093
THD *thd= current_thd;
7095
if (lex->current_select != &lex->select_lex)
7098
Lex_input_stream *lip= & thd->m_parser_state->m_lip;
7099
strmake(command, lip->yylval->symbol.str,
7100
min(lip->yylval->symbol.length, sizeof(command)-1));
7101
my_error(ER_CANT_USE_OPTION_HERE, MYF(0), command);
7108
Comp_creator *comp_eq_creator(bool invert)
7110
return invert?(Comp_creator *)&ne_creator:(Comp_creator *)&eq_creator;
7114
Comp_creator *comp_ge_creator(bool invert)
7116
return invert?(Comp_creator *)<_creator:(Comp_creator *)&ge_creator;
7120
Comp_creator *comp_gt_creator(bool invert)
7122
return invert?(Comp_creator *)&le_creator:(Comp_creator *)>_creator;
7126
Comp_creator *comp_le_creator(bool invert)
7128
return invert?(Comp_creator *)>_creator:(Comp_creator *)&le_creator;
7132
Comp_creator *comp_lt_creator(bool invert)
7134
return invert?(Comp_creator *)&ge_creator:(Comp_creator *)<_creator;
7138
Comp_creator *comp_ne_creator(bool invert)
7140
return invert?(Comp_creator *)&eq_creator:(Comp_creator *)&ne_creator;
7145
Construct ALL/ANY/SOME subquery Item.
7147
@param left_expr pointer to left expression
7148
@param cmp compare function creator
7149
@param all true if we create ALL subquery
7150
@param select_lex pointer on parsed subquery structure
7153
constructed Item (or 0 if out of memory)
7155
Item * all_any_subquery_creator(Item *left_expr,
7156
chooser_compare_func_creator cmp,
7158
SELECT_LEX *select_lex)
7160
if ((cmp == &comp_eq_creator) && !all) // = ANY <=> IN
7161
return new Item_in_subselect(left_expr, select_lex);
7163
if ((cmp == &comp_ne_creator) && all) // <> ALL <=> NOT IN
7164
return new Item_func_not(new Item_in_subselect(left_expr, select_lex));
7166
Item_allany_subselect *it=
7167
new Item_allany_subselect(left_expr, cmp, select_lex, all);
7169
return it->upper_item= new Item_func_not_all(it); /* ALL */
7171
return it->upper_item= new Item_func_nop_all(it); /* ANY/SOME */
7176
Multi update query pre-check.
7178
@param thd Thread handler
7179
@param tables Global/local table list (have to be the same)
7187
bool multi_update_precheck(THD *thd, TABLE_LIST *tables)
7192
SELECT_LEX *select_lex= &lex->select_lex;
7193
DBUG_ENTER("multi_update_precheck");
7195
if (select_lex->item_list.elements != lex->value_list.elements)
7197
my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0));
7201
Ensure that we have UPDATE or SELECT privilege for each table
7202
The exact privilege is checked in mysql_multi_update()
7204
for (table= tables; table; table= table->next_local)
7207
table->grant.privilege= SELECT_ACL;
7208
else if ((check_access(thd, UPDATE_ACL, table->db,
7209
&table->grant.privilege, 0, 1,
7210
test(table->schema_table)) ||
7211
check_grant(thd, UPDATE_ACL, table, 0, 1, 1)) &&
7212
(check_access(thd, SELECT_ACL, table->db,
7213
&table->grant.privilege, 0, 0,
7214
test(table->schema_table)) ||
7215
check_grant(thd, SELECT_ACL, table, 0, 1, 0)))
7218
table->table_in_first_from_clause= 1;
7221
Is there tables of subqueries?
7223
if (&lex->select_lex != lex->all_selects_list)
7225
DBUG_PRINT("info",("Checking sub query list"));
7226
for (table= tables; table; table= table->next_global)
7228
if (!table->table_in_first_from_clause)
7230
if (check_access(thd, SELECT_ACL, table->db,
7231
&table->grant.privilege, 0, 0,
7232
test(table->schema_table)) ||
7233
check_grant(thd, SELECT_ACL, table, 0, 1, 0))
7239
if (select_lex->order_list.elements)
7241
else if (select_lex->select_limit)
7245
my_error(ER_WRONG_USAGE, MYF(0), "UPDATE", msg);
7252
Multi delete query pre-check.
7254
@param thd Thread handler
7255
@param tables Global/local table list
7263
bool multi_delete_precheck(THD *thd, TABLE_LIST *tables)
7265
SELECT_LEX *select_lex= &thd->lex->select_lex;
7266
TABLE_LIST *aux_tables=
7267
(TABLE_LIST *)thd->lex->auxiliary_table_list.first;
7268
TABLE_LIST **save_query_tables_own_last= thd->lex->query_tables_own_last;
7269
DBUG_ENTER("multi_delete_precheck");
7271
/* sql_yacc guarantees that tables and aux_tables are not zero */
7272
DBUG_ASSERT(aux_tables != 0);
7273
if (check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE))
7277
Since aux_tables list is not part of LEX::query_tables list we
7278
have to juggle with LEX::query_tables_own_last value to be able
7279
call check_table_access() safely.
7281
thd->lex->query_tables_own_last= 0;
7282
if (check_table_access(thd, DELETE_ACL, aux_tables, UINT_MAX, FALSE))
7284
thd->lex->query_tables_own_last= save_query_tables_own_last;
7287
thd->lex->query_tables_own_last= save_query_tables_own_last;
7289
if ((thd->options & OPTION_SAFE_UPDATES) && !select_lex->where)
7291
my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
7292
ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
7300
Link tables in auxilary table list of multi-delete with corresponding
7301
elements in main table list, and set proper locks for them.
7303
@param lex pointer to LEX representing multi-delete
7311
bool multi_delete_set_locks_and_link_aux_tables(LEX *lex)
7313
TABLE_LIST *tables= (TABLE_LIST*)lex->select_lex.table_list.first;
7314
TABLE_LIST *target_tbl;
7315
DBUG_ENTER("multi_delete_set_locks_and_link_aux_tables");
7317
lex->table_count= 0;
7319
for (target_tbl= (TABLE_LIST *)lex->auxiliary_table_list.first;
7320
target_tbl; target_tbl= target_tbl->next_local)
7323
/* All tables in aux_tables must be found in FROM PART */
7325
for (walk= tables; walk; walk= walk->next_local)
7327
if (!my_strcasecmp(table_alias_charset,
7328
target_tbl->alias, walk->alias) &&
7329
!strcmp(walk->db, target_tbl->db))
7334
my_error(ER_UNKNOWN_TABLE, MYF(0),
7335
target_tbl->table_name, "MULTI DELETE");
7340
target_tbl->table_name= walk->table_name;
7341
target_tbl->table_name_length= walk->table_name_length;
7343
walk->updating= target_tbl->updating;
7344
walk->lock_type= target_tbl->lock_type;
7345
target_tbl->correspondent_table= walk; // Remember corresponding table
7352
simple UPDATE query pre-check.
7354
@param thd Thread handler
7355
@param tables Global table list
7363
bool update_precheck(THD *thd, TABLE_LIST *tables)
7365
DBUG_ENTER("update_precheck");
7366
if (thd->lex->select_lex.item_list.elements != thd->lex->value_list.elements)
7368
my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0));
7371
DBUG_RETURN(check_one_table_access(thd, UPDATE_ACL, tables));
7376
simple DELETE query pre-check.
7378
@param thd Thread handler
7379
@param tables Global table list
7387
bool delete_precheck(THD *thd, TABLE_LIST *tables)
7389
DBUG_ENTER("delete_precheck");
7390
if (check_one_table_access(thd, DELETE_ACL, tables))
7392
/* Set privilege for the WHERE clause */
7393
tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege);
7399
simple INSERT query pre-check.
7401
@param thd Thread handler
7402
@param tables Global table list
7410
bool insert_precheck(THD *thd, TABLE_LIST *tables)
7413
DBUG_ENTER("insert_precheck");
7416
Check that we have modify privileges for the first table and
7417
select privileges for the rest
7419
ulong privilege= (INSERT_ACL |
7420
(lex->duplicates == DUP_REPLACE ? DELETE_ACL : 0) |
7421
(lex->value_list.elements ? UPDATE_ACL : 0));
7423
if (check_one_table_access(thd, privilege, tables))
7426
if (lex->update_list.elements != lex->value_list.elements)
7428
my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0));
7436
@brief Check privileges for SHOW CREATE TABLE statement.
7438
@param thd Thread context
7439
@param table Target table
7441
@retval TRUE Failure
7442
@retval FALSE Success
7445
static bool check_show_create_table_access(THD *thd, TABLE_LIST *table)
7447
return check_access(thd, SELECT_ACL | EXTRA_ACL, table->db,
7448
&table->grant.privilege, 0, 0,
7449
test(table->schema_table)) ||
7450
check_grant(thd, SELECT_ACL, table, 2, UINT_MAX, 0);
7455
CREATE TABLE query pre-check.
7457
@param thd Thread handler
7458
@param tables Global table list
7459
@param create_table Table which will be created
7467
bool create_table_precheck(THD *thd, TABLE_LIST *tables,
7468
TABLE_LIST *create_table)
7471
SELECT_LEX *select_lex= &lex->select_lex;
7473
bool error= TRUE; // Error message is given
7474
DBUG_ENTER("create_table_precheck");
7477
Require CREATE [TEMPORARY] privilege on new table; for
7478
CREATE TABLE ... SELECT, also require INSERT.
7481
want_priv= ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) ?
7482
CREATE_TMP_ACL : CREATE_ACL) |
7483
(select_lex->item_list.elements ? INSERT_ACL : 0);
7485
if (check_access(thd, want_priv, create_table->db,
7486
&create_table->grant.privilege, 0, 0,
7487
test(create_table->schema_table)) ||
7488
check_merge_table_access(thd, create_table->db,
7490
lex->create_info.merge_list.first))
7492
if (want_priv != CREATE_TMP_ACL &&
7493
check_grant(thd, want_priv, create_table, 0, 1, 0))
7496
if (select_lex->item_list.elements)
7498
/* Check permissions for used tables in CREATE TABLE ... SELECT */
7500
#ifdef NOT_NECESSARY_TO_CHECK_CREATE_TABLE_EXIST_WHEN_PREPARING_STATEMENT
7501
/* This code throws an ill error for CREATE TABLE t1 SELECT * FROM t1 */
7503
Only do the check for PS, because we on execute we have to check that
7504
against the opened tables to ensure we don't use a table that is part
7505
of the view (which can only be done after the table has been opened).
7507
if (thd->stmt_arena->is_stmt_prepare_or_first_sp_execute())
7510
For temporary tables we don't have to check if the created table exists
7512
if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) &&
7513
find_table_in_global_list(tables, create_table->db,
7514
create_table->table_name))
7521
if (tables && check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE))
7524
else if (lex->create_info.options & HA_LEX_CREATE_TABLE_LIKE)
7526
if (check_show_create_table_access(thd, tables))
7537
negate given expression.
7539
@param thd thread handler
7540
@param expr expression for negation
7546
Item *negate_expression(THD *thd, Item *expr)
7549
if (expr->type() == Item::FUNC_ITEM &&
7550
((Item_func *) expr)->functype() == Item_func::NOT_FUNC)
7552
/* it is NOT(NOT( ... )) */
7553
Item *arg= ((Item_func *) expr)->arguments()[0];
7554
enum_parsing_place place= thd->lex->current_select->parsing_place;
7555
if (arg->is_bool_func() || place == IN_WHERE || place == IN_HAVING)
7558
if it is not boolean function then we have to emulate value of
7559
not(not(a)), it will be a != 0
7561
return new Item_func_ne(arg, new Item_int((char*) "0", 0, 1));
7564
if ((negated= expr->neg_transformer(thd)) != 0)
7566
return new Item_func_not(expr);
7570
Set the specified definer to the default value, which is the
7571
current user in the thread.
7573
@param[in] thd thread handler
7574
@param[out] definer definer
7577
void get_default_definer(THD *thd, LEX_USER *definer)
7579
const Security_context *sctx= thd->security_ctx;
7581
definer->user.str= (char *) sctx->priv_user;
7582
definer->user.length= strlen(definer->user.str);
7584
definer->host.str= (char *) sctx->priv_host;
7585
definer->host.length= strlen(definer->host.str);
7587
definer->password.str= NULL;
7588
definer->password.length= 0;
7593
Create default definer for the specified THD.
7595
@param[in] thd thread handler
7598
- On success, return a valid pointer to the created and initialized
7599
LEX_USER, which contains definer information.
7600
- On error, return 0.
7603
LEX_USER *create_default_definer(THD *thd)
7607
if (! (definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER))))
7610
get_default_definer(thd, definer);
7617
Create definer with the given user and host names.
7619
@param[in] thd thread handler
7620
@param[in] user_name user name
7621
@param[in] host_name host name
7624
- On success, return a valid pointer to the created and initialized
7625
LEX_USER, which contains definer information.
7626
- On error, return 0.
7629
LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name)
7633
/* Create and initialize. */
7635
if (! (definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER))))
7638
definer->user= *user_name;
7639
definer->host= *host_name;
7640
definer->password.str= NULL;
7641
definer->password.length= 0;
7648
Retuns information about user or current user.
7650
@param[in] thd thread handler
7651
@param[in] user user
7654
- On success, return a valid pointer to initialized
7655
LEX_USER, which contains user information.
7656
- On error, return 0.
7659
LEX_USER *get_current_user(THD *thd, LEX_USER *user)
7661
if (!user->user.str) // current_user
7662
return create_default_definer(thd);
7669
Check that byte length of a string does not exceed some limit.
7671
@param str string to be checked
7672
@param err_msg error message to be displayed if the string is too long
7673
@param max_length max length
7676
FALSE the passed string is not longer than max_length
7678
TRUE the passed string is longer than max_length
7681
The function is not used in existing code but can be useful later?
7684
bool check_string_byte_length(LEX_STRING *str, const char *err_msg,
7685
uint max_byte_length)
7687
if (str->length <= max_byte_length)
7690
my_error(ER_WRONG_STRING_LENGTH, MYF(0), str->str, err_msg, max_byte_length);
7697
Check that char length of a string does not exceed some limit.
7700
check_string_char_length()
7701
str string to be checked
7702
err_msg error message to be displayed if the string is too long
7703
max_char_length max length in symbols
7707
FALSE the passed string is not longer than max_char_length
7708
TRUE the passed string is longer than max_char_length
7712
bool check_string_char_length(LEX_STRING *str, const char *err_msg,
7713
uint max_char_length, CHARSET_INFO *cs,
7716
int well_formed_error;
7717
uint res= cs->cset->well_formed_len(cs, str->str, str->str + str->length,
7718
max_char_length, &well_formed_error);
7720
if (!well_formed_error && str->length == res)
7724
my_error(ER_WRONG_STRING_LENGTH, MYF(0), str->str, err_msg, max_char_length);
7730
Check if path does not contain mysql data home directory
7732
test_if_data_home_dir()
7734
conv_home_dir converted data home directory
7735
home_dir_len converted data home directory length
7743
int test_if_data_home_dir(const char *dir)
7745
char path[FN_REFLEN];
7747
DBUG_ENTER("test_if_data_home_dir");
7752
(void) fn_format(path, dir, "", "",
7753
(MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
7754
dir_len= strlen(path);
7755
if (mysql_unpacked_real_data_home_len<= dir_len)
7757
if (dir_len > mysql_unpacked_real_data_home_len &&
7758
path[mysql_unpacked_real_data_home_len] != FN_LIBCHAR)
7761
if (lower_case_file_system)
7763
if (!my_strnncoll(default_charset_info, (const uchar*) path,
7764
mysql_unpacked_real_data_home_len,
7765
(const uchar*) mysql_unpacked_real_data_home,
7766
mysql_unpacked_real_data_home_len))
7769
else if (!memcmp(path, mysql_unpacked_real_data_home,
7770
mysql_unpacked_real_data_home_len))
7780
Check that host name string is valid.
7782
@param[in] str string to be checked
7784
@return Operation status
7785
@retval FALSE host name is ok
7786
@retval TRUE host name string is longer than max_length or
7790
bool check_host_name(LEX_STRING *str)
7792
const char *name= str->str;
7793
const char *end= str->str + str->length;
7794
if (check_string_byte_length(str, ER(ER_HOSTNAME), HOSTNAME_LENGTH))
7801
my_printf_error(ER_UNKNOWN_ERROR,
7802
"Malformed hostname (illegal symbol: '%c')", MYF(0),
7812
extern int MYSQLparse(void *thd); // from sql_yacc.cc
7816
This is a wrapper of MYSQLparse(). All the code should call parse_sql()
7817
instead of MYSQLparse().
7819
@param thd Thread context.
7820
@param parser_state Parser state.
7821
@param creation_ctx Object creation context.
7823
@return Error status.
7824
@retval FALSE on success.
7825
@retval TRUE on parsing error.
7828
bool parse_sql(THD *thd,
7829
Parser_state *parser_state,
7830
Object_creation_ctx *creation_ctx)
7832
DBUG_ASSERT(thd->m_parser_state == NULL);
7834
/* Backup creation context. */
7836
Object_creation_ctx *backup_ctx= NULL;
7839
backup_ctx= creation_ctx->set_n_backup(thd);
7841
/* Set parser state. */
7843
thd->m_parser_state= parser_state;
7845
/* Parse the query. */
7847
bool mysql_parse_status= MYSQLparse(thd) != 0;
7849
/* Check that if MYSQLparse() failed, thd->is_error() is set. */
7851
DBUG_ASSERT(!mysql_parse_status ||
7852
(mysql_parse_status && thd->is_error()));
7854
/* Reset parser state. */
7856
thd->m_parser_state= NULL;
7858
/* Restore creation context. */
7861
creation_ctx->restore_env(thd, backup_ctx);
7865
return mysql_parse_status || thd->is_fatal_error;
7869
@} (end of group Runtime_Environment)