1 /* Copyright (c) 2000, 2021, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23 #include "sql_parse.h"
24
25 #include "auth_common.h" // acl_authenticate
26 #include "binlog.h" // purge_master_logs
27 #include "debug_sync.h" // DEBUG_SYNC
28 #include "events.h" // Events
29 #include "item_timefunc.h" // Item_func_unix_timestamp
30 #include "log.h" // query_logger
31 #include "log_event.h" // slave_execute_deferred_events
32 #include "mysys_err.h" // EE_CAPACITY_EXCEEDED
33 #include "opt_explain.h" // mysql_explain_other
34 #include "opt_trace.h" // Opt_trace_start
35 #include "partition_info.h" // partition_info
36 #include "probes_mysql.h" // MYSQL_COMMAND_START
37 #include "rpl_filter.h" // rpl_filter
38 #include "rpl_master.h" // register_slave
39 #include "rpl_rli.h" // mysql_show_relaylog_events
40 #include "rpl_slave.h" // change_master_cmd
41 #include "sp.h" // sp_create_routine
42 #include "sp_cache.h" // sp_cache_enforce_limit
43 #include "sp_head.h" // sp_head
44 #include "sql_admin.h" // mysql_assign_to_keycache
45 #include "sql_analyse.h" // Query_result_analyse
46 #include "sql_audit.h" // MYSQL_AUDIT_NOTIFY_CONNECTION_CHANGE_USER
47 #include "sql_base.h" // find_temporary_table
48 #include "sql_binlog.h" // mysql_client_binlog_statement
49 #include "sql_cache.h" // query_cache
50 #include "sql_connect.h" // decrease_user_connections
51 #include "sql_db.h" // mysql_change_db
52 #include "sql_delete.h" // mysql_delete
53 #include "sql_do.h" // mysql_do
54 #include "sql_handler.h" // mysql_ha_rm_tables
55 #include "sql_help.h" // mysqld_help
56 #include "sql_insert.h" // Query_result_create
57 #include "sql_load.h" // mysql_load
58 #include "sql_prepare.h" // mysql_stmt_execute
59 #include "partition_info.h" // has_external_data_or_index_dir
60 #include "sql_reload.h" // reload_acl_and_cache
61 #include "sql_rename.h" // mysql_rename_tables
62 #include "sql_select.h" // handle_query
63 #include "sql_show.h" // find_schema_table
64 #include "sql_table.h" // mysql_create_table
65 #include "sql_tablespace.h" // mysql_alter_tablespace
66 #include "sql_test.h" // mysql_print_status
67 #include "sql_select.h" // handle_query
68 #include "sql_load.h" // mysql_load
69 #include "sql_servers.h" // create_servers, alter_servers,
70 // drop_servers, servers_reload
71 #include "sql_handler.h" // mysql_ha_open, mysql_ha_close,
72 // mysql_ha_read
73 #include "sql_binlog.h" // mysql_client_binlog_statement
74 #include "sql_do.h" // mysql_do
75 #include "sql_help.h" // mysqld_help
76 #include "rpl_constants.h" // Incident, INCIDENT_LOST_EVENTS
77 #include "log_event.h"
78 #include "rpl_slave.h"
79 #include "rpl_master.h"
80 #include "rpl_msr.h" /* Multisource replication */
81 #include "rpl_filter.h"
82 #include <m_ctype.h>
83 #include <myisam.h>
84 #include <my_dir.h>
85 #include <dur_prop.h>
86 #include "rpl_handler.h"
87
88 #include "sp_head.h"
89 #include "sp.h"
90 #include "sp_cache.h"
91 #include "events.h"
92 #include "sql_trigger.h" // mysql_create_or_drop_trigger
93 #include "transaction.h"
94 #include "xa.h"
95 #include "sql_audit.h"
96 #include "sql_prepare.h"
97 #include "debug_sync.h"
98 #include "probes_mysql.h"
99 #include "set_var.h"
100 #include "opt_trace.h"
101 #include "mysql/psi/mysql_statement.h"
102 #include "opt_explain.h"
103 #include "sql_rewrite.h"
104 #include "sql_analyse.h"
105 #include "table_cache.h" // table_cache_manager
106 #include "sql_timer.h" // thd_timer_set, thd_timer_reset
107 #include "sp_rcontext.h"
108 #include "parse_location.h"
109 #include "sql_digest.h"
110 #include "sql_timer.h" // thd_timer_set
111 #include "sql_trigger.h" // add_table_for_trigger
112 #include "sql_update.h" // mysql_update
113 #include "sql_view.h" // mysql_create_view
114 #include "table_cache.h" // table_cache_manager
115 #include "transaction.h" // trans_commit_implicit
116 #include "sql_query_rewrite.h"
117
118 #include "rpl_group_replication.h"
119 #include <algorithm>
120 using std::max;
121
122 /**
123 @defgroup Runtime_Environment Runtime Environment
124 @{
125 */
126
127 /* Used in error handling only */
128 #define SP_COM_STRING(LP) \
129 ((LP)->sql_command == SQLCOM_CREATE_SPFUNCTION || \
130 (LP)->sql_command == SQLCOM_ALTER_FUNCTION || \
131 (LP)->sql_command == SQLCOM_SHOW_CREATE_FUNC || \
132 (LP)->sql_command == SQLCOM_DROP_FUNCTION ? \
133 "FUNCTION" : "PROCEDURE")
134
135 static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables);
136 static void sql_kill(THD *thd, my_thread_id id, bool only_kill_query);
137
138 const LEX_STRING command_name[]={
139 { C_STRING_WITH_LEN("Sleep") },
140 { C_STRING_WITH_LEN("Quit") },
141 { C_STRING_WITH_LEN("Init DB") },
142 { C_STRING_WITH_LEN("Query") },
143 { C_STRING_WITH_LEN("Field List") },
144 { C_STRING_WITH_LEN("Create DB") },
145 { C_STRING_WITH_LEN("Drop DB") },
146 { C_STRING_WITH_LEN("Refresh") },
147 { C_STRING_WITH_LEN("Shutdown") },
148 { C_STRING_WITH_LEN("Statistics") },
149 { C_STRING_WITH_LEN("Processlist") },
150 { C_STRING_WITH_LEN("Connect") },
151 { C_STRING_WITH_LEN("Kill") },
152 { C_STRING_WITH_LEN("Debug") },
153 { C_STRING_WITH_LEN("Ping") },
154 { C_STRING_WITH_LEN("Time") },
155 { C_STRING_WITH_LEN("Delayed insert") },
156 { C_STRING_WITH_LEN("Change user") },
157 { C_STRING_WITH_LEN("Binlog Dump") },
158 { C_STRING_WITH_LEN("Table Dump") },
159 { C_STRING_WITH_LEN("Connect Out") },
160 { C_STRING_WITH_LEN("Register Slave") },
161 { C_STRING_WITH_LEN("Prepare") },
162 { C_STRING_WITH_LEN("Execute") },
163 { C_STRING_WITH_LEN("Long Data") },
164 { C_STRING_WITH_LEN("Close stmt") },
165 { C_STRING_WITH_LEN("Reset stmt") },
166 { C_STRING_WITH_LEN("Set option") },
167 { C_STRING_WITH_LEN("Fetch") },
168 { C_STRING_WITH_LEN("Daemon") },
169 { C_STRING_WITH_LEN("Binlog Dump GTID") },
170 { C_STRING_WITH_LEN("Reset Connection") },
171 { C_STRING_WITH_LEN("Error") } // Last command number
172 };
173
174 #ifdef HAVE_REPLICATION
175 /**
176 Returns true if all tables should be ignored.
177 */
all_tables_not_ok(THD * thd,TABLE_LIST * tables)178 bool all_tables_not_ok(THD *thd, TABLE_LIST *tables)
179 {
180 return rpl_filter->is_on() && tables && !thd->sp_runtime_ctx &&
181 !rpl_filter->tables_ok(thd->db().str, tables);
182 }
183
184 /**
185 Checks whether the event for the given database, db, should
186 be ignored or not. This is done by checking whether there are
187 active rules in ignore_db or in do_db containers. If there
188 are, then check if there is a match, if not then check the
189 wild_do rules.
190
191 NOTE: This means that when using this function replicate-do-db
192 and replicate-ignore-db take precedence over wild do
193 rules.
194
195 @param thd Thread handle.
196 @param db Database name used while evaluating the filtering
197 rules.
198 @param sql_cmd Represents the current query that needs to be
199 verified against the database filter rules.
200 @return TRUE Query should not be filtered out from the execution.
201 FALSE Query should be filtered out from the execution.
202
203 */
check_database_filters(THD * thd,const char * db,enum_sql_command sql_cmd)204 inline bool check_database_filters(THD *thd, const char* db, enum_sql_command sql_cmd)
205 {
206 DBUG_ENTER("check_database_filters");
207 assert(thd->slave_thread);
208 if (!db)
209 DBUG_RETURN(TRUE);
210 switch (sql_cmd)
211 {
212 case SQLCOM_BEGIN:
213 case SQLCOM_COMMIT:
214 case SQLCOM_SAVEPOINT:
215 case SQLCOM_ROLLBACK:
216 case SQLCOM_ROLLBACK_TO_SAVEPOINT:
217 DBUG_RETURN(TRUE);
218 default:
219 break;
220 }
221 bool db_ok= rpl_filter->db_ok(db);
222 /*
223 No filters exist in ignore/do_db ? Then, just check
224 wild_do_table filtering for 'DATABASE' related
225 statements (CREATE/DROP/ATLER DATABASE)
226 */
227 if (db_ok &&
228 (rpl_filter->get_do_db()->is_empty() &&
229 rpl_filter->get_ignore_db()->is_empty()))
230 {
231 switch (sql_cmd)
232 {
233 case SQLCOM_CREATE_DB:
234 case SQLCOM_ALTER_DB:
235 case SQLCOM_ALTER_DB_UPGRADE:
236 case SQLCOM_DROP_DB:
237 db_ok= rpl_filter->db_ok_with_wild_table(db);
238 default:
239 break;
240 }
241 }
242 DBUG_RETURN(db_ok);
243 }
244
245 #endif
246
247
some_non_temp_table_to_be_updated(THD * thd,TABLE_LIST * tables)248 bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables)
249 {
250 for (TABLE_LIST *table= tables; table; table= table->next_global)
251 {
252 assert(table->db && table->table_name);
253 /*
254 Update on performance_schema and temp tables are allowed
255 in readonly mode.
256 */
257 if (table->updating && !find_temporary_table(thd, table) &&
258 !is_perfschema_db(table->db, table->db_length))
259 return 1;
260 }
261 return 0;
262 }
263
264
265 /*
266 Implicitly commit a active transaction if statement requires so.
267
268 @param thd Thread handle.
269 @param mask Bitmask used for the SQL command match.
270
271 */
stmt_causes_implicit_commit(const THD * thd,uint mask)272 bool stmt_causes_implicit_commit(const THD *thd, uint mask)
273 {
274 const LEX *lex= thd->lex;
275 bool skip= FALSE;
276 DBUG_ENTER("stmt_causes_implicit_commit");
277
278 if (!(sql_command_flags[lex->sql_command] & mask))
279 DBUG_RETURN(FALSE);
280
281 switch (lex->sql_command) {
282 case SQLCOM_DROP_TABLE:
283 skip= lex->drop_temporary;
284 break;
285 case SQLCOM_ALTER_TABLE:
286 case SQLCOM_CREATE_TABLE:
287 /* If CREATE TABLE of non-temporary table, do implicit commit */
288 skip= (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE);
289 break;
290 case SQLCOM_SET_OPTION:
291 /* Implicitly commit a transaction started by a SET statement */
292 skip= lex->autocommit ? FALSE : TRUE;
293 break;
294 default:
295 break;
296 }
297
298 DBUG_RETURN(!skip);
299 }
300
301
302 /**
303 Mark all commands that somehow changes a table.
304
305 This is used to check number of updates / hour.
306
307 sql_command is actually set to SQLCOM_END sometimes
308 so we need the +1 to include it in the array.
309
310 See COMMAND_FLAG_xxx for different type of commands
311 2 - query that returns meaningful ROW_COUNT() -
312 a number of modified rows
313 */
314
315 uint sql_command_flags[SQLCOM_END+1];
316 uint server_command_flags[COM_END+1];
317
init_update_queries(void)318 void init_update_queries(void)
319 {
320 /* Initialize the server command flags array. */
321 memset(server_command_flags, 0, sizeof(server_command_flags));
322
323 server_command_flags[COM_SLEEP]= CF_ALLOW_PROTOCOL_PLUGIN;
324 server_command_flags[COM_INIT_DB]= CF_ALLOW_PROTOCOL_PLUGIN;
325 server_command_flags[COM_QUERY]= CF_ALLOW_PROTOCOL_PLUGIN;
326 server_command_flags[COM_FIELD_LIST]= CF_ALLOW_PROTOCOL_PLUGIN;
327 server_command_flags[COM_REFRESH]= CF_ALLOW_PROTOCOL_PLUGIN;
328 server_command_flags[COM_SHUTDOWN]= CF_ALLOW_PROTOCOL_PLUGIN;
329 server_command_flags[COM_STATISTICS]= CF_SKIP_QUESTIONS;
330 server_command_flags[COM_PROCESS_KILL]= CF_ALLOW_PROTOCOL_PLUGIN;
331 server_command_flags[COM_PING]= CF_SKIP_QUESTIONS;
332 server_command_flags[COM_STMT_PREPARE]= CF_SKIP_QUESTIONS |
333 CF_ALLOW_PROTOCOL_PLUGIN;
334 server_command_flags[COM_STMT_EXECUTE]= CF_ALLOW_PROTOCOL_PLUGIN;
335 server_command_flags[COM_STMT_SEND_LONG_DATA]= CF_ALLOW_PROTOCOL_PLUGIN;
336 server_command_flags[COM_STMT_CLOSE]= CF_SKIP_QUESTIONS |
337 CF_ALLOW_PROTOCOL_PLUGIN;
338 server_command_flags[COM_STMT_RESET]= CF_SKIP_QUESTIONS |
339 CF_ALLOW_PROTOCOL_PLUGIN;
340 server_command_flags[COM_STMT_FETCH]= CF_ALLOW_PROTOCOL_PLUGIN;
341 server_command_flags[COM_END]= CF_ALLOW_PROTOCOL_PLUGIN;
342
343 /* Initialize the sql command flags array. */
344 memset(sql_command_flags, 0, sizeof(sql_command_flags));
345
346 /*
347 In general, DDL statements do not generate row events and do not go
348 through a cache before being written to the binary log. However, the
349 CREATE TABLE...SELECT is an exception because it may generate row
350 events. For that reason, the SQLCOM_CREATE_TABLE which represents
351 a CREATE TABLE, including the CREATE TABLE...SELECT, has the
352 CF_CAN_GENERATE_ROW_EVENTS flag. The distinction between a regular
353 CREATE TABLE and the CREATE TABLE...SELECT is made in other parts of
354 the code, in particular in the Query_log_event's constructor.
355 */
356 sql_command_flags[SQLCOM_CREATE_TABLE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
357 CF_AUTO_COMMIT_TRANS |
358 CF_CAN_GENERATE_ROW_EVENTS;
359 sql_command_flags[SQLCOM_CREATE_INDEX]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
360 sql_command_flags[SQLCOM_ALTER_TABLE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND |
361 CF_AUTO_COMMIT_TRANS;
362 sql_command_flags[SQLCOM_TRUNCATE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND |
363 CF_AUTO_COMMIT_TRANS;
364 sql_command_flags[SQLCOM_DROP_TABLE]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
365 sql_command_flags[SQLCOM_LOAD]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
366 CF_CAN_GENERATE_ROW_EVENTS;
367 sql_command_flags[SQLCOM_CREATE_DB]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
368 sql_command_flags[SQLCOM_DROP_DB]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
369 sql_command_flags[SQLCOM_ALTER_DB_UPGRADE]= CF_AUTO_COMMIT_TRANS;
370 sql_command_flags[SQLCOM_ALTER_DB]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
371 sql_command_flags[SQLCOM_RENAME_TABLE]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
372 sql_command_flags[SQLCOM_DROP_INDEX]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
373 sql_command_flags[SQLCOM_CREATE_VIEW]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
374 CF_AUTO_COMMIT_TRANS;
375 sql_command_flags[SQLCOM_DROP_VIEW]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
376 sql_command_flags[SQLCOM_CREATE_TRIGGER]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
377 sql_command_flags[SQLCOM_DROP_TRIGGER]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
378 sql_command_flags[SQLCOM_CREATE_EVENT]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
379 sql_command_flags[SQLCOM_ALTER_EVENT]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
380 sql_command_flags[SQLCOM_DROP_EVENT]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
381
382 sql_command_flags[SQLCOM_UPDATE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
383 CF_CAN_GENERATE_ROW_EVENTS |
384 CF_OPTIMIZER_TRACE |
385 CF_CAN_BE_EXPLAINED;
386 sql_command_flags[SQLCOM_UPDATE_MULTI]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
387 CF_CAN_GENERATE_ROW_EVENTS |
388 CF_OPTIMIZER_TRACE |
389 CF_CAN_BE_EXPLAINED;
390 // This is INSERT VALUES(...), can be VALUES(stored_func()) so we trace it
391 sql_command_flags[SQLCOM_INSERT]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
392 CF_CAN_GENERATE_ROW_EVENTS |
393 CF_OPTIMIZER_TRACE |
394 CF_CAN_BE_EXPLAINED;
395 sql_command_flags[SQLCOM_INSERT_SELECT]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
396 CF_CAN_GENERATE_ROW_EVENTS |
397 CF_OPTIMIZER_TRACE |
398 CF_CAN_BE_EXPLAINED;
399 sql_command_flags[SQLCOM_DELETE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
400 CF_CAN_GENERATE_ROW_EVENTS |
401 CF_OPTIMIZER_TRACE |
402 CF_CAN_BE_EXPLAINED;
403 sql_command_flags[SQLCOM_DELETE_MULTI]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
404 CF_CAN_GENERATE_ROW_EVENTS |
405 CF_OPTIMIZER_TRACE |
406 CF_CAN_BE_EXPLAINED;
407 sql_command_flags[SQLCOM_REPLACE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
408 CF_CAN_GENERATE_ROW_EVENTS |
409 CF_OPTIMIZER_TRACE |
410 CF_CAN_BE_EXPLAINED;
411 sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
412 CF_CAN_GENERATE_ROW_EVENTS |
413 CF_OPTIMIZER_TRACE |
414 CF_CAN_BE_EXPLAINED;
415 sql_command_flags[SQLCOM_SELECT]= CF_REEXECUTION_FRAGILE |
416 CF_CAN_GENERATE_ROW_EVENTS |
417 CF_OPTIMIZER_TRACE |
418 CF_CAN_BE_EXPLAINED;
419 // (1) so that subquery is traced when doing "SET @var = (subquery)"
420 /*
421 @todo SQLCOM_SET_OPTION should have CF_CAN_GENERATE_ROW_EVENTS
422 set, because it may invoke a stored function that generates row
423 events. /Sven
424 */
425 sql_command_flags[SQLCOM_SET_OPTION]= CF_REEXECUTION_FRAGILE |
426 CF_AUTO_COMMIT_TRANS |
427 CF_CAN_GENERATE_ROW_EVENTS |
428 CF_OPTIMIZER_TRACE; // (1)
429 // (1) so that subquery is traced when doing "DO @var := (subquery)"
430 sql_command_flags[SQLCOM_DO]= CF_REEXECUTION_FRAGILE |
431 CF_CAN_GENERATE_ROW_EVENTS |
432 CF_OPTIMIZER_TRACE; // (1)
433
434 sql_command_flags[SQLCOM_SHOW_STATUS_PROC]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
435 sql_command_flags[SQLCOM_SHOW_STATUS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
436 sql_command_flags[SQLCOM_SHOW_DATABASES]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
437 sql_command_flags[SQLCOM_SHOW_TRIGGERS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
438 sql_command_flags[SQLCOM_SHOW_EVENTS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
439 sql_command_flags[SQLCOM_SHOW_OPEN_TABLES]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
440 sql_command_flags[SQLCOM_SHOW_PLUGINS]= CF_STATUS_COMMAND;
441 sql_command_flags[SQLCOM_SHOW_FIELDS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
442 sql_command_flags[SQLCOM_SHOW_KEYS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
443 sql_command_flags[SQLCOM_SHOW_VARIABLES]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
444 sql_command_flags[SQLCOM_SHOW_CHARSETS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
445 sql_command_flags[SQLCOM_SHOW_COLLATIONS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
446 sql_command_flags[SQLCOM_SHOW_BINLOGS]= CF_STATUS_COMMAND;
447 sql_command_flags[SQLCOM_SHOW_SLAVE_HOSTS]= CF_STATUS_COMMAND;
448 sql_command_flags[SQLCOM_SHOW_BINLOG_EVENTS]= CF_STATUS_COMMAND;
449 sql_command_flags[SQLCOM_SHOW_STORAGE_ENGINES]= CF_STATUS_COMMAND;
450 sql_command_flags[SQLCOM_SHOW_PRIVILEGES]= CF_STATUS_COMMAND;
451 sql_command_flags[SQLCOM_SHOW_WARNS]= CF_STATUS_COMMAND | CF_DIAGNOSTIC_STMT;
452 sql_command_flags[SQLCOM_SHOW_ERRORS]= CF_STATUS_COMMAND | CF_DIAGNOSTIC_STMT;
453 sql_command_flags[SQLCOM_SHOW_ENGINE_STATUS]= CF_STATUS_COMMAND;
454 sql_command_flags[SQLCOM_SHOW_ENGINE_MUTEX]= CF_STATUS_COMMAND;
455 sql_command_flags[SQLCOM_SHOW_ENGINE_LOGS]= CF_STATUS_COMMAND;
456 sql_command_flags[SQLCOM_SHOW_PROCESSLIST]= CF_STATUS_COMMAND;
457 sql_command_flags[SQLCOM_SHOW_GRANTS]= CF_STATUS_COMMAND;
458 sql_command_flags[SQLCOM_SHOW_CREATE_DB]= CF_STATUS_COMMAND;
459 sql_command_flags[SQLCOM_SHOW_CREATE]= CF_STATUS_COMMAND;
460 sql_command_flags[SQLCOM_SHOW_MASTER_STAT]= CF_STATUS_COMMAND;
461 sql_command_flags[SQLCOM_SHOW_SLAVE_STAT]= CF_STATUS_COMMAND;
462 sql_command_flags[SQLCOM_SHOW_CREATE_PROC]= CF_STATUS_COMMAND;
463 sql_command_flags[SQLCOM_SHOW_CREATE_FUNC]= CF_STATUS_COMMAND;
464 sql_command_flags[SQLCOM_SHOW_CREATE_TRIGGER]= CF_STATUS_COMMAND;
465 sql_command_flags[SQLCOM_SHOW_STATUS_FUNC]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
466 sql_command_flags[SQLCOM_SHOW_PROC_CODE]= CF_STATUS_COMMAND;
467 sql_command_flags[SQLCOM_SHOW_FUNC_CODE]= CF_STATUS_COMMAND;
468 sql_command_flags[SQLCOM_SHOW_CREATE_EVENT]= CF_STATUS_COMMAND;
469 sql_command_flags[SQLCOM_SHOW_PROFILES]= CF_STATUS_COMMAND;
470 sql_command_flags[SQLCOM_SHOW_PROFILE]= CF_STATUS_COMMAND;
471 sql_command_flags[SQLCOM_BINLOG_BASE64_EVENT]= CF_STATUS_COMMAND |
472 CF_CAN_GENERATE_ROW_EVENTS;
473
474 sql_command_flags[SQLCOM_SHOW_TABLES]= (CF_STATUS_COMMAND |
475 CF_SHOW_TABLE_COMMAND |
476 CF_REEXECUTION_FRAGILE);
477 sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]= (CF_STATUS_COMMAND |
478 CF_SHOW_TABLE_COMMAND |
479 CF_REEXECUTION_FRAGILE);
480
481 sql_command_flags[SQLCOM_CREATE_USER]= CF_CHANGES_DATA;
482 sql_command_flags[SQLCOM_RENAME_USER]= CF_CHANGES_DATA;
483 sql_command_flags[SQLCOM_DROP_USER]= CF_CHANGES_DATA;
484 sql_command_flags[SQLCOM_ALTER_USER]= CF_CHANGES_DATA;
485 sql_command_flags[SQLCOM_GRANT]= CF_CHANGES_DATA;
486 sql_command_flags[SQLCOM_REVOKE]= CF_CHANGES_DATA;
487 sql_command_flags[SQLCOM_REVOKE_ALL]= CF_CHANGES_DATA;
488 sql_command_flags[SQLCOM_OPTIMIZE]= CF_CHANGES_DATA;
489 sql_command_flags[SQLCOM_ALTER_INSTANCE]= CF_CHANGES_DATA;
490 sql_command_flags[SQLCOM_CREATE_FUNCTION]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
491 sql_command_flags[SQLCOM_CREATE_PROCEDURE]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
492 sql_command_flags[SQLCOM_CREATE_SPFUNCTION]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
493 sql_command_flags[SQLCOM_DROP_PROCEDURE]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
494 sql_command_flags[SQLCOM_DROP_FUNCTION]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
495 sql_command_flags[SQLCOM_ALTER_PROCEDURE]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
496 sql_command_flags[SQLCOM_ALTER_FUNCTION]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
497 sql_command_flags[SQLCOM_INSTALL_PLUGIN]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
498 sql_command_flags[SQLCOM_UNINSTALL_PLUGIN]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
499
500 /* Does not change the contents of the Diagnostics Area. */
501 sql_command_flags[SQLCOM_GET_DIAGNOSTICS]= CF_DIAGNOSTIC_STMT;
502
503 /*
504 (1): without it, in "CALL some_proc((subq))", subquery would not be
505 traced.
506 */
507 sql_command_flags[SQLCOM_CALL]= CF_REEXECUTION_FRAGILE |
508 CF_CAN_GENERATE_ROW_EVENTS |
509 CF_OPTIMIZER_TRACE; // (1)
510 sql_command_flags[SQLCOM_EXECUTE]= CF_CAN_GENERATE_ROW_EVENTS;
511
512 /*
513 The following admin table operations are allowed
514 on log tables.
515 */
516 sql_command_flags[SQLCOM_REPAIR]= CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS;
517 sql_command_flags[SQLCOM_OPTIMIZE]|= CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS;
518 sql_command_flags[SQLCOM_ANALYZE]= CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS;
519 sql_command_flags[SQLCOM_CHECK]= CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS;
520
521 sql_command_flags[SQLCOM_CREATE_USER]|= CF_AUTO_COMMIT_TRANS;
522 sql_command_flags[SQLCOM_DROP_USER]|= CF_AUTO_COMMIT_TRANS;
523 sql_command_flags[SQLCOM_RENAME_USER]|= CF_AUTO_COMMIT_TRANS;
524 sql_command_flags[SQLCOM_ALTER_USER]|= CF_AUTO_COMMIT_TRANS;
525 sql_command_flags[SQLCOM_REVOKE]|= CF_AUTO_COMMIT_TRANS;
526 sql_command_flags[SQLCOM_REVOKE_ALL]|= CF_AUTO_COMMIT_TRANS;
527 sql_command_flags[SQLCOM_GRANT]|= CF_AUTO_COMMIT_TRANS;
528
529 sql_command_flags[SQLCOM_ASSIGN_TO_KEYCACHE]= CF_AUTO_COMMIT_TRANS;
530 sql_command_flags[SQLCOM_PRELOAD_KEYS]= CF_AUTO_COMMIT_TRANS;
531 sql_command_flags[SQLCOM_ALTER_INSTANCE]|= CF_AUTO_COMMIT_TRANS;
532
533 sql_command_flags[SQLCOM_FLUSH]= CF_AUTO_COMMIT_TRANS;
534 sql_command_flags[SQLCOM_RESET]= CF_AUTO_COMMIT_TRANS;
535 sql_command_flags[SQLCOM_CREATE_SERVER]= CF_AUTO_COMMIT_TRANS;
536 sql_command_flags[SQLCOM_ALTER_SERVER]= CF_AUTO_COMMIT_TRANS;
537 sql_command_flags[SQLCOM_DROP_SERVER]= CF_AUTO_COMMIT_TRANS;
538 sql_command_flags[SQLCOM_CHANGE_MASTER]= CF_AUTO_COMMIT_TRANS;
539 sql_command_flags[SQLCOM_CHANGE_REPLICATION_FILTER]= CF_AUTO_COMMIT_TRANS;
540 sql_command_flags[SQLCOM_SLAVE_START]= CF_AUTO_COMMIT_TRANS;
541 sql_command_flags[SQLCOM_SLAVE_STOP]= CF_AUTO_COMMIT_TRANS;
542 sql_command_flags[SQLCOM_ALTER_TABLESPACE]|= CF_AUTO_COMMIT_TRANS;
543
544 /*
545 The following statements can deal with temporary tables,
546 so temporary tables should be pre-opened for those statements to
547 simplify privilege checking.
548
549 There are other statements that deal with temporary tables and open
550 them, but which are not listed here. The thing is that the order of
551 pre-opening temporary tables for those statements is somewhat custom.
552 */
553 sql_command_flags[SQLCOM_CREATE_TABLE]|= CF_PREOPEN_TMP_TABLES;
554 sql_command_flags[SQLCOM_DROP_TABLE]|= CF_PREOPEN_TMP_TABLES;
555 sql_command_flags[SQLCOM_CREATE_INDEX]|= CF_PREOPEN_TMP_TABLES;
556 sql_command_flags[SQLCOM_ALTER_TABLE]|= CF_PREOPEN_TMP_TABLES;
557 sql_command_flags[SQLCOM_TRUNCATE]|= CF_PREOPEN_TMP_TABLES;
558 sql_command_flags[SQLCOM_LOAD]|= CF_PREOPEN_TMP_TABLES;
559 sql_command_flags[SQLCOM_DROP_INDEX]|= CF_PREOPEN_TMP_TABLES;
560 sql_command_flags[SQLCOM_UPDATE]|= CF_PREOPEN_TMP_TABLES;
561 sql_command_flags[SQLCOM_UPDATE_MULTI]|= CF_PREOPEN_TMP_TABLES;
562 sql_command_flags[SQLCOM_INSERT_SELECT]|= CF_PREOPEN_TMP_TABLES;
563 sql_command_flags[SQLCOM_DELETE]|= CF_PREOPEN_TMP_TABLES;
564 sql_command_flags[SQLCOM_DELETE_MULTI]|= CF_PREOPEN_TMP_TABLES;
565 sql_command_flags[SQLCOM_REPLACE_SELECT]|= CF_PREOPEN_TMP_TABLES;
566 sql_command_flags[SQLCOM_SELECT]|= CF_PREOPEN_TMP_TABLES;
567 sql_command_flags[SQLCOM_SET_OPTION]|= CF_PREOPEN_TMP_TABLES;
568 sql_command_flags[SQLCOM_DO]|= CF_PREOPEN_TMP_TABLES;
569 sql_command_flags[SQLCOM_CALL]|= CF_PREOPEN_TMP_TABLES;
570 sql_command_flags[SQLCOM_CHECKSUM]|= CF_PREOPEN_TMP_TABLES;
571 sql_command_flags[SQLCOM_ANALYZE]|= CF_PREOPEN_TMP_TABLES;
572 sql_command_flags[SQLCOM_CHECK]|= CF_PREOPEN_TMP_TABLES;
573 sql_command_flags[SQLCOM_OPTIMIZE]|= CF_PREOPEN_TMP_TABLES;
574 sql_command_flags[SQLCOM_REPAIR]|= CF_PREOPEN_TMP_TABLES;
575 sql_command_flags[SQLCOM_PRELOAD_KEYS]|= CF_PREOPEN_TMP_TABLES;
576 sql_command_flags[SQLCOM_ASSIGN_TO_KEYCACHE]|= CF_PREOPEN_TMP_TABLES;
577
578 /*
579 DDL statements that should start with closing opened handlers.
580
581 We use this flag only for statements for which open HANDLERs
582 have to be closed before emporary tables are pre-opened.
583 */
584 sql_command_flags[SQLCOM_CREATE_TABLE]|= CF_HA_CLOSE;
585 sql_command_flags[SQLCOM_DROP_TABLE]|= CF_HA_CLOSE;
586 sql_command_flags[SQLCOM_ALTER_TABLE]|= CF_HA_CLOSE;
587 sql_command_flags[SQLCOM_TRUNCATE]|= CF_HA_CLOSE;
588 sql_command_flags[SQLCOM_REPAIR]|= CF_HA_CLOSE;
589 sql_command_flags[SQLCOM_OPTIMIZE]|= CF_HA_CLOSE;
590 sql_command_flags[SQLCOM_ANALYZE]|= CF_HA_CLOSE;
591 sql_command_flags[SQLCOM_CHECK]|= CF_HA_CLOSE;
592 sql_command_flags[SQLCOM_CREATE_INDEX]|= CF_HA_CLOSE;
593 sql_command_flags[SQLCOM_DROP_INDEX]|= CF_HA_CLOSE;
594 sql_command_flags[SQLCOM_PRELOAD_KEYS]|= CF_HA_CLOSE;
595 sql_command_flags[SQLCOM_ASSIGN_TO_KEYCACHE]|= CF_HA_CLOSE;
596
597 /*
598 Mark statements that always are disallowed in read-only
599 transactions. Note that according to the SQL standard,
600 even temporary table DDL should be disallowed.
601 */
602 sql_command_flags[SQLCOM_CREATE_TABLE]|= CF_DISALLOW_IN_RO_TRANS;
603 sql_command_flags[SQLCOM_ALTER_TABLE]|= CF_DISALLOW_IN_RO_TRANS;
604 sql_command_flags[SQLCOM_DROP_TABLE]|= CF_DISALLOW_IN_RO_TRANS;
605 sql_command_flags[SQLCOM_RENAME_TABLE]|= CF_DISALLOW_IN_RO_TRANS;
606 sql_command_flags[SQLCOM_CREATE_INDEX]|= CF_DISALLOW_IN_RO_TRANS;
607 sql_command_flags[SQLCOM_DROP_INDEX]|= CF_DISALLOW_IN_RO_TRANS;
608 sql_command_flags[SQLCOM_CREATE_DB]|= CF_DISALLOW_IN_RO_TRANS;
609 sql_command_flags[SQLCOM_DROP_DB]|= CF_DISALLOW_IN_RO_TRANS;
610 sql_command_flags[SQLCOM_ALTER_DB_UPGRADE]|= CF_DISALLOW_IN_RO_TRANS;
611 sql_command_flags[SQLCOM_ALTER_DB]|= CF_DISALLOW_IN_RO_TRANS;
612 sql_command_flags[SQLCOM_CREATE_VIEW]|= CF_DISALLOW_IN_RO_TRANS;
613 sql_command_flags[SQLCOM_DROP_VIEW]|= CF_DISALLOW_IN_RO_TRANS;
614 sql_command_flags[SQLCOM_CREATE_TRIGGER]|= CF_DISALLOW_IN_RO_TRANS;
615 sql_command_flags[SQLCOM_DROP_TRIGGER]|= CF_DISALLOW_IN_RO_TRANS;
616 sql_command_flags[SQLCOM_CREATE_EVENT]|= CF_DISALLOW_IN_RO_TRANS;
617 sql_command_flags[SQLCOM_ALTER_EVENT]|= CF_DISALLOW_IN_RO_TRANS;
618 sql_command_flags[SQLCOM_DROP_EVENT]|= CF_DISALLOW_IN_RO_TRANS;
619 sql_command_flags[SQLCOM_CREATE_USER]|= CF_DISALLOW_IN_RO_TRANS;
620 sql_command_flags[SQLCOM_RENAME_USER]|= CF_DISALLOW_IN_RO_TRANS;
621 sql_command_flags[SQLCOM_ALTER_USER]|= CF_DISALLOW_IN_RO_TRANS;
622 sql_command_flags[SQLCOM_DROP_USER]|= CF_DISALLOW_IN_RO_TRANS;
623 sql_command_flags[SQLCOM_CREATE_SERVER]|= CF_DISALLOW_IN_RO_TRANS;
624 sql_command_flags[SQLCOM_ALTER_SERVER]|= CF_DISALLOW_IN_RO_TRANS;
625 sql_command_flags[SQLCOM_DROP_SERVER]|= CF_DISALLOW_IN_RO_TRANS;
626 sql_command_flags[SQLCOM_CREATE_FUNCTION]|= CF_DISALLOW_IN_RO_TRANS;
627 sql_command_flags[SQLCOM_CREATE_PROCEDURE]|= CF_DISALLOW_IN_RO_TRANS;
628 sql_command_flags[SQLCOM_CREATE_SPFUNCTION]|=CF_DISALLOW_IN_RO_TRANS;
629 sql_command_flags[SQLCOM_DROP_PROCEDURE]|= CF_DISALLOW_IN_RO_TRANS;
630 sql_command_flags[SQLCOM_DROP_FUNCTION]|= CF_DISALLOW_IN_RO_TRANS;
631 sql_command_flags[SQLCOM_ALTER_PROCEDURE]|= CF_DISALLOW_IN_RO_TRANS;
632 sql_command_flags[SQLCOM_ALTER_FUNCTION]|= CF_DISALLOW_IN_RO_TRANS;
633 sql_command_flags[SQLCOM_TRUNCATE]|= CF_DISALLOW_IN_RO_TRANS;
634 sql_command_flags[SQLCOM_ALTER_TABLESPACE]|= CF_DISALLOW_IN_RO_TRANS;
635 sql_command_flags[SQLCOM_REPAIR]|= CF_DISALLOW_IN_RO_TRANS;
636 sql_command_flags[SQLCOM_OPTIMIZE]|= CF_DISALLOW_IN_RO_TRANS;
637 sql_command_flags[SQLCOM_GRANT]|= CF_DISALLOW_IN_RO_TRANS;
638 sql_command_flags[SQLCOM_REVOKE]|= CF_DISALLOW_IN_RO_TRANS;
639 sql_command_flags[SQLCOM_REVOKE_ALL]|= CF_DISALLOW_IN_RO_TRANS;
640 sql_command_flags[SQLCOM_INSTALL_PLUGIN]|= CF_DISALLOW_IN_RO_TRANS;
641 sql_command_flags[SQLCOM_UNINSTALL_PLUGIN]|= CF_DISALLOW_IN_RO_TRANS;
642 sql_command_flags[SQLCOM_ALTER_INSTANCE]|= CF_DISALLOW_IN_RO_TRANS;
643
644 /*
645 Mark statements that are allowed to be executed by the plugins.
646 */
647 sql_command_flags[SQLCOM_SELECT]|= CF_ALLOW_PROTOCOL_PLUGIN;
648 sql_command_flags[SQLCOM_CREATE_TABLE]|= CF_ALLOW_PROTOCOL_PLUGIN;
649 sql_command_flags[SQLCOM_CREATE_INDEX]|= CF_ALLOW_PROTOCOL_PLUGIN;
650 sql_command_flags[SQLCOM_ALTER_TABLE]|= CF_ALLOW_PROTOCOL_PLUGIN;
651 sql_command_flags[SQLCOM_UPDATE]|= CF_ALLOW_PROTOCOL_PLUGIN;
652 sql_command_flags[SQLCOM_INSERT]|= CF_ALLOW_PROTOCOL_PLUGIN;
653 sql_command_flags[SQLCOM_INSERT_SELECT]|= CF_ALLOW_PROTOCOL_PLUGIN;
654 sql_command_flags[SQLCOM_DELETE]|= CF_ALLOW_PROTOCOL_PLUGIN;
655 sql_command_flags[SQLCOM_TRUNCATE]|= CF_ALLOW_PROTOCOL_PLUGIN;
656 sql_command_flags[SQLCOM_DROP_TABLE]|= CF_ALLOW_PROTOCOL_PLUGIN;
657 sql_command_flags[SQLCOM_DROP_INDEX]|= CF_ALLOW_PROTOCOL_PLUGIN;
658 sql_command_flags[SQLCOM_SHOW_DATABASES]|= CF_ALLOW_PROTOCOL_PLUGIN;
659 sql_command_flags[SQLCOM_SHOW_TABLES]|= CF_ALLOW_PROTOCOL_PLUGIN;
660 sql_command_flags[SQLCOM_SHOW_FIELDS]|= CF_ALLOW_PROTOCOL_PLUGIN;
661 sql_command_flags[SQLCOM_SHOW_KEYS]|= CF_ALLOW_PROTOCOL_PLUGIN;
662 sql_command_flags[SQLCOM_SHOW_VARIABLES]|= CF_ALLOW_PROTOCOL_PLUGIN;
663 sql_command_flags[SQLCOM_SHOW_STATUS]|= CF_ALLOW_PROTOCOL_PLUGIN;
664 sql_command_flags[SQLCOM_SHOW_ENGINE_LOGS]|= CF_ALLOW_PROTOCOL_PLUGIN;
665 sql_command_flags[SQLCOM_SHOW_ENGINE_STATUS]|= CF_ALLOW_PROTOCOL_PLUGIN;
666 sql_command_flags[SQLCOM_SHOW_ENGINE_MUTEX]|= CF_ALLOW_PROTOCOL_PLUGIN;
667 sql_command_flags[SQLCOM_SHOW_PROCESSLIST]|= CF_ALLOW_PROTOCOL_PLUGIN;
668 sql_command_flags[SQLCOM_SHOW_MASTER_STAT]|= CF_ALLOW_PROTOCOL_PLUGIN;
669 sql_command_flags[SQLCOM_SHOW_SLAVE_STAT]|= CF_ALLOW_PROTOCOL_PLUGIN;
670 sql_command_flags[SQLCOM_SHOW_GRANTS]|= CF_ALLOW_PROTOCOL_PLUGIN;
671 sql_command_flags[SQLCOM_SHOW_CREATE]|= CF_ALLOW_PROTOCOL_PLUGIN;
672 sql_command_flags[SQLCOM_SHOW_CHARSETS]|= CF_ALLOW_PROTOCOL_PLUGIN;
673 sql_command_flags[SQLCOM_SHOW_COLLATIONS]|= CF_ALLOW_PROTOCOL_PLUGIN;
674 sql_command_flags[SQLCOM_SHOW_CREATE_DB]|= CF_ALLOW_PROTOCOL_PLUGIN;
675 sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]|= CF_ALLOW_PROTOCOL_PLUGIN;
676 sql_command_flags[SQLCOM_SHOW_TRIGGERS]|= CF_ALLOW_PROTOCOL_PLUGIN;
677 sql_command_flags[SQLCOM_LOAD]|= CF_ALLOW_PROTOCOL_PLUGIN;
678 sql_command_flags[SQLCOM_SET_OPTION]|= CF_ALLOW_PROTOCOL_PLUGIN;
679 sql_command_flags[SQLCOM_LOCK_TABLES]|= CF_ALLOW_PROTOCOL_PLUGIN;
680 sql_command_flags[SQLCOM_UNLOCK_TABLES]|= CF_ALLOW_PROTOCOL_PLUGIN;
681 sql_command_flags[SQLCOM_GRANT]|= CF_ALLOW_PROTOCOL_PLUGIN;
682 sql_command_flags[SQLCOM_CHANGE_DB]|= CF_ALLOW_PROTOCOL_PLUGIN;
683 sql_command_flags[SQLCOM_CREATE_DB]|= CF_ALLOW_PROTOCOL_PLUGIN;
684 sql_command_flags[SQLCOM_DROP_DB]|= CF_ALLOW_PROTOCOL_PLUGIN;
685 sql_command_flags[SQLCOM_ALTER_DB]|= CF_ALLOW_PROTOCOL_PLUGIN;
686 sql_command_flags[SQLCOM_REPAIR]|= CF_ALLOW_PROTOCOL_PLUGIN;
687 sql_command_flags[SQLCOM_REPLACE]|= CF_ALLOW_PROTOCOL_PLUGIN;
688 sql_command_flags[SQLCOM_REPLACE_SELECT]|= CF_ALLOW_PROTOCOL_PLUGIN;
689 sql_command_flags[SQLCOM_CREATE_FUNCTION]|= CF_ALLOW_PROTOCOL_PLUGIN;
690 sql_command_flags[SQLCOM_DROP_FUNCTION]|= CF_ALLOW_PROTOCOL_PLUGIN;
691 sql_command_flags[SQLCOM_REVOKE]|= CF_ALLOW_PROTOCOL_PLUGIN;
692 sql_command_flags[SQLCOM_OPTIMIZE]|= CF_ALLOW_PROTOCOL_PLUGIN;
693 sql_command_flags[SQLCOM_CHECK]|= CF_ALLOW_PROTOCOL_PLUGIN;
694 sql_command_flags[SQLCOM_ASSIGN_TO_KEYCACHE]|= CF_ALLOW_PROTOCOL_PLUGIN;
695 sql_command_flags[SQLCOM_PRELOAD_KEYS]|= CF_ALLOW_PROTOCOL_PLUGIN;
696 sql_command_flags[SQLCOM_FLUSH]|= CF_ALLOW_PROTOCOL_PLUGIN;
697 sql_command_flags[SQLCOM_KILL]|= CF_ALLOW_PROTOCOL_PLUGIN;
698 sql_command_flags[SQLCOM_ANALYZE]|= CF_ALLOW_PROTOCOL_PLUGIN;
699 sql_command_flags[SQLCOM_ROLLBACK]|= CF_ALLOW_PROTOCOL_PLUGIN;
700 sql_command_flags[SQLCOM_ROLLBACK_TO_SAVEPOINT]|= CF_ALLOW_PROTOCOL_PLUGIN;
701 sql_command_flags[SQLCOM_COMMIT]|= CF_ALLOW_PROTOCOL_PLUGIN;
702 sql_command_flags[SQLCOM_SAVEPOINT]|= CF_ALLOW_PROTOCOL_PLUGIN;
703 sql_command_flags[SQLCOM_RELEASE_SAVEPOINT]|= CF_ALLOW_PROTOCOL_PLUGIN;
704 sql_command_flags[SQLCOM_SLAVE_START]|= CF_ALLOW_PROTOCOL_PLUGIN;
705 sql_command_flags[SQLCOM_SLAVE_STOP]|= CF_ALLOW_PROTOCOL_PLUGIN;
706 sql_command_flags[SQLCOM_BEGIN]|= CF_ALLOW_PROTOCOL_PLUGIN;
707 sql_command_flags[SQLCOM_CHANGE_MASTER]|= CF_ALLOW_PROTOCOL_PLUGIN;
708 sql_command_flags[SQLCOM_CHANGE_REPLICATION_FILTER]|= CF_ALLOW_PROTOCOL_PLUGIN;
709 sql_command_flags[SQLCOM_RENAME_TABLE]|= CF_ALLOW_PROTOCOL_PLUGIN;
710 sql_command_flags[SQLCOM_RESET]|= CF_ALLOW_PROTOCOL_PLUGIN;
711 sql_command_flags[SQLCOM_PURGE]|= CF_ALLOW_PROTOCOL_PLUGIN;
712 sql_command_flags[SQLCOM_PURGE_BEFORE]|= CF_ALLOW_PROTOCOL_PLUGIN;
713 sql_command_flags[SQLCOM_SHOW_BINLOGS]|= CF_ALLOW_PROTOCOL_PLUGIN;
714 sql_command_flags[SQLCOM_SHOW_OPEN_TABLES]|= CF_ALLOW_PROTOCOL_PLUGIN;
715 sql_command_flags[SQLCOM_HA_OPEN]|= CF_ALLOW_PROTOCOL_PLUGIN;
716 sql_command_flags[SQLCOM_HA_CLOSE]|= CF_ALLOW_PROTOCOL_PLUGIN;
717 sql_command_flags[SQLCOM_HA_READ]|= CF_ALLOW_PROTOCOL_PLUGIN;
718 sql_command_flags[SQLCOM_SHOW_SLAVE_HOSTS]|= CF_ALLOW_PROTOCOL_PLUGIN;
719 sql_command_flags[SQLCOM_DELETE_MULTI]|= CF_ALLOW_PROTOCOL_PLUGIN;
720 sql_command_flags[SQLCOM_UPDATE_MULTI]|= CF_ALLOW_PROTOCOL_PLUGIN;
721 sql_command_flags[SQLCOM_SHOW_BINLOG_EVENTS]|= CF_ALLOW_PROTOCOL_PLUGIN;
722 sql_command_flags[SQLCOM_DO]|= CF_ALLOW_PROTOCOL_PLUGIN;
723 sql_command_flags[SQLCOM_SHOW_WARNS]|= CF_ALLOW_PROTOCOL_PLUGIN;
724 sql_command_flags[SQLCOM_EMPTY_QUERY]|= CF_ALLOW_PROTOCOL_PLUGIN;
725 sql_command_flags[SQLCOM_SHOW_ERRORS]|= CF_ALLOW_PROTOCOL_PLUGIN;
726 sql_command_flags[SQLCOM_SHOW_STORAGE_ENGINES]|= CF_ALLOW_PROTOCOL_PLUGIN;
727 sql_command_flags[SQLCOM_SHOW_PRIVILEGES]|= CF_ALLOW_PROTOCOL_PLUGIN;
728 sql_command_flags[SQLCOM_HELP]|= CF_ALLOW_PROTOCOL_PLUGIN;
729 sql_command_flags[SQLCOM_CREATE_USER]|= CF_ALLOW_PROTOCOL_PLUGIN;
730 sql_command_flags[SQLCOM_DROP_USER]|= CF_ALLOW_PROTOCOL_PLUGIN;
731 sql_command_flags[SQLCOM_RENAME_USER]|= CF_ALLOW_PROTOCOL_PLUGIN;
732 sql_command_flags[SQLCOM_REVOKE_ALL]|= CF_ALLOW_PROTOCOL_PLUGIN;
733 sql_command_flags[SQLCOM_CHECKSUM]|= CF_ALLOW_PROTOCOL_PLUGIN;
734 sql_command_flags[SQLCOM_CREATE_PROCEDURE]|= CF_ALLOW_PROTOCOL_PLUGIN;
735 sql_command_flags[SQLCOM_CREATE_SPFUNCTION]|= CF_ALLOW_PROTOCOL_PLUGIN;
736 sql_command_flags[SQLCOM_CALL]|= CF_ALLOW_PROTOCOL_PLUGIN;
737 sql_command_flags[SQLCOM_DROP_PROCEDURE]|= CF_ALLOW_PROTOCOL_PLUGIN;
738 sql_command_flags[SQLCOM_ALTER_PROCEDURE]|= CF_ALLOW_PROTOCOL_PLUGIN;
739 sql_command_flags[SQLCOM_ALTER_FUNCTION]|= CF_ALLOW_PROTOCOL_PLUGIN;
740 sql_command_flags[SQLCOM_SHOW_CREATE_PROC]|= CF_ALLOW_PROTOCOL_PLUGIN;
741 sql_command_flags[SQLCOM_SHOW_CREATE_FUNC]|= CF_ALLOW_PROTOCOL_PLUGIN;
742 sql_command_flags[SQLCOM_SHOW_STATUS_PROC]|= CF_ALLOW_PROTOCOL_PLUGIN;
743 sql_command_flags[SQLCOM_SHOW_STATUS_FUNC]|= CF_ALLOW_PROTOCOL_PLUGIN;
744 sql_command_flags[SQLCOM_PREPARE]|= CF_ALLOW_PROTOCOL_PLUGIN;
745 sql_command_flags[SQLCOM_EXECUTE]|= CF_ALLOW_PROTOCOL_PLUGIN;
746 sql_command_flags[SQLCOM_DEALLOCATE_PREPARE]|= CF_ALLOW_PROTOCOL_PLUGIN;
747 sql_command_flags[SQLCOM_CREATE_VIEW]|= CF_ALLOW_PROTOCOL_PLUGIN;
748 sql_command_flags[SQLCOM_DROP_VIEW]|= CF_ALLOW_PROTOCOL_PLUGIN;
749 sql_command_flags[SQLCOM_CREATE_TRIGGER]|= CF_ALLOW_PROTOCOL_PLUGIN;
750 sql_command_flags[SQLCOM_DROP_TRIGGER]|= CF_ALLOW_PROTOCOL_PLUGIN;
751 sql_command_flags[SQLCOM_XA_START]|= CF_ALLOW_PROTOCOL_PLUGIN;
752 sql_command_flags[SQLCOM_XA_END]|= CF_ALLOW_PROTOCOL_PLUGIN;
753 sql_command_flags[SQLCOM_XA_PREPARE]|= CF_ALLOW_PROTOCOL_PLUGIN;
754 sql_command_flags[SQLCOM_XA_COMMIT]|= CF_ALLOW_PROTOCOL_PLUGIN;
755 sql_command_flags[SQLCOM_XA_ROLLBACK]|= CF_ALLOW_PROTOCOL_PLUGIN;
756 sql_command_flags[SQLCOM_XA_RECOVER]|= CF_ALLOW_PROTOCOL_PLUGIN;
757 sql_command_flags[SQLCOM_SHOW_PROC_CODE]|= CF_ALLOW_PROTOCOL_PLUGIN;
758 sql_command_flags[SQLCOM_SHOW_FUNC_CODE]|= CF_ALLOW_PROTOCOL_PLUGIN;
759 sql_command_flags[SQLCOM_ALTER_TABLESPACE]|= CF_ALLOW_PROTOCOL_PLUGIN;
760 sql_command_flags[SQLCOM_BINLOG_BASE64_EVENT]|= CF_ALLOW_PROTOCOL_PLUGIN;
761 sql_command_flags[SQLCOM_SHOW_PLUGINS]|= CF_ALLOW_PROTOCOL_PLUGIN;
762 sql_command_flags[SQLCOM_CREATE_SERVER]|= CF_ALLOW_PROTOCOL_PLUGIN;
763 sql_command_flags[SQLCOM_DROP_SERVER]|= CF_ALLOW_PROTOCOL_PLUGIN;
764 sql_command_flags[SQLCOM_ALTER_SERVER]|= CF_ALLOW_PROTOCOL_PLUGIN;
765 sql_command_flags[SQLCOM_CREATE_EVENT]|= CF_ALLOW_PROTOCOL_PLUGIN;
766 sql_command_flags[SQLCOM_ALTER_EVENT]|= CF_ALLOW_PROTOCOL_PLUGIN;
767 sql_command_flags[SQLCOM_DROP_EVENT]|= CF_ALLOW_PROTOCOL_PLUGIN;
768 sql_command_flags[SQLCOM_SHOW_CREATE_EVENT]|= CF_ALLOW_PROTOCOL_PLUGIN;
769 sql_command_flags[SQLCOM_SHOW_EVENTS]|= CF_ALLOW_PROTOCOL_PLUGIN;
770 sql_command_flags[SQLCOM_SHOW_CREATE_TRIGGER]|= CF_ALLOW_PROTOCOL_PLUGIN;
771 sql_command_flags[SQLCOM_ALTER_DB_UPGRADE]|= CF_ALLOW_PROTOCOL_PLUGIN;
772 sql_command_flags[SQLCOM_SHOW_PROFILE]|= CF_ALLOW_PROTOCOL_PLUGIN;
773 sql_command_flags[SQLCOM_SHOW_PROFILES]|= CF_ALLOW_PROTOCOL_PLUGIN;
774 sql_command_flags[SQLCOM_SIGNAL]|= CF_ALLOW_PROTOCOL_PLUGIN;
775 sql_command_flags[SQLCOM_RESIGNAL]|= CF_ALLOW_PROTOCOL_PLUGIN;
776 sql_command_flags[SQLCOM_SHOW_RELAYLOG_EVENTS]|= CF_ALLOW_PROTOCOL_PLUGIN;
777 sql_command_flags[SQLCOM_GET_DIAGNOSTICS]|= CF_ALLOW_PROTOCOL_PLUGIN;
778 sql_command_flags[SQLCOM_ALTER_USER]|= CF_ALLOW_PROTOCOL_PLUGIN;
779 sql_command_flags[SQLCOM_EXPLAIN_OTHER]|= CF_ALLOW_PROTOCOL_PLUGIN;
780 sql_command_flags[SQLCOM_SHOW_CREATE_USER]|= CF_ALLOW_PROTOCOL_PLUGIN;
781 sql_command_flags[SQLCOM_END]|= CF_ALLOW_PROTOCOL_PLUGIN;
782 }
783
sqlcom_can_generate_row_events(enum enum_sql_command command)784 bool sqlcom_can_generate_row_events(enum enum_sql_command command)
785 {
786 return (sql_command_flags[command] & CF_CAN_GENERATE_ROW_EVENTS);
787 }
788
is_update_query(enum enum_sql_command command)789 bool is_update_query(enum enum_sql_command command)
790 {
791 assert(command >= 0 && command <= SQLCOM_END);
792 return (sql_command_flags[command] & CF_CHANGES_DATA) != 0;
793 }
794
795
is_explainable_query(enum enum_sql_command command)796 bool is_explainable_query(enum enum_sql_command command)
797 {
798 assert(command >= 0 && command <= SQLCOM_END);
799 return (sql_command_flags[command] & CF_CAN_BE_EXPLAINED) != 0;
800 }
801
802 /**
803 Check if a sql command is allowed to write to log tables.
804 @param command The SQL command
805 @return true if writing is allowed
806 */
is_log_table_write_query(enum enum_sql_command command)807 bool is_log_table_write_query(enum enum_sql_command command)
808 {
809 assert(command >= 0 && command <= SQLCOM_END);
810 return (sql_command_flags[command] & CF_WRITE_LOGS_COMMAND) != 0;
811 }
812
execute_init_command(THD * thd,LEX_STRING * init_command,mysql_rwlock_t * var_lock)813 void execute_init_command(THD *thd, LEX_STRING *init_command,
814 mysql_rwlock_t *var_lock)
815 {
816 Protocol_classic *protocol= thd->get_protocol_classic();
817 Vio* save_vio;
818 ulong save_client_capabilities;
819 COM_DATA com_data;
820
821 mysql_rwlock_rdlock(var_lock);
822 if (!init_command->length)
823 {
824 mysql_rwlock_unlock(var_lock);
825 return;
826 }
827
828 /*
829 copy the value under a lock, and release the lock.
830 init_command has to be executed without a lock held,
831 as it may try to change itself
832 */
833 size_t len= init_command->length;
834 char *buf= thd->strmake(init_command->str, len);
835 mysql_rwlock_unlock(var_lock);
836
837 #if defined(ENABLED_PROFILING)
838 thd->profiling.start_new_query();
839 thd->profiling.set_query_source(buf, len);
840 #endif
841
842 THD_STAGE_INFO(thd, stage_execution_of_init_command);
843 save_client_capabilities= protocol->get_client_capabilities();
844 protocol->add_client_capability(CLIENT_MULTI_QUERIES);
845 /*
846 We don't need return result of execution to client side.
847 To forbid this we should set thd->net.vio to 0.
848 */
849 save_vio= protocol->get_vio();
850 protocol->set_vio(NULL);
851 protocol->create_command(&com_data, COM_QUERY, (uchar *) buf, len);
852 dispatch_command(thd, &com_data, COM_QUERY);
853 protocol->set_client_capabilities(save_client_capabilities);
854 protocol->set_vio(save_vio);
855
856 #if defined(ENABLED_PROFILING)
857 thd->profiling.finish_current_query();
858 #endif
859 }
860
861
862 /* This works because items are allocated with sql_alloc() */
863
free_items(Item * item)864 void free_items(Item *item)
865 {
866 Item *next;
867 DBUG_ENTER("free_items");
868 for (; item ; item=next)
869 {
870 next=item->next;
871 item->delete_self();
872 }
873 DBUG_VOID_RETURN;
874 }
875
876 /**
877 This works because items are allocated with sql_alloc().
878 @note The function also handles null pointers (empty list).
879 */
cleanup_items(Item * item)880 void cleanup_items(Item *item)
881 {
882 DBUG_ENTER("cleanup_items");
883 for (; item ; item=item->next)
884 item->cleanup();
885 DBUG_VOID_RETURN;
886 }
887
888 #ifndef EMBEDDED_LIBRARY
889
890 /**
891 Read one command from connection and execute it (query or simple command).
892 This function is called in loop from thread function.
893
894 For profiling to work, it must never be called recursively.
895
896 @retval
897 0 success
898 @retval
899 1 request of thread shutdown (see dispatch_command() description)
900 */
901
do_command(THD * thd)902 bool do_command(THD *thd)
903 {
904 bool return_value;
905 int rc;
906 const bool classic=
907 (thd->get_protocol()->type() == Protocol::PROTOCOL_TEXT ||
908 thd->get_protocol()->type() == Protocol::PROTOCOL_BINARY);
909
910 NET *net= NULL;
911 enum enum_server_command command;
912 COM_DATA com_data;
913 DBUG_ENTER("do_command");
914
915 /*
916 indicator of uninitialized lex => normal flow of errors handling
917 (see my_message_sql)
918 */
919 thd->lex->set_current_select(0);
920
921 /*
922 XXX: this code is here only to clear possible errors of init_connect.
923 Consider moving to prepare_new_connection_state() instead.
924 That requires making sure the DA is cleared before non-parsing statements
925 such as COM_QUIT.
926 */
927 thd->clear_error(); // Clear error message
928 thd->get_stmt_da()->reset_diagnostics_area();
929
930 if (classic)
931 {
932 /*
933 This thread will do a blocking read from the client which
934 will be interrupted when the next command is received from
935 the client, the connection is closed or "net_wait_timeout"
936 number of seconds has passed.
937 */
938 net= thd->get_protocol_classic()->get_net();
939 my_net_set_read_timeout(net, thd->variables.net_wait_timeout);
940 net_new_transaction(net);
941 }
942
943 /*
944 Synchronization point for testing of KILL_CONNECTION.
945 This sync point can wait here, to simulate slow code execution
946 between the last test of thd->killed and blocking in read().
947
948 The goal of this test is to verify that a connection does not
949 hang, if it is killed at this point of execution.
950 (Bug#37780 - main.kill fails randomly)
951
952 Note that the sync point wait itself will be terminated by a
953 kill. In this case it consumes a condition broadcast, but does
954 not change anything else. The consumed broadcast should not
955 matter here, because the read/recv() below doesn't use it.
956 */
957 DEBUG_SYNC(thd, "before_do_command_net_read");
958
959 /*
960 Because of networking layer callbacks in place,
961 this call will maintain the following instrumentation:
962 - IDLE events
963 - SOCKET events
964 - STATEMENT events
965 - STAGE events
966 when reading a new network packet.
967 In particular, a new instrumented statement is started.
968 See init_net_server_extension()
969 */
970 thd->m_server_idle= true;
971 rc= thd->get_protocol()->get_command(&com_data, &command);
972 thd->m_server_idle= false;
973
974 if (rc)
975 {
976 if (classic)
977 {
978 DBUG_PRINT("info",("Got error %d reading command from socket %s",
979 net->error,
980 vio_description(net->vio)));
981 }
982 else
983 {
984 DBUG_PRINT("info",("Got error %d reading command from %s protocol",
985 rc,
986 (thd->get_protocol()->type() ==
987 Protocol::PROTOCOL_LOCAL) ? "local" : "plugin"));
988 }
989 /* Instrument this broken statement as "statement/com/error" */
990 thd->m_statement_psi= MYSQL_REFINE_STATEMENT(thd->m_statement_psi,
991 com_statement_info[COM_END].m_key);
992
993 /* Check if we can continue without closing the connection */
994
995 /* The error must be set. */
996 assert(thd->is_error());
997 thd->send_statement_status();
998
999 /* Mark the statement completed. */
1000 MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
1001 thd->m_statement_psi= NULL;
1002 thd->m_digest= NULL;
1003
1004 if (rc < 0)
1005 {
1006 return_value= TRUE; // We have to close it.
1007 goto out;
1008 }
1009 if (classic)
1010 net->error= 0;
1011 return_value= FALSE;
1012 goto out;
1013 }
1014
1015 DBUG_PRINT("info",("Command on %s = %d (%s)",
1016 vio_description(net->vio), command,
1017 command_name[command].str));
1018
1019 DBUG_PRINT("info", ("packet: '%*.s'; command: %d",
1020 (int)thd->get_protocol_classic()->get_packet_length(),
1021 thd->get_protocol_classic()->get_raw_packet(), command));
1022 if (thd->get_protocol_classic()->bad_packet)
1023 assert(0); // Should be caught earlier
1024
1025 // Reclaim some memory
1026 thd->get_protocol_classic()->get_packet()->shrink(
1027 thd->variables.net_buffer_length);
1028 /* Restore read timeout value */
1029 if (classic)
1030 my_net_set_read_timeout(net, thd->variables.net_read_timeout);
1031
1032 return_value= dispatch_command(thd, &com_data, command);
1033 thd->get_protocol_classic()->get_packet()->shrink(
1034 thd->variables.net_buffer_length);
1035
1036 out:
1037 /* The statement instrumentation must be closed in all cases. */
1038 assert(thd->m_digest == NULL);
1039 assert(thd->m_statement_psi == NULL);
1040 DBUG_RETURN(return_value);
1041 }
1042 #endif /* EMBEDDED_LIBRARY */
1043
1044
1045 /**
1046 @brief Determine if an attempt to update a non-temporary table while the
1047 read-only option was enabled has been made.
1048
1049 This is a helper function to mysql_execute_command.
1050
1051 @note SQLCOM_UPDATE_MULTI is an exception and delt with elsewhere.
1052
1053 @see mysql_execute_command
1054 @returns Status code
1055 @retval TRUE The statement should be denied.
1056 @retval FALSE The statement isn't updating any relevant tables.
1057 */
deny_updates_if_read_only_option(THD * thd,TABLE_LIST * all_tables)1058 static my_bool deny_updates_if_read_only_option(THD *thd,
1059 TABLE_LIST *all_tables)
1060 {
1061 DBUG_ENTER("deny_updates_if_read_only_option");
1062
1063 if (!check_readonly(thd, false))
1064 DBUG_RETURN(FALSE);
1065
1066 LEX *lex = thd->lex;
1067 if (!(sql_command_flags[lex->sql_command] & CF_CHANGES_DATA))
1068 DBUG_RETURN(FALSE);
1069
1070 /* Multi update is an exception and is dealt with later. */
1071 if (lex->sql_command == SQLCOM_UPDATE_MULTI)
1072 DBUG_RETURN(FALSE);
1073
1074 const my_bool create_temp_tables=
1075 (lex->sql_command == SQLCOM_CREATE_TABLE) &&
1076 (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE);
1077
1078 const my_bool create_real_tables=
1079 (lex->sql_command == SQLCOM_CREATE_TABLE) &&
1080 !(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE);
1081
1082 const my_bool drop_temp_tables=
1083 (lex->sql_command == SQLCOM_DROP_TABLE) &&
1084 lex->drop_temporary;
1085
1086 const my_bool update_real_tables=
1087 ((create_real_tables ||
1088 some_non_temp_table_to_be_updated(thd, all_tables)) &&
1089 !(create_temp_tables || drop_temp_tables));
1090
1091 const my_bool create_or_drop_databases=
1092 (lex->sql_command == SQLCOM_CREATE_DB) ||
1093 (lex->sql_command == SQLCOM_DROP_DB);
1094
1095 if (update_real_tables || create_or_drop_databases)
1096 {
1097 /*
1098 An attempt was made to modify one or more non-temporary tables.
1099 */
1100 DBUG_RETURN(TRUE);
1101 }
1102
1103
1104 /* Assuming that only temporary tables are modified. */
1105 DBUG_RETURN(FALSE);
1106 }
1107
1108
1109 /**
1110 Check whether max statement time is applicable to statement or not.
1111
1112
1113 @param thd Thread (session) context.
1114
1115 @return true if max statement time is applicable to statement
1116 @return false otherwise.
1117 */
is_timer_applicable_to_statement(THD * thd)1118 static inline bool is_timer_applicable_to_statement(THD *thd)
1119 {
1120 bool timer_value_is_set= (thd->lex->max_execution_time ||
1121 thd->variables.max_execution_time);
1122
1123 /**
1124 Following conditions are checked,
1125 - is SELECT statement.
1126 - timer support is implemented and it is initialized.
1127 - statement is not made by the slave threads.
1128 - timer is not set for statement
1129 - timer out value of is set
1130 - SELECT statement is not from any stored programs.
1131 */
1132 return (thd->lex->sql_command == SQLCOM_SELECT &&
1133 (have_statement_timeout == SHOW_OPTION_YES) &&
1134 !thd->slave_thread &&
1135 !thd->timer && timer_value_is_set &&
1136 !thd->sp_runtime_ctx);
1137 }
1138
1139
1140 /**
1141 Get the maximum execution time for a statement.
1142
1143 @return Length of time in milliseconds.
1144
1145 @remark A zero timeout means that no timeout should be
1146 applied to this particular statement.
1147
1148 */
get_max_execution_time(THD * thd)1149 static inline ulong get_max_execution_time(THD *thd)
1150 {
1151 return (thd->lex->max_execution_time ? thd->lex->max_execution_time :
1152 thd->variables.max_execution_time);
1153 }
1154
1155
1156 /**
1157 Set the time until the currently running statement is aborted.
1158
1159 @param thd Thread (session) context.
1160
1161 @return true if the timer was armed.
1162 */
set_statement_timer(THD * thd)1163 static inline bool set_statement_timer(THD *thd)
1164 {
1165 ulong max_execution_time= get_max_execution_time(thd);
1166
1167 /**
1168 whether timer can be set for the statement or not should be checked before
1169 calling set_statement_timer function.
1170 */
1171 assert(is_timer_applicable_to_statement(thd) == true);
1172 assert(thd->timer == NULL);
1173
1174 thd->timer= thd_timer_set(thd, thd->timer_cache, max_execution_time);
1175 thd->timer_cache= NULL;
1176
1177 if (thd->timer)
1178 thd->status_var.max_execution_time_set++;
1179 else
1180 thd->status_var.max_execution_time_set_failed++;
1181
1182 return thd->timer;
1183 }
1184
1185
1186 /**
1187 Deactivate the timer associated with the statement that was executed.
1188
1189 @param thd Thread (session) context.
1190 */
1191
reset_statement_timer(THD * thd)1192 void reset_statement_timer(THD *thd)
1193 {
1194 assert(thd->timer);
1195 /* Cache the timer object if it can be reused. */
1196 thd->timer_cache= thd_timer_reset(thd->timer);
1197 thd->timer= NULL;
1198 }
1199
1200
1201 /**
1202 Perform one connection-level (COM_XXXX) command.
1203
1204 @param thd connection handle
1205 @param command type of command to perform
1206 @com_data com_data union to store the generated command
1207
1208 @todo
1209 set thd->lex->sql_command to SQLCOM_END here.
1210 @todo
1211 The following has to be changed to an 8 byte integer
1212
1213 @retval
1214 0 ok
1215 @retval
1216 1 request of thread shutdown, i. e. if command is
1217 COM_QUIT/COM_SHUTDOWN
1218 */
dispatch_command(THD * thd,const COM_DATA * com_data,enum enum_server_command command)1219 bool dispatch_command(THD *thd, const COM_DATA *com_data,
1220 enum enum_server_command command)
1221 {
1222 bool error= 0;
1223 Global_THD_manager *thd_manager= Global_THD_manager::get_instance();
1224 DBUG_ENTER("dispatch_command");
1225 DBUG_PRINT("info", ("command: %d", command));
1226
1227 /* SHOW PROFILE instrumentation, begin */
1228 #if defined(ENABLED_PROFILING)
1229 thd->profiling.start_new_query();
1230 #endif
1231
1232 /* DTRACE instrumentation, begin */
1233 MYSQL_COMMAND_START(thd->thread_id(), command,
1234 (char *) thd->security_context()->priv_user().str,
1235 (char *) thd->security_context()->host_or_ip().str);
1236
1237 /* Performance Schema Interface instrumentation, begin */
1238 thd->m_statement_psi= MYSQL_REFINE_STATEMENT(thd->m_statement_psi,
1239 com_statement_info[command].m_key);
1240
1241 thd->set_command(command);
1242 /*
1243 Commands which always take a long time are logged into
1244 the slow log only if opt_log_slow_admin_statements is set.
1245 */
1246 thd->enable_slow_log= TRUE;
1247 thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
1248 thd->set_time();
1249 if (thd->is_valid_time() == false)
1250 {
1251 /*
1252 If the time has gone past 2038 we need to shutdown the server. But
1253 there is possibility of getting invalid time value on some platforms.
1254 For example, gettimeofday() might return incorrect value on solaris
1255 platform. Hence validating the current time with 5 iterations before
1256 initiating the normal server shutdown process because of time getting
1257 past 2038.
1258 */
1259 const int max_tries= 5;
1260 sql_print_warning("Current time has got past year 2038. Validating current "
1261 "time with %d iterations before initiating the normal "
1262 "server shutdown process.", max_tries);
1263
1264 int tries= 0;
1265 while (++tries <= max_tries)
1266 {
1267 thd->set_time();
1268 if (thd->is_valid_time() == true)
1269 {
1270 sql_print_warning("Iteration %d: Obtained valid current time from "
1271 "system", tries);
1272 break;
1273 }
1274 sql_print_warning("Iteration %d: Current time obtained from system is "
1275 "greater than 2038", tries);
1276 }
1277 if (tries > max_tries)
1278 {
1279 /*
1280 If the time has got past 2038 we need to shut this server down.
1281 We do this by making sure every command is a shutdown and we
1282 have enough privileges to shut the server down
1283
1284 TODO: remove this when we have full 64 bit my_time_t support
1285 */
1286 sql_print_error("This MySQL server doesn't support dates later than 2038");
1287 ulong master_access= thd->security_context()->master_access();
1288 thd->security_context()->set_master_access(master_access | SHUTDOWN_ACL);
1289 command= COM_SHUTDOWN;
1290 }
1291 }
1292 thd->set_query_id(next_query_id());
1293 thd->reset_rewritten_query();
1294 thd_manager->inc_thread_running();
1295
1296 if (!(server_command_flags[command] & CF_SKIP_QUESTIONS))
1297 thd->status_var.questions++;
1298
1299 /**
1300 Clear the set of flags that are expected to be cleared at the
1301 beginning of each command.
1302 */
1303 thd->server_status&= ~SERVER_STATUS_CLEAR_SET;
1304
1305 if (thd->get_protocol()->type() == Protocol::PROTOCOL_PLUGIN &&
1306 !(server_command_flags[command] & CF_ALLOW_PROTOCOL_PLUGIN))
1307 {
1308 my_error(ER_PLUGGABLE_PROTOCOL_COMMAND_NOT_SUPPORTED, MYF(0));
1309 thd->killed= THD::KILL_CONNECTION;
1310 error= true;
1311 goto done;
1312 }
1313
1314 /**
1315 Enforce password expiration for all RPC commands, except the
1316 following:
1317
1318 COM_QUERY does a more fine-grained check later.
1319 COM_STMT_CLOSE and COM_STMT_SEND_LONG_DATA don't return anything.
1320 COM_PING only discloses information that the server is running,
1321 and that's available through other means.
1322 COM_QUIT should work even for expired statements.
1323 */
1324 if (unlikely(thd->security_context()->password_expired() &&
1325 command != COM_QUERY &&
1326 command != COM_STMT_CLOSE &&
1327 command != COM_STMT_SEND_LONG_DATA &&
1328 command != COM_PING &&
1329 command != COM_QUIT))
1330 {
1331 my_error(ER_MUST_CHANGE_PASSWORD, MYF(0));
1332 goto done;
1333 }
1334
1335 #ifndef EMBEDDED_LIBRARY
1336 if (mysql_audit_notify(thd,
1337 AUDIT_EVENT(MYSQL_AUDIT_COMMAND_START),
1338 command, command_name[command].str))
1339 {
1340 goto done;
1341 }
1342 #endif /* !EMBEDDED_LIBRARY */
1343
1344 switch (command) {
1345 case COM_INIT_DB:
1346 {
1347 LEX_STRING tmp;
1348 thd->status_var.com_stat[SQLCOM_CHANGE_DB]++;
1349 thd->convert_string(&tmp, system_charset_info,
1350 com_data->com_init_db.db_name,
1351 com_data->com_init_db.length, thd->charset());
1352
1353 LEX_CSTRING tmp_cstr= {tmp.str, tmp.length};
1354 if (!mysql_change_db(thd, tmp_cstr, FALSE))
1355 {
1356 query_logger.general_log_write(thd, command,
1357 thd->db().str, thd->db().length);
1358 my_ok(thd);
1359 }
1360 break;
1361 }
1362 #ifdef HAVE_REPLICATION
1363 case COM_REGISTER_SLAVE:
1364 {
1365 // TODO: access of protocol_classic should be removed
1366 if (!register_slave(thd,
1367 thd->get_protocol_classic()->get_raw_packet(),
1368 thd->get_protocol_classic()->get_packet_length()))
1369 my_ok(thd);
1370 break;
1371 }
1372 #endif
1373 case COM_RESET_CONNECTION:
1374 {
1375 thd->status_var.com_other++;
1376 thd->cleanup_connection();
1377 my_ok(thd);
1378 break;
1379 }
1380 case COM_CHANGE_USER:
1381 {
1382 int auth_rc;
1383 thd->status_var.com_other++;
1384
1385 thd->cleanup_connection();
1386 USER_CONN *save_user_connect=
1387 const_cast<USER_CONN*>(thd->get_user_connect());
1388 LEX_CSTRING save_db= thd->db();
1389 Security_context save_security_ctx(*(thd->security_context()));
1390
1391 auth_rc= acl_authenticate(thd, COM_CHANGE_USER);
1392 #ifndef EMBEDDED_LIBRARY
1393 auth_rc|= mysql_audit_notify(thd,
1394 AUDIT_EVENT(MYSQL_AUDIT_CONNECTION_CHANGE_USER));
1395 #endif
1396 if (auth_rc)
1397 {
1398 *thd->security_context()= save_security_ctx;
1399 thd->set_user_connect(save_user_connect);
1400 thd->reset_db(save_db);
1401
1402 my_error(ER_ACCESS_DENIED_CHANGE_USER_ERROR, MYF(0),
1403 thd->security_context()->user().str,
1404 thd->security_context()->host_or_ip().str,
1405 (thd->password ? ER(ER_YES) : ER(ER_NO)));
1406 thd->killed= THD::KILL_CONNECTION;
1407 error=true;
1408 }
1409 else
1410 {
1411 #ifndef NO_EMBEDDED_ACCESS_CHECKS
1412 /* we've authenticated new user */
1413 if (save_user_connect)
1414 decrease_user_connections(save_user_connect);
1415 #endif /* NO_EMBEDDED_ACCESS_CHECKS */
1416 mysql_mutex_lock(&thd->LOCK_thd_data);
1417 my_free(const_cast<char*>(save_db.str));
1418 save_db= NULL_CSTR;
1419 mysql_mutex_unlock(&thd->LOCK_thd_data);
1420 }
1421 break;
1422 }
1423 case COM_STMT_EXECUTE:
1424 {
1425 mysqld_stmt_execute(thd, com_data->com_stmt_execute.stmt_id,
1426 com_data->com_stmt_execute.flags,
1427 com_data->com_stmt_execute.params,
1428 com_data->com_stmt_execute.params_length);
1429 break;
1430 }
1431 case COM_STMT_FETCH:
1432 {
1433 mysqld_stmt_fetch(thd, com_data->com_stmt_fetch.stmt_id,
1434 com_data->com_stmt_fetch.num_rows);
1435 break;
1436 }
1437 case COM_STMT_SEND_LONG_DATA:
1438 {
1439 mysql_stmt_get_longdata(thd, com_data->com_stmt_send_long_data.stmt_id,
1440 com_data->com_stmt_send_long_data.param_number,
1441 com_data->com_stmt_send_long_data.longdata,
1442 com_data->com_stmt_send_long_data.length);
1443 break;
1444 }
1445 case COM_STMT_PREPARE:
1446 {
1447 mysqld_stmt_prepare(thd, com_data->com_stmt_prepare.query,
1448 com_data->com_stmt_prepare.length);
1449 break;
1450 }
1451 case COM_STMT_CLOSE:
1452 {
1453 mysqld_stmt_close(thd, com_data->com_stmt_close.stmt_id);
1454 break;
1455 }
1456 case COM_STMT_RESET:
1457 {
1458 mysqld_stmt_reset(thd, com_data->com_stmt_reset.stmt_id);
1459 break;
1460 }
1461 case COM_QUERY:
1462 {
1463 assert(thd->m_digest == NULL);
1464 thd->m_digest= & thd->m_digest_state;
1465 thd->m_digest->reset(thd->m_token_array, max_digest_length);
1466
1467 if (alloc_query(thd, com_data->com_query.query,
1468 com_data->com_query.length))
1469 break; // fatal error is set
1470 MYSQL_QUERY_START(const_cast<char*>(thd->query().str), thd->thread_id(),
1471 (char *) (thd->db().str ? thd->db().str : ""),
1472 (char *) thd->security_context()->priv_user().str,
1473 (char *) thd->security_context()->host_or_ip().str);
1474
1475 const char *packet_end= thd->query().str + thd->query().length;
1476
1477 if (opt_general_log_raw)
1478 query_logger.general_log_write(thd, command, thd->query().str,
1479 thd->query().length);
1480
1481 DBUG_PRINT("query",("%-.4096s", thd->query().str));
1482
1483 #if defined(ENABLED_PROFILING)
1484 thd->profiling.set_query_source(thd->query().str, thd->query().length);
1485 #endif
1486
1487 Parser_state parser_state;
1488 if (parser_state.init(thd, thd->query().str, thd->query().length))
1489 break;
1490
1491 parser_state.m_input.m_has_digest = true;
1492
1493 mysql_parse(thd, &parser_state);
1494
1495 while (!thd->killed && (parser_state.m_lip.found_semicolon != NULL) &&
1496 ! thd->is_error())
1497 {
1498 /*
1499 Multiple queries exits, execute them individually
1500 */
1501 const char *beginning_of_next_stmt= parser_state.m_lip.found_semicolon;
1502
1503 /* Finalize server status flags after executing a statement. */
1504 thd->update_server_status();
1505 thd->send_statement_status();
1506 query_cache.end_of_result(thd);
1507
1508 #ifndef EMBEDDED_LIBRARY
1509 mysql_audit_notify(thd, AUDIT_EVENT(MYSQL_AUDIT_GENERAL_STATUS),
1510 thd->get_stmt_da()->is_error() ?
1511 thd->get_stmt_da()->mysql_errno() : 0,
1512 command_name[command].str,
1513 command_name[command].length);
1514 #endif
1515
1516 size_t length= static_cast<size_t>(packet_end - beginning_of_next_stmt);
1517
1518 log_slow_statement(thd);
1519
1520 /* Remove garbage at start of query */
1521 while (length > 0 && my_isspace(thd->charset(), *beginning_of_next_stmt))
1522 {
1523 beginning_of_next_stmt++;
1524 length--;
1525 }
1526
1527 /* PSI end */
1528 MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
1529 thd->m_statement_psi= NULL;
1530 thd->m_digest= NULL;
1531
1532 /* DTRACE end */
1533 if (MYSQL_QUERY_DONE_ENABLED())
1534 {
1535 MYSQL_QUERY_DONE(thd->is_error());
1536 }
1537
1538 /* SHOW PROFILE end */
1539 #if defined(ENABLED_PROFILING)
1540 thd->profiling.finish_current_query();
1541 #endif
1542
1543 /* SHOW PROFILE begin */
1544 #if defined(ENABLED_PROFILING)
1545 thd->profiling.start_new_query("continuing");
1546 thd->profiling.set_query_source(beginning_of_next_stmt, length);
1547 #endif
1548
1549 /* DTRACE begin */
1550 MYSQL_QUERY_START(const_cast<char*>(beginning_of_next_stmt),
1551 thd->thread_id(),
1552 (char *) (thd->db().str ? thd->db().str : ""),
1553 (char *) thd->security_context()->priv_user().str,
1554 (char *) thd->security_context()->host_or_ip().str);
1555
1556 /* PSI begin */
1557 thd->m_digest= & thd->m_digest_state;
1558 thd->m_digest->reset(thd->m_token_array, max_digest_length);
1559
1560 thd->m_statement_psi= MYSQL_START_STATEMENT(&thd->m_statement_state,
1561 com_statement_info[command].m_key,
1562 thd->db().str, thd->db().length,
1563 thd->charset(), NULL);
1564 THD_STAGE_INFO(thd, stage_starting);
1565
1566 thd->set_query(beginning_of_next_stmt, length);
1567 thd->set_query_id(next_query_id());
1568 /*
1569 Count each statement from the client.
1570 */
1571 thd->status_var.questions++;
1572 thd->set_time(); /* Reset the query start time. */
1573 parser_state.reset(beginning_of_next_stmt, length);
1574 /* TODO: set thd->lex->sql_command to SQLCOM_END here */
1575 mysql_parse(thd, &parser_state);
1576 }
1577
1578 /* Need to set error to true for graceful shutdown */
1579 if((thd->lex->sql_command == SQLCOM_SHUTDOWN) && (thd->get_stmt_da()->is_ok()))
1580 error= TRUE;
1581
1582 DBUG_PRINT("info",("query ready"));
1583 break;
1584 }
1585 case COM_FIELD_LIST: // This isn't actually needed
1586 {
1587 char *fields;
1588 /* Locked closure of all tables */
1589 TABLE_LIST table_list;
1590 LEX_STRING table_name;
1591 LEX_STRING db;
1592 push_deprecated_warn(thd, "COM_FIELD_LIST",
1593 "SHOW COLUMNS FROM statement");
1594 /*
1595 SHOW statements should not add the used tables to the list of tables
1596 used in a transaction.
1597 */
1598 MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint();
1599
1600 thd->status_var.com_stat[SQLCOM_SHOW_FIELDS]++;
1601 if (thd->copy_db_to(&db.str, &db.length))
1602 break;
1603 thd->convert_string(&table_name, system_charset_info,
1604 (char *) com_data->com_field_list.table_name,
1605 com_data->com_field_list.table_name_length,
1606 thd->charset());
1607 enum_ident_name_check ident_check_status=
1608 check_table_name(table_name.str, table_name.length, FALSE);
1609 if (ident_check_status == IDENT_NAME_WRONG)
1610 {
1611 /* this is OK due to convert_string() null-terminating the string */
1612 my_error(ER_WRONG_TABLE_NAME, MYF(0), table_name.str);
1613 break;
1614 }
1615 else if (ident_check_status == IDENT_NAME_TOO_LONG)
1616 {
1617 my_error(ER_TOO_LONG_IDENT, MYF(0), table_name.str);
1618 break;
1619 }
1620 mysql_reset_thd_for_next_command(thd);
1621 lex_start(thd);
1622 /* Must be before we init the table list. */
1623 if (lower_case_table_names)
1624 table_name.length= my_casedn_str(files_charset_info, table_name.str);
1625 table_list.init_one_table(db.str, db.length, table_name.str,
1626 table_name.length, table_name.str, TL_READ);
1627 /*
1628 Init TABLE_LIST members necessary when the undelrying
1629 table is view.
1630 */
1631 table_list.select_lex= thd->lex->select_lex;
1632 thd->lex->
1633 select_lex->table_list.link_in_list(&table_list,
1634 &table_list.next_local);
1635 thd->lex->add_to_query_tables(&table_list);
1636
1637 if (is_infoschema_db(table_list.db, table_list.db_length))
1638 {
1639 ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, table_list.alias);
1640 if (schema_table)
1641 table_list.schema_table= schema_table;
1642 }
1643
1644 if (!(fields=
1645 (char *) thd->memdup(com_data->com_field_list.query,
1646 com_data->com_field_list.query_length)))
1647 break;
1648 // Don't count end \0
1649 thd->set_query(fields, com_data->com_field_list.query_length - 1);
1650 query_logger.general_log_print(thd, command, "%s %s",
1651 table_list.table_name, fields);
1652
1653 if (open_temporary_tables(thd, &table_list))
1654 break;
1655
1656 if (check_table_access(thd, SELECT_ACL, &table_list,
1657 TRUE, UINT_MAX, FALSE))
1658 break;
1659 /*
1660 Turn on an optimization relevant if the underlying table
1661 is a view: do not fill derived tables.
1662 */
1663 thd->lex->sql_command= SQLCOM_SHOW_FIELDS;
1664
1665 // See comment in opt_trace_disable_if_no_security_context_access()
1666 Opt_trace_start ots(thd, &table_list, thd->lex->sql_command, NULL,
1667 NULL, 0, NULL, NULL);
1668
1669 mysqld_list_fields(thd,&table_list,fields);
1670
1671 thd->lex->unit->cleanup(true);
1672 /* No need to rollback statement transaction, it's not started. */
1673 assert(thd->get_transaction()->is_empty(Transaction_ctx::STMT));
1674 close_thread_tables(thd);
1675 thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
1676
1677 if (thd->transaction_rollback_request)
1678 {
1679 /*
1680 Transaction rollback was requested since MDL deadlock was
1681 discovered while trying to open tables. Rollback transaction
1682 in all storage engines including binary log and release all
1683 locks.
1684 */
1685 trans_rollback_implicit(thd);
1686 thd->mdl_context.release_transactional_locks();
1687 }
1688
1689 thd->cleanup_after_query();
1690 break;
1691 }
1692 case COM_QUIT:
1693 /* We don't calculate statistics for this command */
1694 query_logger.general_log_print(thd, command, NullS);
1695 // Don't give 'abort' message
1696 // TODO: access of protocol_classic should be removed
1697 if (thd->is_classic_protocol())
1698 thd->get_protocol_classic()->get_net()->error= 0;
1699 thd->get_stmt_da()->disable_status(); // Don't send anything back
1700 error=TRUE; // End server
1701 break;
1702 #ifndef EMBEDDED_LIBRARY
1703 case COM_BINLOG_DUMP_GTID:
1704 // TODO: access of protocol_classic should be removed
1705 error=
1706 com_binlog_dump_gtid(thd,
1707 (char *)thd->get_protocol_classic()->get_raw_packet(),
1708 thd->get_protocol_classic()->get_packet_length());
1709 break;
1710 case COM_BINLOG_DUMP:
1711 // TODO: access of protocol_classic should be removed
1712 error=
1713 com_binlog_dump(thd,
1714 (char*)thd->get_protocol_classic()->get_raw_packet(),
1715 thd->get_protocol_classic()->get_packet_length());
1716 break;
1717 #endif
1718 case COM_REFRESH:
1719 {
1720 int not_used;
1721 push_deprecated_warn(thd, "COM_REFRESH", "FLUSH statement");
1722 /*
1723 Initialize thd->lex since it's used in many base functions, such as
1724 open_tables(). Otherwise, it remains uninitialized and may cause crash
1725 during execution of COM_REFRESH.
1726 */
1727 lex_start(thd);
1728
1729 thd->status_var.com_stat[SQLCOM_FLUSH]++;
1730 ulong options= (ulong) com_data->com_refresh.options;
1731 if (trans_commit_implicit(thd))
1732 break;
1733 thd->mdl_context.release_transactional_locks();
1734 if (check_global_access(thd,RELOAD_ACL))
1735 break;
1736 query_logger.general_log_print(thd, command, NullS);
1737 #ifndef NDEBUG
1738 bool debug_simulate= FALSE;
1739 DBUG_EXECUTE_IF("simulate_detached_thread_refresh", debug_simulate= TRUE;);
1740 if (debug_simulate)
1741 {
1742 /*
1743 Simulate a reload without a attached thread session.
1744 Provides a environment similar to that of when the
1745 server receives a SIGHUP signal and reloads caches
1746 and flushes tables.
1747 */
1748 bool res;
1749 my_thread_set_THR_THD(NULL);
1750 res= reload_acl_and_cache(NULL, options | REFRESH_FAST,
1751 NULL, ¬_used);
1752 my_thread_set_THR_THD(thd);
1753 if (res)
1754 break;
1755 }
1756 else
1757 #endif
1758 if (reload_acl_and_cache(thd, options, (TABLE_LIST*) 0, ¬_used))
1759 break;
1760 if (trans_commit_implicit(thd))
1761 break;
1762 close_thread_tables(thd);
1763 thd->mdl_context.release_transactional_locks();
1764 my_ok(thd);
1765 break;
1766 }
1767 #ifndef EMBEDDED_LIBRARY
1768 case COM_SHUTDOWN:
1769 {
1770 thd->status_var.com_other++;
1771 /*
1772 If the client is < 4.1.3, it is going to send us no argument; then
1773 packet_length is 0, packet[0] is the end 0 of the packet. Note that
1774 SHUTDOWN_DEFAULT is 0. If client is >= 4.1.3, the shutdown level is in
1775 packet[0].
1776 */
1777 enum mysql_enum_shutdown_level level;
1778 if (!thd->is_valid_time())
1779 level= SHUTDOWN_DEFAULT;
1780 else
1781 level= com_data->com_shutdown.level;
1782 if(!shutdown(thd, level, command))
1783 break;
1784 error= TRUE;
1785 break;
1786 }
1787 #endif
1788 case COM_STATISTICS:
1789 {
1790 STATUS_VAR current_global_status_var;
1791 ulong uptime;
1792 size_t length MY_ATTRIBUTE((unused));
1793 ulonglong queries_per_second1000;
1794 char buff[250];
1795 size_t buff_len= sizeof(buff);
1796
1797 query_logger.general_log_print(thd, command, NullS);
1798 thd->status_var.com_stat[SQLCOM_SHOW_STATUS]++;
1799 mysql_mutex_lock(&LOCK_status);
1800 calc_sum_of_all_status(¤t_global_status_var);
1801 mysql_mutex_unlock(&LOCK_status);
1802 if (!(uptime= (ulong) (thd->start_time.tv_sec - server_start_time)))
1803 queries_per_second1000= 0;
1804 else
1805 queries_per_second1000= thd->query_id * 1000LL / uptime;
1806
1807 length= my_snprintf(buff, buff_len - 1,
1808 "Uptime: %lu Threads: %d Questions: %lu "
1809 "Slow queries: %llu Opens: %llu Flush tables: %lu "
1810 "Open tables: %u Queries per second avg: %u.%03u",
1811 uptime,
1812 (int) thd_manager->get_thd_count(), (ulong) thd->query_id,
1813 current_global_status_var.long_query_count,
1814 current_global_status_var.opened_tables,
1815 refresh_version,
1816 table_cache_manager.cached_tables(),
1817 (uint) (queries_per_second1000 / 1000),
1818 (uint) (queries_per_second1000 % 1000));
1819 #ifdef EMBEDDED_LIBRARY
1820 /* Store the buffer in permanent memory */
1821 my_ok(thd, 0, 0, buff);
1822 #else
1823 // TODO: access of protocol_classic should be removed.
1824 // should be rewritten using store functions
1825 thd->get_protocol_classic()->write((uchar*) buff, length);
1826 thd->get_protocol_classic()->flush_net();
1827 thd->get_stmt_da()->disable_status();
1828 #endif
1829 break;
1830 }
1831 case COM_PING:
1832 thd->status_var.com_other++;
1833 my_ok(thd); // Tell client we are alive
1834 break;
1835 case COM_PROCESS_INFO:
1836 thd->status_var.com_stat[SQLCOM_SHOW_PROCESSLIST]++;
1837 push_deprecated_warn(thd, "COM_PROCESS_INFO",
1838 "SHOW PROCESSLIST statement");
1839 if (!thd->security_context()->priv_user().str[0] &&
1840 check_global_access(thd, PROCESS_ACL))
1841 break;
1842 query_logger.general_log_print(thd, command, NullS);
1843 mysqld_list_processes(
1844 thd,
1845 thd->security_context()->check_access(PROCESS_ACL) ?
1846 NullS : thd->security_context()->priv_user().str, 0);
1847 break;
1848 case COM_PROCESS_KILL:
1849 {
1850 push_deprecated_warn(thd, "COM_PROCESS_KILL",
1851 "KILL CONNECTION/QUERY statement");
1852 if (thd_manager->get_thread_id() & (~0xfffffffful))
1853 my_error(ER_DATA_OUT_OF_RANGE, MYF(0), "thread_id", "mysql_kill()");
1854 else
1855 {
1856 thd->status_var.com_stat[SQLCOM_KILL]++;
1857 sql_kill(thd, com_data->com_kill.id, false);
1858 }
1859 break;
1860 }
1861 case COM_SET_OPTION:
1862 {
1863 thd->status_var.com_stat[SQLCOM_SET_OPTION]++;
1864
1865 switch (com_data->com_set_option.opt_command) {
1866 case (int) MYSQL_OPTION_MULTI_STATEMENTS_ON:
1867 //TODO: access of protocol_classic should be removed
1868 thd->get_protocol_classic()->add_client_capability(
1869 CLIENT_MULTI_STATEMENTS);
1870 my_eof(thd);
1871 break;
1872 case (int) MYSQL_OPTION_MULTI_STATEMENTS_OFF:
1873 thd->get_protocol_classic()->remove_client_capability(
1874 CLIENT_MULTI_STATEMENTS);
1875 my_eof(thd);
1876 break;
1877 default:
1878 my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
1879 break;
1880 }
1881 break;
1882 }
1883 case COM_DEBUG:
1884 thd->status_var.com_other++;
1885 if (check_global_access(thd, SUPER_ACL))
1886 break; /* purecov: inspected */
1887 mysql_print_status();
1888 query_logger.general_log_print(thd, command, NullS);
1889 my_eof(thd);
1890 break;
1891 case COM_SLEEP:
1892 case COM_CONNECT: // Impossible here
1893 case COM_TIME: // Impossible from client
1894 case COM_DELAYED_INSERT: // INSERT DELAYED has been removed.
1895 case COM_END:
1896 default:
1897 my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
1898 break;
1899 }
1900
1901 done:
1902 assert(thd->derived_tables == NULL &&
1903 (thd->open_tables == NULL ||
1904 (thd->locked_tables_mode == LTM_LOCK_TABLES)));
1905
1906 /* Finalize server status flags after executing a command. */
1907 thd->update_server_status();
1908 if (thd->killed)
1909 thd->send_kill_message();
1910 thd->send_statement_status();
1911 thd->rpl_thd_ctx.session_gtids_ctx().notify_after_response_packet(thd);
1912 query_cache.end_of_result(thd);
1913
1914 #ifndef EMBEDDED_LIBRARY
1915 if (!thd->is_error() && !thd->killed_errno())
1916 mysql_audit_notify(thd,
1917 AUDIT_EVENT(MYSQL_AUDIT_GENERAL_RESULT), 0, NULL, 0);
1918
1919 mysql_audit_notify(thd, AUDIT_EVENT(MYSQL_AUDIT_GENERAL_STATUS),
1920 thd->get_stmt_da()->is_error() ?
1921 thd->get_stmt_da()->mysql_errno() : 0,
1922 command_name[command].str,
1923 command_name[command].length);
1924
1925 /* command_end is informational only. The plugin cannot abort
1926 execution of the command at thie point. */
1927 mysql_audit_notify(thd, AUDIT_EVENT(MYSQL_AUDIT_COMMAND_END), command,
1928 command_name[command].str);
1929 #endif
1930
1931 log_slow_statement(thd);
1932
1933 THD_STAGE_INFO(thd, stage_cleaning_up);
1934
1935 thd->reset_query();
1936 thd->set_command(COM_SLEEP);
1937 thd->proc_info= 0;
1938 thd->lex->sql_command= SQLCOM_END;
1939
1940 /* Performance Schema Interface instrumentation, end */
1941 MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
1942 thd->m_statement_psi= NULL;
1943 thd->m_digest= NULL;
1944 thd->reset_query_for_display();
1945
1946 /* Prevent rewritten query from getting "stuck" in SHOW PROCESSLIST. */
1947 thd->reset_rewritten_query();
1948
1949 thd_manager->dec_thread_running();
1950 free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
1951
1952 /* DTRACE instrumentation, end */
1953 if (MYSQL_QUERY_DONE_ENABLED() && command == COM_QUERY)
1954 {
1955 MYSQL_QUERY_DONE(thd->is_error());
1956 }
1957 if (MYSQL_COMMAND_DONE_ENABLED())
1958 {
1959 MYSQL_COMMAND_DONE(thd->is_error());
1960 }
1961
1962 /* SHOW PROFILE instrumentation, end */
1963 #if defined(ENABLED_PROFILING)
1964 thd->profiling.finish_current_query();
1965 #endif
1966
1967 DBUG_RETURN(error);
1968 }
1969
1970 /**
1971 Shutdown the mysqld server.
1972
1973 @param thd Thread (session) context.
1974 @param level Shutdown level.
1975 @param command type of command to perform
1976
1977 @retval
1978 true success
1979 @retval
1980 false When user has insufficient privilege or unsupported shutdown level
1981
1982 */
1983 #ifndef EMBEDDED_LIBRARY
shutdown(THD * thd,enum mysql_enum_shutdown_level level,enum enum_server_command command)1984 bool shutdown(THD *thd, enum mysql_enum_shutdown_level level, enum enum_server_command command)
1985 {
1986 DBUG_ENTER("shutdown");
1987 bool res= FALSE;
1988 thd->lex->no_write_to_binlog= 1;
1989
1990 if (check_global_access(thd,SHUTDOWN_ACL))
1991 goto error; /* purecov: inspected */
1992
1993 if (level == SHUTDOWN_DEFAULT)
1994 level= SHUTDOWN_WAIT_ALL_BUFFERS; // soon default will be configurable
1995 else if (level != SHUTDOWN_WAIT_ALL_BUFFERS)
1996 {
1997 my_error(ER_NOT_SUPPORTED_YET, MYF(0), "this shutdown level");
1998 goto error;;
1999 }
2000
2001 if(command == COM_SHUTDOWN)
2002 my_eof(thd);
2003 else if(command == COM_QUERY)
2004 my_ok(thd);
2005 else
2006 {
2007 my_error(ER_NOT_SUPPORTED_YET, MYF(0), "shutdown from this server command");
2008 goto error;
2009 }
2010
2011 DBUG_PRINT("quit",("Got shutdown command for level %u", level));
2012 query_logger.general_log_print(thd, command, NullS);
2013 kill_mysql();
2014 res= TRUE;
2015
2016 error:
2017 DBUG_RETURN(res);
2018 }
2019 #endif
2020
2021 /**
2022 Create a TABLE_LIST object for an INFORMATION_SCHEMA table.
2023
2024 This function is used in the parser to convert a SHOW or DESCRIBE
2025 table_name command to a SELECT from INFORMATION_SCHEMA.
2026 It prepares a SELECT_LEX and a TABLE_LIST object to represent the
2027 given command as a SELECT parse tree.
2028
2029 @param thd thread handle
2030 @param lex current lex
2031 @param table_ident table alias if it's used
2032 @param schema_table_idx the type of the INFORMATION_SCHEMA table to be
2033 created
2034
2035 @note
2036 Due to the way this function works with memory and LEX it cannot
2037 be used outside the parser (parse tree transformations outside
2038 the parser break PS and SP).
2039
2040 @retval
2041 0 success
2042 @retval
2043 1 out of memory or SHOW commands are not allowed
2044 in this version of the server.
2045 */
2046
prepare_schema_table(THD * thd,LEX * lex,Table_ident * table_ident,enum enum_schema_tables schema_table_idx)2047 int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
2048 enum enum_schema_tables schema_table_idx)
2049 {
2050 SELECT_LEX *schema_select_lex= NULL;
2051 DBUG_ENTER("prepare_schema_table");
2052
2053 switch (schema_table_idx) {
2054 case SCH_SCHEMATA:
2055 break;
2056
2057 case SCH_TABLE_NAMES:
2058 case SCH_TABLES:
2059 case SCH_VIEWS:
2060 case SCH_TRIGGERS:
2061 case SCH_EVENTS:
2062 {
2063 LEX_STRING db;
2064 size_t dummy;
2065 if (lex->select_lex->db == NULL &&
2066 lex->copy_db_to(&lex->select_lex->db, &dummy))
2067 DBUG_RETURN(1);
2068 if ((schema_select_lex= lex->new_empty_query_block()) == NULL)
2069 DBUG_RETURN(1); /* purecov: inspected */
2070 db.str= schema_select_lex->db= lex->select_lex->db;
2071 schema_select_lex->table_list.first= NULL;
2072 db.length= strlen(db.str);
2073
2074 if (check_and_convert_db_name(&db, FALSE) != IDENT_NAME_OK)
2075 DBUG_RETURN(1);
2076 break;
2077 }
2078 case SCH_COLUMNS:
2079 case SCH_STATISTICS:
2080 {
2081 assert(table_ident);
2082 TABLE_LIST **query_tables_last= lex->query_tables_last;
2083 if ((schema_select_lex= lex->new_empty_query_block()) == NULL)
2084 DBUG_RETURN(1); /* purecov: inspected */
2085 if (!schema_select_lex->add_table_to_list(thd, table_ident, 0, 0, TL_READ,
2086 MDL_SHARED_READ))
2087 DBUG_RETURN(1);
2088 lex->query_tables_last= query_tables_last;
2089 break;
2090 }
2091 case SCH_PROFILES:
2092 /*
2093 Mark this current profiling record to be discarded. We don't
2094 wish to have SHOW commands show up in profiling.
2095 */
2096 #if defined(ENABLED_PROFILING)
2097 thd->profiling.discard_current_query();
2098 #endif
2099 break;
2100 case SCH_OPTIMIZER_TRACE:
2101 case SCH_OPEN_TABLES:
2102 case SCH_VARIABLES:
2103 case SCH_STATUS:
2104 case SCH_PROCEDURES:
2105 case SCH_CHARSETS:
2106 case SCH_ENGINES:
2107 case SCH_COLLATIONS:
2108 case SCH_COLLATION_CHARACTER_SET_APPLICABILITY:
2109 case SCH_USER_PRIVILEGES:
2110 case SCH_SCHEMA_PRIVILEGES:
2111 case SCH_TABLE_PRIVILEGES:
2112 case SCH_COLUMN_PRIVILEGES:
2113 case SCH_TABLE_CONSTRAINTS:
2114 case SCH_KEY_COLUMN_USAGE:
2115 default:
2116 break;
2117 }
2118
2119 SELECT_LEX *select_lex= lex->current_select();
2120 if (make_schema_select(thd, select_lex, schema_table_idx))
2121 {
2122 DBUG_RETURN(1);
2123 }
2124 TABLE_LIST *table_list= select_lex->table_list.first;
2125 table_list->schema_select_lex= schema_select_lex;
2126 table_list->schema_table_reformed= 1;
2127 DBUG_RETURN(0);
2128 }
2129
2130
2131 /**
2132 Read query from packet and store in thd->query.
2133 Used in COM_QUERY and COM_STMT_PREPARE.
2134
2135 Sets the following THD variables:
2136 - query
2137 - query_length
2138
2139 @retval
2140 FALSE ok
2141 @retval
2142 TRUE error; In this case thd->fatal_error is set
2143 */
2144
alloc_query(THD * thd,const char * packet,size_t packet_length)2145 bool alloc_query(THD *thd, const char *packet, size_t packet_length)
2146 {
2147 /* Remove garbage at start and end of query */
2148 while (packet_length > 0 && my_isspace(thd->charset(), packet[0]))
2149 {
2150 packet++;
2151 packet_length--;
2152 }
2153 const char *pos= packet + packet_length; // Point at end null
2154 while (packet_length > 0 &&
2155 (pos[-1] == ';' || my_isspace(thd->charset() ,pos[-1])))
2156 {
2157 pos--;
2158 packet_length--;
2159 }
2160
2161 char *query= static_cast<char*>(thd->alloc(packet_length + 1));
2162 if (!query)
2163 return TRUE;
2164 memcpy(query, packet, packet_length);
2165 query[packet_length]= '\0';
2166
2167 thd->set_query(query, packet_length);
2168
2169 /* Reclaim some memory */
2170 if(thd->get_protocol()->type() == Protocol::PROTOCOL_TEXT ||
2171 thd->get_protocol()->type() == Protocol::PROTOCOL_BINARY)
2172
2173 thd->convert_buffer.shrink(thd->variables.net_buffer_length);
2174
2175 return FALSE;
2176 }
2177
2178 static
sp_process_definer(THD * thd)2179 bool sp_process_definer(THD *thd)
2180 {
2181 DBUG_ENTER("sp_process_definer");
2182
2183 LEX *lex= thd->lex;
2184
2185 /*
2186 If the definer is not specified, this means that CREATE-statement missed
2187 DEFINER-clause. DEFINER-clause can be missed in two cases:
2188
2189 - The user submitted a statement w/o the clause. This is a normal
2190 case, we should assign CURRENT_USER as definer.
2191
2192 - Our slave received an updated from the master, that does not
2193 replicate definer for stored rountines. We should also assign
2194 CURRENT_USER as definer here, but also we should mark this routine
2195 as NON-SUID. This is essential for the sake of backward
2196 compatibility.
2197
2198 The problem is the slave thread is running under "special" user (@),
2199 that actually does not exist. In the older versions we do not fail
2200 execution of a stored routine if its definer does not exist and
2201 continue the execution under the authorization of the invoker
2202 (BUG#13198). And now if we try to switch to slave-current-user (@),
2203 we will fail.
2204
2205 Actually, this leads to the inconsistent state of master and
2206 slave (different definers, different SUID behaviour), but it seems,
2207 this is the best we can do.
2208 */
2209
2210 if (!lex->definer)
2211 {
2212 Prepared_stmt_arena_holder ps_arena_holder(thd);
2213
2214 lex->definer= create_default_definer(thd);
2215
2216 /* Error has been already reported. */
2217 if (lex->definer == NULL)
2218 DBUG_RETURN(TRUE);
2219
2220 if (thd->slave_thread && lex->sphead)
2221 lex->sphead->m_chistics->suid= SP_IS_NOT_SUID;
2222 }
2223 else
2224 {
2225 /*
2226 If the specified definer differs from the current user, we
2227 should check that the current user has SUPER privilege (in order
2228 to create a stored routine under another user one must have
2229 SUPER privilege).
2230 */
2231 if ((strcmp(lex->definer->user.str,
2232 thd->security_context()->priv_user().str) ||
2233 my_strcasecmp(system_charset_info, lex->definer->host.str,
2234 thd->security_context()->priv_host().str)) &&
2235 check_global_access(thd, SUPER_ACL))
2236 {
2237 my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
2238 DBUG_RETURN(TRUE);
2239 }
2240 }
2241
2242 /* Check that the specified definer exists. Emit a warning if not. */
2243
2244 #ifndef NO_EMBEDDED_ACCESS_CHECKS
2245 if (!is_acl_user(lex->definer->host.str, lex->definer->user.str))
2246 {
2247 push_warning_printf(thd,
2248 Sql_condition::SL_NOTE,
2249 ER_NO_SUCH_USER,
2250 ER(ER_NO_SUCH_USER),
2251 lex->definer->user.str,
2252 lex->definer->host.str);
2253 }
2254 #endif /* NO_EMBEDDED_ACCESS_CHECKS */
2255
2256 DBUG_RETURN(FALSE);
2257 }
2258
2259
2260 /**
2261 Auxiliary call that opens and locks tables for LOCK TABLES statement
2262 and initializes the list of locked tables.
2263
2264 @param thd Thread context.
2265 @param tables List of tables to be locked.
2266
2267 @return FALSE in case of success, TRUE in case of error.
2268 */
2269
lock_tables_open_and_lock_tables(THD * thd,TABLE_LIST * tables)2270 static bool lock_tables_open_and_lock_tables(THD *thd, TABLE_LIST *tables)
2271 {
2272 Lock_tables_prelocking_strategy lock_tables_prelocking_strategy;
2273 MDL_deadlock_and_lock_abort_error_handler deadlock_handler;
2274 MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint();
2275 uint counter;
2276 TABLE_LIST *table;
2277
2278 thd->in_lock_tables= 1;
2279
2280 retry:
2281
2282 if (open_tables(thd, &tables, &counter, 0, &lock_tables_prelocking_strategy))
2283 goto err;
2284
2285 deadlock_handler.init();
2286 thd->push_internal_handler(&deadlock_handler);
2287
2288 for (table= tables; table; table= table->next_global)
2289 {
2290 if (!table->is_placeholder())
2291 {
2292 if (table->table->s->tmp_table)
2293 {
2294 /*
2295 We allow to change temporary tables even if they were locked for read
2296 by LOCK TABLES. To avoid a discrepancy between lock acquired at LOCK
2297 TABLES time and by the statement which is later executed under LOCK
2298 TABLES we ensure that for temporary tables we always request a write
2299 lock (such discrepancy can cause problems for the storage engine).
2300 We don't set TABLE_LIST::lock_type in this case as this might result
2301 in extra warnings from THD::decide_logging_format() even though
2302 binary logging is totally irrelevant for LOCK TABLES.
2303 */
2304 table->table->reginfo.lock_type= TL_WRITE;
2305 }
2306 else if (table->lock_type == TL_READ &&
2307 ! table->prelocking_placeholder &&
2308 table->table->file->ha_table_flags() & HA_NO_READ_LOCAL_LOCK)
2309 {
2310 /*
2311 In case when LOCK TABLE ... READ LOCAL was issued for table with
2312 storage engine which doesn't support READ LOCAL option and doesn't
2313 use THR_LOCK locks we need to upgrade weak SR metadata lock acquired
2314 in open_tables() to stronger SRO metadata lock.
2315 This is not needed for tables used through stored routines or
2316 triggers as we always acquire SRO (or even stronger SNRW) metadata
2317 lock for them.
2318 */
2319 bool result= thd->mdl_context.upgrade_shared_lock(
2320 table->table->mdl_ticket,
2321 MDL_SHARED_READ_ONLY,
2322 thd->variables.lock_wait_timeout);
2323
2324 if (deadlock_handler.need_reopen())
2325 {
2326 /*
2327 Deadlock occurred during upgrade of metadata lock.
2328 Let us restart acquring and opening tables for LOCK TABLES.
2329 */
2330 thd->pop_internal_handler();
2331 close_tables_for_reopen(thd, &tables, mdl_savepoint);
2332 if (open_temporary_tables(thd, tables))
2333 goto err;
2334 goto retry;
2335 }
2336
2337 if (result)
2338 {
2339 thd->pop_internal_handler();
2340 goto err;
2341 }
2342 }
2343 }
2344 }
2345
2346 thd->pop_internal_handler();
2347
2348 if (lock_tables(thd, tables, counter, 0) ||
2349 thd->locked_tables_list.init_locked_tables(thd))
2350 goto err;
2351
2352 thd->in_lock_tables= 0;
2353
2354 return FALSE;
2355
2356 err:
2357 thd->in_lock_tables= 0;
2358
2359 trans_rollback_stmt(thd);
2360 /*
2361 Need to end the current transaction, so the storage engine (InnoDB)
2362 can free its locks if LOCK TABLES locked some tables before finding
2363 that it can't lock a table in its list
2364 */
2365 trans_rollback(thd);
2366 /* Close tables and release metadata locks. */
2367 close_thread_tables(thd);
2368 assert(!thd->locked_tables_mode);
2369 thd->mdl_context.release_transactional_locks();
2370 return TRUE;
2371 }
2372
2373
2374 /**
2375 This is a wrapper for MYSQL_BIN_LOG::gtid_end_transaction. For normal
2376 statements, the function gtid_end_transaction is called in the commit
2377 handler. However, if the statement is filtered out or not written to
2378 the binary log, the commit handler is not invoked. Therefore, this
2379 wrapper calls gtid_end_transaction in case the current statement is
2380 committing but was not written to the binary log.
2381 (The function gtid_end_transaction ensures that gtid-related
2382 end-of-transaction operations are performed; this includes
2383 generating an empty transaction and calling
2384 Gtid_state::update_gtids_impl.)
2385
2386 @param thd Thread (session) context.
2387 */
2388
binlog_gtid_end_transaction(THD * thd)2389 static inline void binlog_gtid_end_transaction(THD *thd)
2390 {
2391 DBUG_ENTER("binlog_gtid_end_transaction");
2392
2393 /*
2394 This performs end-of-transaction actions needed by GTIDs:
2395 in particular, it generates an empty transaction if
2396 needed (e.g., if the statement was filtered out).
2397
2398 It is executed at the end of an implicitly or explicitly
2399 committing statement.
2400
2401 In addition, it is executed after CREATE TEMPORARY TABLE
2402 or DROP TEMPORARY TABLE when they occur outside
2403 transactional context. When enforce_gtid_consistency is
2404 enabled, these statements cannot occur in transactional
2405 context, and then they behave exactly as implicitly
2406 committing: they are written to the binary log
2407 immediately, not wrapped in BEGIN/COMMIT, and cannot be
2408 rolled back. However, they do not count as implicitly
2409 committing according to stmt_causes_implicit_commit(), so
2410 we need to add special cases in the condition below. Hence
2411 the clauses for SQLCOM_CREATE_TABLE and SQLCOM_DROP_TABLE.
2412
2413 If enforce_gtid_consistency=off, CREATE TEMPORARY TABLE
2414 and DROP TEMPORARY TABLE can occur in the middle of a
2415 transaction. Then they do not behave as DDL; they are
2416 written to the binary log inside BEGIN/COMMIT.
2417
2418 (For base tables, SQLCOM_[CREATE|DROP]_TABLE match both
2419 the stmt_causes_implicit_commit(...) clause and the
2420 thd->lex->sql_command == SQLCOM_* clause; for temporary
2421 tables they match only thd->lex->sql_command == SQLCOM_*.)
2422 */
2423 if ((thd->lex->sql_command == SQLCOM_COMMIT ||
2424 (thd->slave_thread &&
2425 (thd->lex->sql_command == SQLCOM_XA_COMMIT ||
2426 thd->lex->sql_command == SQLCOM_XA_ROLLBACK)) ||
2427 stmt_causes_implicit_commit(thd, CF_IMPLICIT_COMMIT_END) ||
2428 ((thd->lex->sql_command == SQLCOM_CREATE_TABLE ||
2429 thd->lex->sql_command == SQLCOM_DROP_TABLE) &&
2430 !thd->in_multi_stmt_transaction_mode())))
2431 (void) mysql_bin_log.gtid_end_transaction(thd);
2432
2433 DBUG_VOID_RETURN;
2434 }
2435
2436
2437 /**
2438 Execute command saved in thd and lex->sql_command.
2439
2440 @param thd Thread handle
2441
2442 @todo
2443 - Invalidate the table in the query cache if something changed
2444 after unlocking when changes become visible.
2445 @todo: this is workaround. right way will be move invalidating in
2446 the unlock procedure.
2447 - TODO: use check_change_password()
2448
2449 @retval
2450 FALSE OK
2451 @retval
2452 TRUE Error
2453 */
2454
2455 int
mysql_execute_command(THD * thd,bool first_level)2456 mysql_execute_command(THD *thd, bool first_level)
2457 {
2458 int res= FALSE;
2459 LEX *const lex= thd->lex;
2460 /* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */
2461 SELECT_LEX *const select_lex= lex->select_lex;
2462 /* first table of first SELECT_LEX */
2463 TABLE_LIST *const first_table= select_lex->get_table_list();
2464 /* list of all tables in query */
2465 TABLE_LIST *all_tables;
2466 /* most outer SELECT_LEX_UNIT of query */
2467 SELECT_LEX_UNIT *const unit= lex->unit;
2468 // keep GTID violation state in order to roll it back on statement failure
2469 bool gtid_consistency_violation_state = thd->has_gtid_consistency_violation;
2470 assert(select_lex->master_unit() == unit);
2471 DBUG_ENTER("mysql_execute_command");
2472 /* EXPLAIN OTHER isn't explainable command, but can have describe flag. */
2473 assert(!lex->describe || is_explainable_query(lex->sql_command) ||
2474 lex->sql_command == SQLCOM_EXPLAIN_OTHER);
2475
2476 thd->work_part_info= 0;
2477
2478 assert(thd->get_transaction()->is_empty(Transaction_ctx::STMT) ||
2479 thd->in_sub_stmt);
2480 /*
2481 Each statement or replication event which might produce deadlock
2482 should handle transaction rollback on its own. So by the start of
2483 the next statement transaction rollback request should be fulfilled
2484 already.
2485 */
2486 assert(! thd->transaction_rollback_request || thd->in_sub_stmt);
2487 /*
2488 In many cases first table of main SELECT_LEX have special meaning =>
2489 check that it is first table in global list and relink it first in
2490 queries_tables list if it is necessary (we need such relinking only
2491 for queries with subqueries in select list, in this case tables of
2492 subqueries will go to global list first)
2493
2494 all_tables will differ from first_table only if most upper SELECT_LEX
2495 do not contain tables.
2496
2497 Because of above in place where should be at least one table in most
2498 outer SELECT_LEX we have following check:
2499 assert(first_table == all_tables);
2500 assert(first_table == all_tables && first_table != 0);
2501 */
2502 lex->first_lists_tables_same();
2503 /* should be assigned after making first tables same */
2504 all_tables= lex->query_tables;
2505 /* set context for commands which do not use setup_tables */
2506 select_lex->context.resolve_in_table_list_only(select_lex->get_table_list());
2507
2508 thd->get_stmt_da()->reset_diagnostics_area();
2509 if ((thd->lex->keep_diagnostics != DA_KEEP_PARSE_ERROR) &&
2510 (thd->lex->keep_diagnostics != DA_KEEP_DIAGNOSTICS))
2511 {
2512 /*
2513 No parse errors, and it's not a diagnostic statement:
2514 remove the sql conditions from the DA!
2515 For diagnostic statements we need to keep the conditions
2516 around so we can inspec them.
2517 */
2518 thd->get_stmt_da()->reset_condition_info(thd);
2519 }
2520
2521 #ifdef HAVE_REPLICATION
2522 if (unlikely(thd->slave_thread))
2523 {
2524 if (!check_database_filters(thd,
2525 thd->db().str,
2526 lex->sql_command))
2527 {
2528 binlog_gtid_end_transaction(thd);
2529 DBUG_RETURN(0);
2530 }
2531
2532 if (lex->sql_command == SQLCOM_DROP_TRIGGER)
2533 {
2534 /*
2535 When dropping a trigger, we need to load its table name
2536 before checking slave filter rules.
2537 */
2538 add_table_for_trigger(thd, lex->spname->m_db,
2539 lex->spname->m_name, true, &all_tables);
2540
2541 if (!all_tables)
2542 {
2543 /*
2544 If table name cannot be loaded,
2545 it means the trigger does not exists possibly because
2546 CREATE TRIGGER was previously skipped for this trigger
2547 according to slave filtering rules.
2548 Returning success without producing any errors in this case.
2549 */
2550 binlog_gtid_end_transaction(thd);
2551 DBUG_RETURN(0);
2552 }
2553
2554 // force searching in slave.cc:tables_ok()
2555 all_tables->updating= 1;
2556 }
2557
2558 /*
2559 For fix of BUG#37051, the master stores the table map for update
2560 in the Query_log_event, and the value is assigned to
2561 thd->variables.table_map_for_update before executing the update
2562 query.
2563
2564 If thd->variables.table_map_for_update is set, then we are
2565 replicating from a new master, we can use this value to apply
2566 filter rules without opening all the tables. However If
2567 thd->variables.table_map_for_update is not set, then we are
2568 replicating from an old master, so we just skip this and
2569 continue with the old method. And of course, the bug would still
2570 exist for old masters.
2571 */
2572 if (lex->sql_command == SQLCOM_UPDATE_MULTI &&
2573 thd->table_map_for_update)
2574 {
2575 table_map table_map_for_update= thd->table_map_for_update;
2576 uint nr= 0;
2577 TABLE_LIST *table;
2578 for (table=all_tables; table; table=table->next_global, nr++)
2579 {
2580 if (table_map_for_update & ((table_map)1 << nr))
2581 table->updating= TRUE;
2582 else
2583 table->updating= FALSE;
2584 }
2585
2586 if (all_tables_not_ok(thd, all_tables))
2587 {
2588 /* we warn the slave SQL thread */
2589 my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
2590 binlog_gtid_end_transaction(thd);
2591 DBUG_RETURN(0);
2592 }
2593
2594 for (table=all_tables; table; table=table->next_global)
2595 table->updating= TRUE;
2596 }
2597
2598 /*
2599 Check if statment should be skipped because of slave filtering
2600 rules
2601
2602 Exceptions are:
2603 - UPDATE MULTI: For this statement, we want to check the filtering
2604 rules later in the code
2605 - SET: we always execute it (Not that many SET commands exists in
2606 the binary log anyway -- only 4.1 masters write SET statements,
2607 in 5.0 there are no SET statements in the binary log)
2608 - DROP TEMPORARY TABLE IF EXISTS: we always execute it (otherwise we
2609 have stale files on slave caused by exclusion of one tmp table).
2610 */
2611 if (!(lex->sql_command == SQLCOM_UPDATE_MULTI) &&
2612 !(lex->sql_command == SQLCOM_SET_OPTION) &&
2613 !(lex->sql_command == SQLCOM_DROP_TABLE &&
2614 lex->drop_temporary && lex->drop_if_exists) &&
2615 all_tables_not_ok(thd, all_tables))
2616 {
2617 /* we warn the slave SQL thread */
2618 my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
2619 binlog_gtid_end_transaction(thd);
2620 DBUG_RETURN(0);
2621 }
2622 /*
2623 Execute deferred events first
2624 */
2625 if (slave_execute_deferred_events(thd))
2626 DBUG_RETURN(-1);
2627 }
2628 else
2629 {
2630 #endif /* HAVE_REPLICATION */
2631 /*
2632 When option readonly is set deny operations which change non-temporary
2633 tables. Except for the replication thread and the 'super' users.
2634 */
2635 if (deny_updates_if_read_only_option(thd, all_tables))
2636 {
2637 err_readonly(thd);
2638 DBUG_RETURN(-1);
2639 }
2640 #ifdef HAVE_REPLICATION
2641 } /* endif unlikely slave */
2642 #endif
2643
2644 thd->status_var.com_stat[lex->sql_command]++;
2645
2646 Opt_trace_start ots(thd, all_tables, lex->sql_command, &lex->var_list,
2647 thd->query().str, thd->query().length, NULL,
2648 thd->variables.character_set_client);
2649
2650 Opt_trace_object trace_command(&thd->opt_trace);
2651 Opt_trace_array trace_command_steps(&thd->opt_trace, "steps");
2652
2653 assert(thd->get_transaction()->cannot_safely_rollback(
2654 Transaction_ctx::STMT) == false);
2655
2656 switch (gtid_pre_statement_checks(thd))
2657 {
2658 case GTID_STATEMENT_EXECUTE:
2659 break;
2660 case GTID_STATEMENT_CANCEL:
2661 DBUG_RETURN(-1);
2662 case GTID_STATEMENT_SKIP:
2663 my_ok(thd);
2664 binlog_gtid_end_transaction(thd);
2665 DBUG_RETURN(0);
2666 }
2667
2668 /*
2669 End a active transaction so that this command will have it's
2670 own transaction and will also sync the binary log. If a DDL is
2671 not run in it's own transaction it may simply never appear on
2672 the slave in case the outside transaction rolls back.
2673 */
2674 if (stmt_causes_implicit_commit(thd, CF_IMPLICIT_COMMIT_BEGIN))
2675 {
2676 /*
2677 Note that this should never happen inside of stored functions
2678 or triggers as all such statements prohibited there.
2679 */
2680 assert(! thd->in_sub_stmt);
2681 /* Statement transaction still should not be started. */
2682 assert(thd->get_transaction()->is_empty(Transaction_ctx::STMT));
2683
2684 /*
2685 Implicit commit is not allowed with an active XA transaction.
2686 In this case we should not release metadata locks as the XA transaction
2687 will not be rolled back. Therefore we simply return here.
2688 */
2689 if (trans_check_state(thd))
2690 DBUG_RETURN(-1);
2691
2692 /* Commit the normal transaction if one is active. */
2693 if (trans_commit_implicit(thd))
2694 goto error;
2695 /* Release metadata locks acquired in this transaction. */
2696 thd->mdl_context.release_transactional_locks();
2697 }
2698
2699 DEBUG_SYNC(thd, "after_implicit_pre_commit");
2700
2701 if (gtid_pre_statement_post_implicit_commit_checks(thd))
2702 DBUG_RETURN(-1);
2703
2704 #ifndef EMBEDDED_LIBRARY
2705 if (mysql_audit_notify(thd, first_level ?
2706 MYSQL_AUDIT_QUERY_START :
2707 MYSQL_AUDIT_QUERY_NESTED_START,
2708 first_level ?
2709 "MYSQL_AUDIT_QUERY_START" :
2710 "MYSQL_AUDIT_QUERY_NESTED_START"))
2711 {
2712 DBUG_RETURN(1);
2713 }
2714 #endif /* !EMBEDDED_LIBRARY */
2715
2716 #ifndef NDEBUG
2717 if (lex->sql_command != SQLCOM_SET_OPTION)
2718 DEBUG_SYNC(thd,"before_execute_sql_command");
2719 #endif
2720
2721 /*
2722 Check if we are in a read-only transaction and we're trying to
2723 execute a statement which should always be disallowed in such cases.
2724
2725 Note that this check is done after any implicit commits.
2726 */
2727 if (thd->tx_read_only &&
2728 (sql_command_flags[lex->sql_command] & CF_DISALLOW_IN_RO_TRANS))
2729 {
2730 my_error(ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION, MYF(0));
2731 goto error;
2732 }
2733
2734 /*
2735 Close tables open by HANDLERs before executing DDL statement
2736 which is going to affect those tables.
2737
2738 This should happen before temporary tables are pre-opened as
2739 otherwise we will get errors about attempt to re-open tables
2740 if table to be changed is open through HANDLER.
2741
2742 Note that even although this is done before any privilege
2743 checks there is no security problem here as closing open
2744 HANDLER doesn't require any privileges anyway.
2745 */
2746 if (sql_command_flags[lex->sql_command] & CF_HA_CLOSE)
2747 mysql_ha_rm_tables(thd, all_tables);
2748
2749 /*
2750 Check that the command is allowed on the PROTOCOL_PLUGIN
2751 */
2752 if (thd->get_protocol()->type() == Protocol::PROTOCOL_PLUGIN &&
2753 !(sql_command_flags[lex->sql_command] & CF_ALLOW_PROTOCOL_PLUGIN))
2754 {
2755 my_error(ER_PLUGGABLE_PROTOCOL_COMMAND_NOT_SUPPORTED, MYF(0));
2756 goto error;
2757 }
2758
2759 /*
2760 Pre-open temporary tables to simplify privilege checking
2761 for statements which need this.
2762 */
2763 if (sql_command_flags[lex->sql_command] & CF_PREOPEN_TMP_TABLES)
2764 {
2765 if (open_temporary_tables(thd, all_tables))
2766 goto error;
2767 }
2768
2769 // Save original info for EXPLAIN FOR CONNECTION
2770 if (!thd->in_sub_stmt)
2771 thd->query_plan.set_query_plan(lex->sql_command, lex,
2772 !thd->stmt_arena->is_conventional());
2773
2774 switch (lex->sql_command) {
2775
2776 case SQLCOM_SHOW_STATUS:
2777 {
2778 system_status_var old_status_var= thd->status_var;
2779 thd->initial_status_var= &old_status_var;
2780
2781 if (!(res= select_precheck(thd, lex, all_tables, first_table)))
2782 res= execute_sqlcom_select(thd, all_tables);
2783
2784 /* Don't log SHOW STATUS commands to slow query log */
2785 thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED |
2786 SERVER_QUERY_NO_GOOD_INDEX_USED);
2787 /*
2788 restore status variables, as we don't want 'show status' to cause
2789 changes
2790 */
2791 mysql_mutex_lock(&LOCK_status);
2792 add_diff_to_status(&global_status_var, &thd->status_var,
2793 &old_status_var);
2794 thd->status_var= old_status_var;
2795 thd->initial_status_var= NULL;
2796 mysql_mutex_unlock(&LOCK_status);
2797 break;
2798 }
2799 case SQLCOM_SHOW_EVENTS:
2800 #ifdef EMBEDDED_LIBRARY
2801 my_error(ER_NOT_SUPPORTED_YET, MYF(0), "embedded server");
2802 break;
2803 #endif
2804 case SQLCOM_SHOW_STATUS_PROC:
2805 case SQLCOM_SHOW_STATUS_FUNC:
2806 case SQLCOM_SHOW_DATABASES:
2807 case SQLCOM_SHOW_TABLES:
2808 case SQLCOM_SHOW_TRIGGERS:
2809 case SQLCOM_SHOW_TABLE_STATUS:
2810 case SQLCOM_SHOW_OPEN_TABLES:
2811 case SQLCOM_SHOW_PLUGINS:
2812 case SQLCOM_SHOW_FIELDS:
2813 case SQLCOM_SHOW_KEYS:
2814 case SQLCOM_SHOW_VARIABLES:
2815 case SQLCOM_SHOW_CHARSETS:
2816 case SQLCOM_SHOW_COLLATIONS:
2817 case SQLCOM_SHOW_STORAGE_ENGINES:
2818 case SQLCOM_SHOW_PROFILE:
2819 case SQLCOM_SELECT:
2820 {
2821 DBUG_EXECUTE_IF("use_attachable_trx",
2822 thd->begin_attachable_ro_transaction(););
2823
2824 thd->clear_current_query_costs();
2825
2826 res= select_precheck(thd, lex, all_tables, first_table);
2827
2828 if (!res)
2829 res= execute_sqlcom_select(thd, all_tables);
2830
2831 thd->save_current_query_costs();
2832
2833 DBUG_EXECUTE_IF("use_attachable_trx",
2834 thd->end_attachable_transaction(););
2835
2836 break;
2837 }
2838 case SQLCOM_PREPARE:
2839 {
2840 mysql_sql_stmt_prepare(thd);
2841 break;
2842 }
2843 case SQLCOM_EXECUTE:
2844 {
2845 mysql_sql_stmt_execute(thd);
2846 break;
2847 }
2848 case SQLCOM_DEALLOCATE_PREPARE:
2849 {
2850 mysql_sql_stmt_close(thd);
2851 break;
2852 }
2853 case SQLCOM_DO:
2854 res= mysql_do(thd, lex);
2855 break;
2856
2857 case SQLCOM_EMPTY_QUERY:
2858 my_ok(thd);
2859 break;
2860
2861 case SQLCOM_HELP:
2862 res= mysqld_help(thd,lex->help_arg);
2863 break;
2864
2865 #ifndef EMBEDDED_LIBRARY
2866 case SQLCOM_PURGE:
2867 {
2868 if (check_global_access(thd, SUPER_ACL))
2869 goto error;
2870 /* PURGE MASTER LOGS TO 'file' */
2871 res = purge_master_logs(thd, lex->to_log);
2872 break;
2873 }
2874 case SQLCOM_PURGE_BEFORE:
2875 {
2876 Item *it;
2877
2878 if (check_global_access(thd, SUPER_ACL))
2879 goto error;
2880 /* PURGE MASTER LOGS BEFORE 'data' */
2881 it= lex->purge_value_list.head();
2882 if ((!it->fixed && it->fix_fields(lex->thd, &it)) ||
2883 it->check_cols(1))
2884 {
2885 my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE LOGS BEFORE");
2886 goto error;
2887 }
2888 it= new Item_func_unix_timestamp(it);
2889 /*
2890 it is OK only emulate fix_fieds, because we need only
2891 value of constant
2892 */
2893 it->quick_fix_field();
2894 time_t purge_time= static_cast<time_t>(it->val_int());
2895 if (thd->is_error())
2896 goto error;
2897 res = purge_master_logs_before_date(thd, purge_time);
2898 break;
2899 }
2900 #endif
2901 case SQLCOM_SHOW_WARNS:
2902 {
2903 res= mysqld_show_warnings(thd, (ulong)
2904 ((1L << (uint) Sql_condition::SL_NOTE) |
2905 (1L << (uint) Sql_condition::SL_WARNING) |
2906 (1L << (uint) Sql_condition::SL_ERROR)
2907 ));
2908 break;
2909 }
2910 case SQLCOM_SHOW_ERRORS:
2911 {
2912 res= mysqld_show_warnings(thd, (ulong)
2913 (1L << (uint) Sql_condition::SL_ERROR));
2914 break;
2915 }
2916 case SQLCOM_SHOW_PROFILES:
2917 {
2918 #if defined(ENABLED_PROFILING)
2919 thd->profiling.discard_current_query();
2920 res= thd->profiling.show_profiles();
2921 if (res)
2922 goto error;
2923 #else
2924 my_error(ER_FEATURE_DISABLED, MYF(0), "SHOW PROFILES", "enable-profiling");
2925 goto error;
2926 #endif
2927 break;
2928 }
2929
2930 #ifdef HAVE_REPLICATION
2931 case SQLCOM_SHOW_SLAVE_HOSTS:
2932 {
2933 if (check_global_access(thd, REPL_SLAVE_ACL))
2934 goto error;
2935 res= show_slave_hosts(thd);
2936 break;
2937 }
2938 case SQLCOM_SHOW_RELAYLOG_EVENTS:
2939 {
2940 if (check_global_access(thd, REPL_SLAVE_ACL))
2941 goto error;
2942 res = mysql_show_relaylog_events(thd);
2943 break;
2944 }
2945 case SQLCOM_SHOW_BINLOG_EVENTS:
2946 {
2947 if (check_global_access(thd, REPL_SLAVE_ACL))
2948 goto error;
2949 res = mysql_show_binlog_events(thd);
2950 break;
2951 }
2952 #endif
2953
2954 case SQLCOM_ASSIGN_TO_KEYCACHE:
2955 {
2956 assert(first_table == all_tables && first_table != 0);
2957 if (check_access(thd, INDEX_ACL, first_table->db,
2958 &first_table->grant.privilege,
2959 &first_table->grant.m_internal,
2960 0, 0))
2961 goto error;
2962 res= mysql_assign_to_keycache(thd, first_table, &lex->ident);
2963 break;
2964 }
2965 case SQLCOM_PRELOAD_KEYS:
2966 {
2967 assert(first_table == all_tables && first_table != 0);
2968 if (check_access(thd, INDEX_ACL, first_table->db,
2969 &first_table->grant.privilege,
2970 &first_table->grant.m_internal,
2971 0, 0))
2972 goto error;
2973 res = mysql_preload_keys(thd, first_table);
2974 break;
2975 }
2976 #ifdef HAVE_REPLICATION
2977 case SQLCOM_CHANGE_MASTER:
2978 {
2979
2980 if (check_global_access(thd, SUPER_ACL))
2981 goto error;
2982 res= change_master_cmd(thd);
2983 break;
2984 }
2985 case SQLCOM_SHOW_SLAVE_STAT:
2986 {
2987 /* Accept one of two privileges */
2988 if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL))
2989 goto error;
2990 res= show_slave_status_cmd(thd);
2991 break;
2992 }
2993 case SQLCOM_SHOW_MASTER_STAT:
2994 {
2995 /* Accept one of two privileges */
2996 if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL))
2997 goto error;
2998 res = show_master_status(thd);
2999 break;
3000 }
3001
3002 #endif /* HAVE_REPLICATION */
3003 case SQLCOM_SHOW_ENGINE_STATUS:
3004 {
3005 if (check_global_access(thd, PROCESS_ACL))
3006 goto error;
3007 res = ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_STATUS);
3008 break;
3009 }
3010 case SQLCOM_SHOW_ENGINE_MUTEX:
3011 {
3012 if (check_global_access(thd, PROCESS_ACL))
3013 goto error;
3014 res = ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_MUTEX);
3015 break;
3016 }
3017 case SQLCOM_CREATE_TABLE:
3018 {
3019 assert(first_table == all_tables && first_table != 0);
3020 bool link_to_local;
3021 TABLE_LIST *create_table= first_table;
3022 TABLE_LIST *select_tables= lex->create_last_non_select_table->next_global;
3023
3024 /*
3025 Code below (especially in mysql_create_table() and Query_result_create
3026 methods) may modify HA_CREATE_INFO structure in LEX, so we have to
3027 use a copy of this structure to make execution prepared statement-
3028 safe. A shallow copy is enough as this code won't modify any memory
3029 referenced from this structure.
3030 */
3031 HA_CREATE_INFO create_info(lex->create_info);
3032 /*
3033 We need to copy alter_info for the same reasons of re-execution
3034 safety, only in case of Alter_info we have to do (almost) a deep
3035 copy.
3036 */
3037 Alter_info alter_info(lex->alter_info, thd->mem_root);
3038 if (thd->is_fatal_error)
3039 {
3040 /* If out of memory when creating a copy of alter_info. */
3041 res= 1;
3042 goto end_with_restore_list;
3043 }
3044
3045 if (((lex->create_info.used_fields & HA_CREATE_USED_DATADIR) != 0 ||
3046 (lex->create_info.used_fields & HA_CREATE_USED_INDEXDIR) != 0) &&
3047 check_access(thd, FILE_ACL, any_db, NULL, NULL, FALSE, FALSE))
3048 {
3049 res= 1;
3050 my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "FILE");
3051 goto end_with_restore_list;
3052 }
3053
3054 if ((res= create_table_precheck(thd, select_tables, create_table)))
3055 goto end_with_restore_list;
3056
3057 /* Might have been updated in create_table_precheck */
3058 create_info.alias= create_table->alias;
3059
3060 /*
3061 Assign target tablespace name to enable locking in lock_table_names().
3062 Reject invalid names.
3063 */
3064 if (create_info.tablespace)
3065 {
3066 if (check_tablespace_name(create_info.tablespace) != IDENT_NAME_OK)
3067 goto end_with_restore_list;
3068
3069 if (!thd->make_lex_string(&create_table->target_tablespace_name,
3070 create_info.tablespace,
3071 strlen(create_info.tablespace), false))
3072 {
3073 my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
3074 goto end_with_restore_list;
3075 }
3076 }
3077
3078 // Reject invalid tablespace names specified for partitions.
3079 if (check_partition_tablespace_names(thd->lex->part_info))
3080 goto end_with_restore_list;
3081
3082 /* Fix names if symlinked or relocated tables */
3083 if (append_file_to_dir(thd, &create_info.data_file_name,
3084 create_table->table_name) ||
3085 append_file_to_dir(thd, &create_info.index_file_name,
3086 create_table->table_name))
3087 goto end_with_restore_list;
3088
3089 /*
3090 If no engine type was given, work out the default now
3091 rather than at parse-time.
3092 */
3093 if (!(create_info.used_fields & HA_CREATE_USED_ENGINE))
3094 create_info.db_type= create_info.options & HA_LEX_CREATE_TMP_TABLE ?
3095 ha_default_temp_handlerton(thd) : ha_default_handlerton(thd);
3096 /*
3097 If we are using SET CHARSET without DEFAULT, add an implicit
3098 DEFAULT to not confuse old users. (This may change).
3099 */
3100 if ((create_info.used_fields &
3101 (HA_CREATE_USED_DEFAULT_CHARSET | HA_CREATE_USED_CHARSET)) ==
3102 HA_CREATE_USED_CHARSET)
3103 {
3104 create_info.used_fields&= ~HA_CREATE_USED_CHARSET;
3105 create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
3106 create_info.default_table_charset= create_info.table_charset;
3107 create_info.table_charset= 0;
3108 }
3109
3110 {
3111 partition_info *part_info= thd->lex->part_info;
3112 if (part_info != NULL && has_external_data_or_index_dir(*part_info) &&
3113 check_access(thd, FILE_ACL, any_db, NULL, NULL, FALSE, FALSE))
3114 {
3115 res= -1;
3116 goto end_with_restore_list;
3117 }
3118 if (part_info && !(part_info= thd->lex->part_info->get_clone(true)))
3119 {
3120 res= -1;
3121 goto end_with_restore_list;
3122 }
3123 thd->work_part_info= part_info;
3124 }
3125
3126 if (select_lex->item_list.elements) // With select
3127 {
3128 Query_result *result;
3129
3130 /*
3131 CREATE TABLE...IGNORE/REPLACE SELECT... can be unsafe, unless
3132 ORDER BY PRIMARY KEY clause is used in SELECT statement. We therefore
3133 use row based logging if mixed or row based logging is available.
3134 TODO: Check if the order of the output of the select statement is
3135 deterministic. Waiting for BUG#42415
3136 */
3137 if(lex->is_ignore())
3138 lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_CREATE_IGNORE_SELECT);
3139
3140 if(lex->duplicates == DUP_REPLACE)
3141 lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_CREATE_REPLACE_SELECT);
3142
3143 /*
3144 If:
3145 a) we inside an SP and there was NAME_CONST substitution,
3146 b) binlogging is on (STMT mode),
3147 c) we log the SP as separate statements
3148 raise a warning, as it may cause problems
3149 (see 'NAME_CONST issues' in 'Binary Logging of Stored Programs')
3150 */
3151 if (thd->query_name_consts &&
3152 mysql_bin_log.is_open() &&
3153 thd->variables.binlog_format == BINLOG_FORMAT_STMT &&
3154 !mysql_bin_log.is_query_in_union(thd, thd->query_id))
3155 {
3156 List_iterator_fast<Item> it(select_lex->item_list);
3157 Item *item;
3158 uint splocal_refs= 0;
3159 /* Count SP local vars in the top-level SELECT list */
3160 while ((item= it++))
3161 {
3162 if (item->is_splocal())
3163 splocal_refs++;
3164 }
3165 /*
3166 If it differs from number of NAME_CONST substitution applied,
3167 we may have a SOME_FUNC(NAME_CONST()) in the SELECT list,
3168 that may cause a problem with binary log (see BUG#35383),
3169 raise a warning.
3170 */
3171 if (splocal_refs != thd->query_name_consts)
3172 push_warning(thd,
3173 Sql_condition::SL_WARNING,
3174 ER_UNKNOWN_ERROR,
3175 "Invoked routine ran a statement that may cause problems with "
3176 "binary log, see 'NAME_CONST issues' in 'Binary Logging of Stored Programs' "
3177 "section of the manual.");
3178 }
3179
3180 unit->set_limit(select_lex);
3181
3182 /*
3183 Disable non-empty MERGE tables with CREATE...SELECT. Too
3184 complicated. See Bug #26379. Empty MERGE tables are read-only
3185 and don't allow CREATE...SELECT anyway.
3186 */
3187 if (create_info.used_fields & HA_CREATE_USED_UNION)
3188 {
3189 my_error(ER_WRONG_OBJECT, MYF(0), create_table->db,
3190 create_table->table_name, "BASE TABLE");
3191 res= 1;
3192 goto end_with_restore_list;
3193 }
3194
3195 if (!(res= open_tables_for_query(thd, all_tables, 0)))
3196 {
3197 /* The table already exists */
3198 if (create_table->table || create_table->is_view())
3199 {
3200 if (create_info.options & HA_LEX_CREATE_IF_NOT_EXISTS)
3201 {
3202 push_warning_printf(thd, Sql_condition::SL_NOTE,
3203 ER_TABLE_EXISTS_ERROR,
3204 ER(ER_TABLE_EXISTS_ERROR),
3205 create_info.alias);
3206 my_ok(thd);
3207 }
3208 else
3209 {
3210 my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_info.alias);
3211 res= 1;
3212 }
3213 goto end_with_restore_list;
3214 }
3215
3216 /*
3217 Remove target table from main select and name resolution
3218 context. This can't be done earlier as it will break view merging in
3219 statements like "CREATE TABLE IF NOT EXISTS existing_view SELECT".
3220 */
3221 lex->unlink_first_table(&link_to_local);
3222
3223 /* Updating any other table is prohibited in CTS statement */
3224 for (TABLE_LIST *table= lex->query_tables; table;
3225 table= table->next_global)
3226 if (table->lock_type >= TL_WRITE_ALLOW_WRITE)
3227 {
3228 lex->link_first_table_back(create_table, link_to_local);
3229
3230 res= 1;
3231 my_error(ER_CANT_UPDATE_TABLE_IN_CREATE_TABLE_SELECT, MYF(0),
3232 table->table_name, create_info.alias);
3233 goto end_with_restore_list;
3234 }
3235
3236 /*
3237 Query_result_create is currently not re-execution friendly and
3238 needs to be created for every execution of a PS/SP.
3239 */
3240 if ((result= new Query_result_create(create_table,
3241 &create_info,
3242 &alter_info,
3243 select_lex->item_list,
3244 lex->duplicates,
3245 select_tables)))
3246 {
3247 Ignore_error_handler ignore_handler;
3248 Strict_error_handler strict_handler;
3249 if (thd->lex->is_ignore())
3250 thd->push_internal_handler(&ignore_handler);
3251 else if (thd->is_strict_mode())
3252 thd->push_internal_handler(&strict_handler);
3253
3254 /*
3255 CREATE from SELECT give its SELECT_LEX for SELECT,
3256 and item_list belong to SELECT
3257 */
3258 res= handle_query(thd, lex, result, SELECT_NO_UNLOCK, 0);
3259
3260 if (thd->lex->is_ignore() || thd->is_strict_mode())
3261 thd->pop_internal_handler();
3262
3263 delete result;
3264 }
3265
3266 lex->link_first_table_back(create_table, link_to_local);
3267 }
3268 }
3269 else
3270 {
3271 Strict_error_handler strict_handler;
3272 /* Push Strict_error_handler */
3273 if (!thd->lex->is_ignore() && thd->is_strict_mode())
3274 thd->push_internal_handler(&strict_handler);
3275
3276 Partition_in_shared_ts_error_handler partition_in_shared_ts_handler;
3277 thd->push_internal_handler(&partition_in_shared_ts_handler);
3278
3279 /* regular create */
3280 if (create_info.options & HA_LEX_CREATE_TABLE_LIKE)
3281 {
3282 /* CREATE TABLE ... LIKE ... */
3283 res= mysql_create_like_table(thd, create_table, select_tables,
3284 &create_info);
3285 }
3286 else
3287 {
3288 /* Regular CREATE TABLE */
3289 res= mysql_create_table(thd, create_table,
3290 &create_info, &alter_info);
3291 }
3292
3293 thd->pop_internal_handler();
3294
3295 /* Pop Strict_error_handler */
3296 if (!thd->lex->is_ignore() && thd->is_strict_mode())
3297 thd->pop_internal_handler();
3298 if (!res)
3299 {
3300 /* in case of create temp tables if @@session_track_state_change is
3301 ON then send session state notification in OK packet */
3302 if(create_info.options & HA_LEX_CREATE_TMP_TABLE &&
3303 thd->session_tracker.get_tracker(SESSION_STATE_CHANGE_TRACKER)->is_enabled())
3304 thd->session_tracker.get_tracker(SESSION_STATE_CHANGE_TRACKER)->mark_as_changed(thd, NULL);
3305 my_ok(thd);
3306 }
3307 }
3308
3309 end_with_restore_list:
3310 break;
3311 }
3312 case SQLCOM_CREATE_INDEX:
3313 /* Fall through */
3314 case SQLCOM_DROP_INDEX:
3315 /*
3316 CREATE INDEX and DROP INDEX are implemented by calling ALTER
3317 TABLE with proper arguments.
3318
3319 In the future ALTER TABLE will notice that the request is to
3320 only add indexes and create these one by one for the existing
3321 table without having to do a full rebuild.
3322 */
3323 {
3324 /* Prepare stack copies to be re-execution safe */
3325 HA_CREATE_INFO create_info;
3326 Alter_info alter_info(lex->alter_info, thd->mem_root);
3327
3328 if (thd->is_fatal_error) /* out of memory creating a copy of alter_info */
3329 goto error;
3330
3331 assert(first_table == all_tables && first_table != 0);
3332 if (check_one_table_access(thd, INDEX_ACL, all_tables))
3333 goto error; /* purecov: inspected */
3334 /*
3335 Currently CREATE INDEX or DROP INDEX cause a full table rebuild
3336 and thus classify as slow administrative statements just like
3337 ALTER TABLE.
3338 */
3339 thd->enable_slow_log= opt_log_slow_admin_statements;
3340
3341 create_info.db_type= 0;
3342 create_info.row_type= ROW_TYPE_NOT_USED;
3343 create_info.default_table_charset= thd->variables.collation_database;
3344
3345 /* Push Strict_error_handler */
3346 Strict_error_handler strict_handler;
3347 if (thd->is_strict_mode())
3348 thd->push_internal_handler(&strict_handler);
3349 assert(!select_lex->order_list.elements);
3350 res= mysql_alter_table(thd, first_table->db, first_table->table_name,
3351 &create_info, first_table, &alter_info);
3352 /* Pop Strict_error_handler */
3353 if (thd->is_strict_mode())
3354 thd->pop_internal_handler();
3355 break;
3356 }
3357 #ifdef HAVE_REPLICATION
3358 case SQLCOM_START_GROUP_REPLICATION:
3359 {
3360 if (check_global_access(thd, SUPER_ACL))
3361 goto error;
3362
3363 /*
3364 If the client thread has locked tables, a deadlock is possible.
3365 Assume that
3366 - the client thread does LOCK TABLE t READ.
3367 - then the client thread does START GROUP_REPLICATION.
3368 -try to make the server in super ready only mode
3369 -acquire MDL lock ownership which will be waiting for
3370 LOCK on table t to be released.
3371 To prevent that, refuse START GROUP_REPLICATION if the
3372 client thread has locked tables
3373 */
3374 if (thd->locked_tables_mode ||
3375 thd->in_active_multi_stmt_transaction() || thd->in_sub_stmt)
3376 {
3377 my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
3378 ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
3379 goto error;
3380 }
3381
3382 res= group_replication_start();
3383
3384 //To reduce server dependency, server errors are not used here
3385 switch (res)
3386 {
3387 case 1: //GROUP_REPLICATION_CONFIGURATION_ERROR
3388 my_message(ER_GROUP_REPLICATION_CONFIGURATION,
3389 ER(ER_GROUP_REPLICATION_CONFIGURATION), MYF(0));
3390 goto error;
3391 case 2: //GROUP_REPLICATION_ALREADY_RUNNING
3392 my_message(ER_GROUP_REPLICATION_RUNNING,
3393 ER(ER_GROUP_REPLICATION_RUNNING), MYF(0));
3394 goto error;
3395 case 3: //GROUP_REPLICATION_REPLICATION_APPLIER_INIT_ERROR
3396 my_message(ER_GROUP_REPLICATION_APPLIER_INIT_ERROR,
3397 ER(ER_GROUP_REPLICATION_APPLIER_INIT_ERROR), MYF(0));
3398 goto error;
3399 case 4: //GROUP_REPLICATION_COMMUNICATION_LAYER_SESSION_ERROR
3400 my_message(ER_GROUP_REPLICATION_COMMUNICATION_LAYER_SESSION_ERROR,
3401 ER(ER_GROUP_REPLICATION_COMMUNICATION_LAYER_SESSION_ERROR), MYF(0));
3402 goto error;
3403 case 5: //GROUP_REPLICATION_COMMUNICATION_LAYER_JOIN_ERROR
3404 my_message(ER_GROUP_REPLICATION_COMMUNICATION_LAYER_JOIN_ERROR,
3405 ER(ER_GROUP_REPLICATION_COMMUNICATION_LAYER_JOIN_ERROR), MYF(0));
3406 goto error;
3407 case 7: //GROUP_REPLICATION_MAX_GROUP_SIZE
3408 my_message(ER_GROUP_REPLICATION_MAX_GROUP_SIZE,
3409 ER(ER_GROUP_REPLICATION_MAX_GROUP_SIZE), MYF(0));
3410 goto error;
3411 }
3412 my_ok(thd);
3413 res= 0;
3414 break;
3415 }
3416
3417 case SQLCOM_STOP_GROUP_REPLICATION:
3418 {
3419 if (check_global_access(thd, SUPER_ACL))
3420 goto error;
3421
3422 /*
3423 Please see explanation @SQLCOM_SLAVE_STOP case
3424 to know the reason for thd->locked_tables_mode in
3425 the below if condition.
3426 */
3427 if (thd->locked_tables_mode ||
3428 thd->in_active_multi_stmt_transaction() || thd->in_sub_stmt)
3429 {
3430 my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
3431 ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
3432 goto error;
3433 }
3434
3435 res= group_replication_stop();
3436 if (res == 1) //GROUP_REPLICATION_CONFIGURATION_ERROR
3437 {
3438 my_message(ER_GROUP_REPLICATION_CONFIGURATION,
3439 ER(ER_GROUP_REPLICATION_CONFIGURATION), MYF(0));
3440 goto error;
3441 }
3442 if (res == 6) //GROUP_REPLICATION_APPLIER_THREAD_TIMEOUT
3443 {
3444 my_message(ER_GROUP_REPLICATION_STOP_APPLIER_THREAD_TIMEOUT,
3445 ER(ER_GROUP_REPLICATION_STOP_APPLIER_THREAD_TIMEOUT), MYF(0));
3446 goto error;
3447 }
3448 my_ok(thd);
3449 res= 0;
3450 break;
3451 }
3452
3453 case SQLCOM_SLAVE_START:
3454 {
3455 res= start_slave_cmd(thd);
3456 break;
3457 }
3458 case SQLCOM_SLAVE_STOP:
3459 {
3460 /*
3461 If the client thread has locked tables, a deadlock is possible.
3462 Assume that
3463 - the client thread does LOCK TABLE t READ.
3464 - then the master updates t.
3465 - then the SQL slave thread wants to update t,
3466 so it waits for the client thread because t is locked by it.
3467 - then the client thread does SLAVE STOP.
3468 SLAVE STOP waits for the SQL slave thread to terminate its
3469 update t, which waits for the client thread because t is locked by it.
3470 To prevent that, refuse SLAVE STOP if the
3471 client thread has locked tables
3472 */
3473 if (thd->locked_tables_mode ||
3474 thd->in_active_multi_stmt_transaction() || thd->global_read_lock.is_acquired())
3475 {
3476 my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
3477 ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
3478 goto error;
3479 }
3480
3481 res= stop_slave_cmd(thd);
3482 break;
3483 }
3484 #endif /* HAVE_REPLICATION */
3485
3486 case SQLCOM_RENAME_TABLE:
3487 {
3488 assert(first_table == all_tables && first_table != 0);
3489 TABLE_LIST *table;
3490 for (table= first_table; table; table= table->next_local->next_local)
3491 {
3492 if (check_access(thd, ALTER_ACL | DROP_ACL, table->db,
3493 &table->grant.privilege,
3494 &table->grant.m_internal,
3495 0, 0) ||
3496 check_access(thd, INSERT_ACL | CREATE_ACL, table->next_local->db,
3497 &table->next_local->grant.privilege,
3498 &table->next_local->grant.m_internal,
3499 0, 0))
3500 goto error;
3501 TABLE_LIST old_list, new_list;
3502 /*
3503 we do not need initialize old_list and new_list because we will
3504 come table[0] and table->next[0] there
3505 */
3506 old_list= table[0];
3507 new_list= table->next_local[0];
3508 if (check_grant(thd, ALTER_ACL | DROP_ACL, &old_list, FALSE, 1, FALSE) ||
3509 (!test_all_bits(table->next_local->grant.privilege,
3510 INSERT_ACL | CREATE_ACL) &&
3511 check_grant(thd, INSERT_ACL | CREATE_ACL, &new_list, FALSE, 1,
3512 FALSE)))
3513 goto error;
3514 }
3515
3516 if (mysql_rename_tables(thd, first_table, 0))
3517 goto error;
3518 break;
3519 }
3520 #ifndef EMBEDDED_LIBRARY
3521 case SQLCOM_SHOW_BINLOGS:
3522 {
3523 if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL))
3524 goto error;
3525 res = show_binlogs(thd);
3526 break;
3527 }
3528 #endif /* EMBEDDED_LIBRARY */
3529 case SQLCOM_SHOW_CREATE:
3530 assert(first_table == all_tables && first_table != 0);
3531 {
3532 /*
3533 Access check:
3534 SHOW CREATE TABLE require any privileges on the table level (ie
3535 effecting all columns in the table).
3536 SHOW CREATE VIEW require the SHOW_VIEW and SELECT ACLs on the table
3537 level.
3538 NOTE: SHOW_VIEW ACL is checked when the view is created.
3539 */
3540
3541 DBUG_PRINT("debug", ("lex->only_view: %d, table: %s.%s",
3542 lex->only_view,
3543 first_table->db, first_table->table_name));
3544 if (lex->only_view)
3545 {
3546 if (check_table_access(thd, SELECT_ACL, first_table, FALSE, 1, FALSE))
3547 {
3548 DBUG_PRINT("debug", ("check_table_access failed"));
3549 my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
3550 "SHOW", thd->security_context()->priv_user().str,
3551 thd->security_context()->host_or_ip().str,
3552 first_table->alias);
3553 goto error;
3554 }
3555 DBUG_PRINT("debug", ("check_table_access succeeded"));
3556
3557 /* Ignore temporary tables if this is "SHOW CREATE VIEW" */
3558 first_table->open_type= OT_BASE_ONLY;
3559
3560 }
3561 else
3562 {
3563 /*
3564 Temporary tables should be opened for SHOW CREATE TABLE, but not
3565 for SHOW CREATE VIEW.
3566 */
3567 if (open_temporary_tables(thd, all_tables))
3568 goto error;
3569
3570 /*
3571 The fact that check_some_access() returned FALSE does not mean that
3572 access is granted. We need to check if first_table->grant.privilege
3573 contains any table-specific privilege.
3574 */
3575 DBUG_PRINT("debug", ("first_table->grant.privilege: %lx",
3576 first_table->grant.privilege));
3577 if (check_some_access(thd, SHOW_CREATE_TABLE_ACLS, first_table) ||
3578 (first_table->grant.privilege & SHOW_CREATE_TABLE_ACLS) == 0)
3579 {
3580 my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
3581 "SHOW", thd->security_context()->priv_user().str,
3582 thd->security_context()->host_or_ip().str,
3583 first_table->alias);
3584 goto error;
3585 }
3586 }
3587
3588 /* Access is granted. Execute the command. */
3589 res= mysqld_show_create(thd, first_table);
3590 break;
3591 }
3592 case SQLCOM_CHECKSUM:
3593 {
3594 assert(first_table == all_tables && first_table != 0);
3595 if (check_table_access(thd, SELECT_ACL, all_tables,
3596 FALSE, UINT_MAX, FALSE))
3597 goto error; /* purecov: inspected */
3598
3599 res = mysql_checksum_table(thd, first_table, &lex->check_opt);
3600 break;
3601 }
3602 case SQLCOM_REPLACE:
3603 case SQLCOM_INSERT:
3604 case SQLCOM_REPLACE_SELECT:
3605 case SQLCOM_INSERT_SELECT:
3606 {
3607 assert(first_table == all_tables && first_table != 0);
3608 assert(lex->m_sql_cmd != NULL);
3609 res= lex->m_sql_cmd->execute(thd);
3610 break;
3611 }
3612 case SQLCOM_DELETE:
3613 case SQLCOM_DELETE_MULTI:
3614 case SQLCOM_UPDATE:
3615 case SQLCOM_UPDATE_MULTI:
3616 {
3617 assert(first_table == all_tables && first_table != 0);
3618 assert(lex->m_sql_cmd != NULL);
3619 res= lex->m_sql_cmd->execute(thd);
3620 break;
3621 }
3622 case SQLCOM_DROP_TABLE:
3623 {
3624 assert(first_table == all_tables && first_table != 0);
3625 if (!lex->drop_temporary)
3626 {
3627 if (check_table_access(thd, DROP_ACL, all_tables, FALSE, UINT_MAX, FALSE))
3628 goto error; /* purecov: inspected */
3629 }
3630 /* DDL and binlog write order are protected by metadata locks. */
3631 res= mysql_rm_table(thd, first_table, lex->drop_if_exists,
3632 lex->drop_temporary);
3633 /* when dropping temporary tables if @@session_track_state_change is ON then
3634 send the boolean tracker in the OK packet */
3635 if(!res && lex->drop_temporary)
3636 {
3637 if (thd->session_tracker.get_tracker(SESSION_STATE_CHANGE_TRACKER)->is_enabled())
3638 thd->session_tracker.get_tracker(SESSION_STATE_CHANGE_TRACKER)->mark_as_changed(thd, NULL);
3639 }
3640 }
3641 break;
3642 case SQLCOM_SHOW_PROCESSLIST:
3643 if (!thd->security_context()->priv_user().str[0] &&
3644 check_global_access(thd,PROCESS_ACL))
3645 break;
3646 mysqld_list_processes(
3647 thd,
3648 (thd->security_context()->check_access(PROCESS_ACL) ?
3649 NullS :
3650 thd->security_context()->priv_user().str),
3651 lex->verbose);
3652 break;
3653 case SQLCOM_SHOW_PRIVILEGES:
3654 res= mysqld_show_privileges(thd);
3655 break;
3656 case SQLCOM_SHOW_ENGINE_LOGS:
3657 {
3658 if (check_access(thd, FILE_ACL, any_db, NULL, NULL, 0, 0))
3659 goto error;
3660 res= ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_LOGS);
3661 break;
3662 }
3663 case SQLCOM_CHANGE_DB:
3664 {
3665 const LEX_CSTRING db_str= { select_lex->db,
3666 strlen(select_lex->db) };
3667
3668 if (!mysql_change_db(thd, db_str, FALSE))
3669 my_ok(thd);
3670
3671 break;
3672 }
3673
3674 case SQLCOM_LOAD:
3675 {
3676 assert(first_table == all_tables && first_table != 0);
3677 uint privilege= (lex->duplicates == DUP_REPLACE ?
3678 INSERT_ACL | DELETE_ACL : INSERT_ACL) |
3679 (lex->local_file ? 0 : FILE_ACL);
3680
3681 if (lex->local_file)
3682 {
3683 if (!thd->get_protocol()->has_client_capability(CLIENT_LOCAL_FILES) ||
3684 !opt_local_infile)
3685 {
3686 my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), MYF(0));
3687 goto error;
3688 }
3689 }
3690
3691 if (check_one_table_access(thd, privilege, all_tables))
3692 goto error;
3693
3694 /* Push strict / ignore error handler */
3695 Ignore_error_handler ignore_handler;
3696 Strict_error_handler strict_handler;
3697 if (thd->lex->is_ignore())
3698 thd->push_internal_handler(&ignore_handler);
3699 else if (thd->is_strict_mode())
3700 thd->push_internal_handler(&strict_handler);
3701
3702 res= mysql_load(thd, lex->exchange, first_table, lex->load_field_list,
3703 lex->load_update_list, lex->load_value_list, lex->duplicates,
3704 lex->local_file);
3705
3706 /* Pop ignore / strict error handler */
3707 if (thd->lex->is_ignore() || thd->is_strict_mode())
3708 thd->pop_internal_handler();
3709
3710 break;
3711 }
3712
3713 case SQLCOM_SET_OPTION:
3714 {
3715 List<set_var_base> *lex_var_list= &lex->var_list;
3716
3717 if ((check_table_access(thd, SELECT_ACL, all_tables, FALSE, UINT_MAX, FALSE)
3718 || open_and_lock_tables(thd, all_tables, 0)))
3719 goto error;
3720 if (!(res= sql_set_variables(thd, lex_var_list)))
3721 my_ok(thd);
3722 else
3723 {
3724 /*
3725 We encountered some sort of error, but no message was sent.
3726 Send something semi-generic here since we don't know which
3727 assignment in the list caused the error.
3728 */
3729 if (!thd->is_error())
3730 my_error(ER_WRONG_ARGUMENTS,MYF(0),"SET");
3731 goto error;
3732 }
3733
3734 break;
3735 }
3736
3737 case SQLCOM_UNLOCK_TABLES:
3738 /*
3739 It is critical for mysqldump --single-transaction --master-data that
3740 UNLOCK TABLES does not implicitely commit a connection which has only
3741 done FLUSH TABLES WITH READ LOCK + BEGIN. If this assumption becomes
3742 false, mysqldump will not work.
3743 */
3744 if (thd->variables.option_bits & OPTION_TABLE_LOCK)
3745 {
3746 /*
3747 Can we commit safely? If not, return to avoid releasing
3748 transactional metadata locks.
3749 */
3750 if (trans_check_state(thd))
3751 DBUG_RETURN(-1);
3752 res= trans_commit_implicit(thd);
3753 thd->locked_tables_list.unlock_locked_tables(thd);
3754 thd->mdl_context.release_transactional_locks();
3755 thd->variables.option_bits&= ~(OPTION_TABLE_LOCK);
3756 }
3757 if (thd->global_read_lock.is_acquired())
3758 thd->global_read_lock.unlock_global_read_lock(thd);
3759 if (res)
3760 goto error;
3761 my_ok(thd);
3762 break;
3763 case SQLCOM_LOCK_TABLES:
3764 /*
3765 Can we commit safely? If not, return to avoid releasing
3766 transactional metadata locks.
3767 */
3768 if (trans_check_state(thd))
3769 DBUG_RETURN(-1);
3770 /* We must end the transaction first, regardless of anything */
3771 res= trans_commit_implicit(thd);
3772 thd->locked_tables_list.unlock_locked_tables(thd);
3773 /* Release transactional metadata locks. */
3774 thd->mdl_context.release_transactional_locks();
3775 if (res)
3776 goto error;
3777
3778 /*
3779 Here we have to pre-open temporary tables for LOCK TABLES.
3780
3781 CF_PREOPEN_TMP_TABLES is not set for this SQL statement simply
3782 because LOCK TABLES calls close_thread_tables() as a first thing
3783 (it's called from unlock_locked_tables() above). So even if
3784 CF_PREOPEN_TMP_TABLES was set and the tables would be pre-opened
3785 in a usual way, they would have been closed.
3786 */
3787
3788 if (open_temporary_tables(thd, all_tables))
3789 goto error;
3790
3791 if (lock_tables_precheck(thd, all_tables))
3792 goto error;
3793
3794 thd->variables.option_bits|= OPTION_TABLE_LOCK;
3795
3796 res= lock_tables_open_and_lock_tables(thd, all_tables);
3797
3798 if (res)
3799 {
3800 thd->variables.option_bits&= ~(OPTION_TABLE_LOCK);
3801 }
3802 else
3803 {
3804 if (thd->variables.query_cache_wlock_invalidate)
3805 query_cache.invalidate_locked_for_write(first_table);
3806 my_ok(thd);
3807 }
3808 break;
3809 case SQLCOM_CREATE_DB:
3810 {
3811 /*
3812 As mysql_create_db() may modify HA_CREATE_INFO structure passed to
3813 it, we need to use a copy of LEX::create_info to make execution
3814 prepared statement- safe.
3815 */
3816 HA_CREATE_INFO create_info(lex->create_info);
3817 char *alias;
3818 if (!(alias=thd->strmake(lex->name.str, lex->name.length)) ||
3819 (check_and_convert_db_name(&lex->name, FALSE) != IDENT_NAME_OK))
3820 break;
3821 if (check_access(thd, CREATE_ACL, lex->name.str, NULL, NULL, 1, 0))
3822 break;
3823 res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias :
3824 lex->name.str), &create_info, 0);
3825 break;
3826 }
3827 case SQLCOM_DROP_DB:
3828 {
3829 if (check_and_convert_db_name(&lex->name, FALSE) != IDENT_NAME_OK)
3830 break;
3831 if (check_access(thd, DROP_ACL, lex->name.str, NULL, NULL, 1, 0))
3832 break;
3833 res= mysql_rm_db(thd, to_lex_cstring(lex->name), lex->drop_if_exists, 0);
3834 break;
3835 }
3836 case SQLCOM_ALTER_DB_UPGRADE:
3837 {
3838 LEX_STRING *db= & lex->name;
3839 if (check_and_convert_db_name(db, FALSE) != IDENT_NAME_OK)
3840 break;
3841 if (check_access(thd, ALTER_ACL, db->str, NULL, NULL, 1, 0) ||
3842 check_access(thd, DROP_ACL, db->str, NULL, NULL, 1, 0) ||
3843 check_access(thd, CREATE_ACL, db->str, NULL, NULL, 1, 0))
3844 {
3845 res= 1;
3846 break;
3847 }
3848 LEX_CSTRING db_name= {db->str, db->length};
3849 res= mysql_upgrade_db(thd, db_name);
3850 if (!res)
3851 my_ok(thd);
3852 break;
3853 }
3854 case SQLCOM_ALTER_DB:
3855 {
3856 LEX_STRING *db= &lex->name;
3857 HA_CREATE_INFO create_info(lex->create_info);
3858 if (check_and_convert_db_name(db, FALSE) != IDENT_NAME_OK)
3859 break;
3860 if (check_access(thd, ALTER_ACL, db->str, NULL, NULL, 1, 0))
3861 break;
3862 res= mysql_alter_db(thd, db->str, &create_info);
3863 break;
3864 }
3865 case SQLCOM_SHOW_CREATE_DB:
3866 {
3867 DBUG_EXECUTE_IF("4x_server_emul",
3868 my_error(ER_UNKNOWN_ERROR, MYF(0)); goto error;);
3869 if (check_and_convert_db_name(&lex->name, TRUE) != IDENT_NAME_OK)
3870 break;
3871 res= mysqld_show_create_db(thd, lex->name.str, &lex->create_info);
3872 break;
3873 }
3874 case SQLCOM_CREATE_EVENT:
3875 case SQLCOM_ALTER_EVENT:
3876 #ifndef EMBEDDED_LIBRARY
3877 do
3878 {
3879 assert(lex->event_parse_data);
3880 if (lex->table_or_sp_used())
3881 {
3882 my_error(ER_NOT_SUPPORTED_YET, MYF(0), "Usage of subqueries or stored "
3883 "function calls as part of this statement");
3884 break;
3885 }
3886
3887 res= sp_process_definer(thd);
3888 if (res)
3889 break;
3890
3891 switch (lex->sql_command) {
3892 case SQLCOM_CREATE_EVENT:
3893 {
3894 bool if_not_exists= (lex->create_info.options &
3895 HA_LEX_CREATE_IF_NOT_EXISTS);
3896 res= Events::create_event(thd, lex->event_parse_data, if_not_exists);
3897 break;
3898 }
3899 case SQLCOM_ALTER_EVENT:
3900 {
3901 LEX_STRING db_lex_str= NULL_STR;
3902 if (lex->spname)
3903 {
3904 db_lex_str.str= const_cast<char*>(lex->spname->m_db.str);
3905 db_lex_str.length= lex->spname->m_db.length;
3906 }
3907
3908 res= Events::update_event(thd, lex->event_parse_data,
3909 lex->spname ? &db_lex_str : NULL,
3910 lex->spname ? &lex->spname->m_name : NULL);
3911 break;
3912 }
3913 default:
3914 assert(0);
3915 }
3916 DBUG_PRINT("info",("DDL error code=%d", res));
3917 if (!res)
3918 my_ok(thd);
3919
3920 } while (0);
3921 /* Don't do it, if we are inside a SP */
3922 if (!thd->sp_runtime_ctx)
3923 {
3924 delete lex->sphead;
3925 lex->sphead= NULL;
3926 }
3927 /* lex->unit->cleanup() is called outside, no need to call it here */
3928 break;
3929 case SQLCOM_SHOW_CREATE_EVENT:
3930 {
3931 LEX_STRING db_lex_str= {const_cast<char*>(lex->spname->m_db.str),
3932 lex->spname->m_db.length};
3933 res= Events::show_create_event(thd, db_lex_str,
3934 lex->spname->m_name);
3935 break;
3936 }
3937 case SQLCOM_DROP_EVENT:
3938 {
3939 LEX_STRING db_lex_str= {const_cast<char*>(lex->spname->m_db.str),
3940 lex->spname->m_db.length};
3941 if (!(res= Events::drop_event(thd,
3942 db_lex_str, lex->spname->m_name,
3943 lex->drop_if_exists)))
3944 my_ok(thd);
3945 break;
3946 }
3947 #else
3948 my_error(ER_NOT_SUPPORTED_YET,MYF(0),"embedded server");
3949 break;
3950 #endif
3951 case SQLCOM_CREATE_FUNCTION: // UDF function
3952 {
3953 if (check_access(thd, INSERT_ACL, "mysql", NULL, NULL, 1, 0))
3954 break;
3955 #ifdef HAVE_DLOPEN
3956 if (!(res = mysql_create_function(thd, &lex->udf)))
3957 my_ok(thd);
3958 #else
3959 my_error(ER_CANT_OPEN_LIBRARY, MYF(0), lex->udf.dl, 0, "feature disabled");
3960 res= TRUE;
3961 #endif
3962 break;
3963 }
3964 #ifndef NO_EMBEDDED_ACCESS_CHECKS
3965 case SQLCOM_CREATE_USER:
3966 {
3967 if (check_access(thd, INSERT_ACL, "mysql", NULL, NULL, 1, 1) &&
3968 check_global_access(thd,CREATE_USER_ACL))
3969 break;
3970 /* Conditionally writes to binlog */
3971 HA_CREATE_INFO create_info(lex->create_info);
3972 if (!(res = mysql_create_user(thd, lex->users_list, create_info.options & HA_LEX_CREATE_IF_NOT_EXISTS)))
3973 my_ok(thd);
3974 break;
3975 }
3976 case SQLCOM_DROP_USER:
3977 {
3978 if (check_access(thd, DELETE_ACL, "mysql", NULL, NULL, 1, 1) &&
3979 check_global_access(thd,CREATE_USER_ACL))
3980 break;
3981 /* Conditionally writes to binlog */
3982 if (!(res = mysql_drop_user(thd, lex->users_list, lex->drop_if_exists)))
3983 my_ok(thd);
3984 break;
3985 }
3986 case SQLCOM_RENAME_USER:
3987 {
3988 if (check_access(thd, UPDATE_ACL, "mysql", NULL, NULL, 1, 1) &&
3989 check_global_access(thd,CREATE_USER_ACL))
3990 break;
3991 /* Conditionally writes to binlog */
3992 if (!(res= mysql_rename_user(thd, lex->users_list)))
3993 my_ok(thd);
3994 break;
3995 }
3996 case SQLCOM_REVOKE_ALL:
3997 {
3998 if (check_access(thd, UPDATE_ACL, "mysql", NULL, NULL, 1, 1) &&
3999 check_global_access(thd,CREATE_USER_ACL))
4000 break;
4001
4002 /* Replicate current user as grantor */
4003 thd->binlog_invoker();
4004
4005 /* Conditionally writes to binlog */
4006 if (!(res = mysql_revoke_all(thd, lex->users_list)))
4007 my_ok(thd);
4008 break;
4009 }
4010 case SQLCOM_REVOKE:
4011 case SQLCOM_GRANT:
4012 {
4013 if (lex->type != TYPE_ENUM_PROXY &&
4014 check_access(thd, lex->grant | lex->grant_tot_col | GRANT_ACL,
4015 first_table ? first_table->db : select_lex->db,
4016 first_table ? &first_table->grant.privilege : NULL,
4017 first_table ? &first_table->grant.m_internal : NULL,
4018 first_table ? 0 : 1, 0))
4019 goto error;
4020
4021 /* Replicate current user as grantor */
4022 thd->binlog_invoker();
4023
4024 if (thd->security_context()->user().str) // If not replication
4025 {
4026 LEX_USER *user, *tmp_user;
4027 bool first_user= TRUE;
4028
4029 List_iterator <LEX_USER> user_list(lex->users_list);
4030 while ((tmp_user= user_list++))
4031 {
4032 if (!(user= get_current_user(thd, tmp_user)))
4033 goto error;
4034 if (specialflag & SPECIAL_NO_RESOLVE &&
4035 hostname_requires_resolving(user->host.str))
4036 push_warning(thd, Sql_condition::SL_WARNING,
4037 ER_WARN_HOSTNAME_WONT_WORK,
4038 ER(ER_WARN_HOSTNAME_WONT_WORK));
4039 // Are we trying to change a password of another user
4040 assert(user->host.str != 0);
4041
4042 /*
4043 GRANT/REVOKE PROXY has the target user as a first entry in the list.
4044 */
4045 if (lex->type == TYPE_ENUM_PROXY && first_user)
4046 {
4047 first_user= FALSE;
4048 if (acl_check_proxy_grant_access (thd, user->host.str, user->user.str,
4049 lex->grant & GRANT_ACL))
4050 goto error;
4051 }
4052 else if (is_acl_user(user->host.str, user->user.str) &&
4053 user->auth.str &&
4054 check_change_password (thd, user->host.str, user->user.str,
4055 user->auth.str,
4056 user->auth.length))
4057 goto error;
4058 }
4059 }
4060 if (first_table)
4061 {
4062 if (lex->type == TYPE_ENUM_PROCEDURE ||
4063 lex->type == TYPE_ENUM_FUNCTION)
4064 {
4065 uint grants= lex->all_privileges
4066 ? (PROC_ACLS & ~GRANT_ACL) | (lex->grant & GRANT_ACL)
4067 : lex->grant;
4068 if (check_grant_routine(thd, grants | GRANT_ACL, all_tables,
4069 lex->type == TYPE_ENUM_PROCEDURE, 0))
4070 goto error;
4071 /* Conditionally writes to binlog */
4072 res= mysql_routine_grant(thd, all_tables,
4073 lex->type == TYPE_ENUM_PROCEDURE,
4074 lex->users_list, grants,
4075 lex->sql_command == SQLCOM_REVOKE, TRUE);
4076 if (!res)
4077 my_ok(thd);
4078 }
4079 else
4080 {
4081 if (check_grant(thd,(lex->grant | lex->grant_tot_col | GRANT_ACL),
4082 all_tables, FALSE, UINT_MAX, FALSE))
4083 goto error;
4084 /* Conditionally writes to binlog */
4085 res= mysql_table_grant(thd, all_tables, lex->users_list,
4086 lex->columns, lex->grant,
4087 lex->sql_command == SQLCOM_REVOKE);
4088 }
4089 }
4090 else
4091 {
4092 if (lex->columns.elements || (lex->type && lex->type != TYPE_ENUM_PROXY))
4093 {
4094 my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER(ER_ILLEGAL_GRANT_FOR_TABLE),
4095 MYF(0));
4096 goto error;
4097 }
4098 else
4099 {
4100 /* Conditionally writes to binlog */
4101 res = mysql_grant(thd, select_lex->db, lex->users_list, lex->grant,
4102 lex->sql_command == SQLCOM_REVOKE,
4103 lex->type == TYPE_ENUM_PROXY);
4104 }
4105 if (!res)
4106 {
4107 if (lex->sql_command == SQLCOM_GRANT)
4108 {
4109 List_iterator <LEX_USER> str_list(lex->users_list);
4110 LEX_USER *user, *tmp_user;
4111 while ((tmp_user=str_list++))
4112 {
4113 if (!(user= get_current_user(thd, tmp_user)))
4114 goto error;
4115 reset_mqh(user, 0);
4116 }
4117 }
4118 }
4119 }
4120 break;
4121 }
4122 #endif /*!NO_EMBEDDED_ACCESS_CHECKS*/
4123 case SQLCOM_RESET:
4124 /*
4125 RESET commands are never written to the binary log, so we have to
4126 initialize this variable because RESET shares the same code as FLUSH
4127 */
4128 lex->no_write_to_binlog= 1;
4129 // Fall through.
4130 case SQLCOM_FLUSH:
4131 {
4132 int write_to_binlog;
4133 if (check_global_access(thd,RELOAD_ACL))
4134 goto error;
4135
4136 if (first_table && lex->type & REFRESH_READ_LOCK)
4137 {
4138 /* Check table-level privileges. */
4139 if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables,
4140 FALSE, UINT_MAX, FALSE))
4141 goto error;
4142 if (flush_tables_with_read_lock(thd, all_tables))
4143 goto error;
4144 my_ok(thd);
4145 break;
4146 }
4147 else if (first_table && lex->type & REFRESH_FOR_EXPORT)
4148 {
4149 /* Check table-level privileges. */
4150 if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables,
4151 FALSE, UINT_MAX, FALSE))
4152 goto error;
4153 if (flush_tables_for_export(thd, all_tables))
4154 goto error;
4155 my_ok(thd);
4156 break;
4157 }
4158
4159 /*
4160 reload_acl_and_cache() will tell us if we are allowed to write to the
4161 binlog or not.
4162 */
4163 if (!reload_acl_and_cache(thd, lex->type, first_table, &write_to_binlog))
4164 {
4165 /*
4166 We WANT to write and we CAN write.
4167 ! we write after unlocking the table.
4168 */
4169 /*
4170 Presumably, RESET and binlog writing doesn't require synchronization
4171 */
4172
4173 if (write_to_binlog > 0) // we should write
4174 {
4175 if (!lex->no_write_to_binlog)
4176 res= write_bin_log(thd, false, thd->query().str, thd->query().length);
4177 } else if (write_to_binlog < 0)
4178 {
4179 /*
4180 We should not write, but rather report error because
4181 reload_acl_and_cache binlog interactions failed
4182 */
4183 res= 1;
4184 }
4185
4186 if (!res)
4187 my_ok(thd);
4188 }
4189
4190 break;
4191 }
4192 case SQLCOM_KILL:
4193 {
4194 Item *it= lex->kill_value_list.head();
4195
4196 if (lex->table_or_sp_used())
4197 {
4198 my_error(ER_NOT_SUPPORTED_YET, MYF(0), "Usage of subqueries or stored "
4199 "function calls as part of this statement");
4200 goto error;
4201 }
4202
4203 if ((!it->fixed && it->fix_fields(lex->thd, &it)) || it->check_cols(1))
4204 {
4205 my_error(ER_SET_CONSTANTS_ONLY, MYF(0));
4206 goto error;
4207 }
4208
4209 my_thread_id thread_id= static_cast<my_thread_id>(it->val_int());
4210 if (thd->is_error())
4211 goto error;
4212
4213 sql_kill(thd, thread_id, lex->type & ONLY_KILL_QUERY);
4214 break;
4215 }
4216 #ifndef NO_EMBEDDED_ACCESS_CHECKS
4217 case SQLCOM_SHOW_GRANTS:
4218 {
4219 LEX_USER *grant_user= get_current_user(thd, lex->grant_user);
4220 if (!grant_user)
4221 goto error;
4222 if (!strcmp(thd->security_context()->priv_user().str,
4223 grant_user->user.str) ||
4224 !check_access(thd, SELECT_ACL, "mysql", NULL, NULL, 1, 0))
4225 {
4226 res = mysql_show_grants(thd, grant_user);
4227 }
4228 break;
4229 }
4230 case SQLCOM_SHOW_CREATE_USER:
4231 {
4232 LEX_USER *show_user= get_current_user(thd, lex->grant_user);
4233 Security_context *sctx= thd->security_context();
4234 bool are_both_users_same= !strcmp(sctx->priv_user().str, show_user->user.str) &&
4235 !my_strcasecmp(system_charset_info, show_user->host.str,
4236 sctx->priv_host().str);
4237 if (are_both_users_same || !check_access(thd, SELECT_ACL, "mysql", NULL, NULL, 1, 0))
4238 res= mysql_show_create_user(thd, show_user, are_both_users_same);
4239 break;
4240 }
4241 #endif
4242 case SQLCOM_BEGIN:
4243 if (trans_begin(thd, lex->start_transaction_opt))
4244 goto error;
4245 my_ok(thd);
4246 break;
4247 case SQLCOM_COMMIT:
4248 {
4249 assert(thd->lock == NULL ||
4250 thd->locked_tables_mode == LTM_LOCK_TABLES);
4251 bool tx_chain= (lex->tx_chain == TVL_YES ||
4252 (thd->variables.completion_type == 1 &&
4253 lex->tx_chain != TVL_NO));
4254 bool tx_release= (lex->tx_release == TVL_YES ||
4255 (thd->variables.completion_type == 2 &&
4256 lex->tx_release != TVL_NO));
4257 if (trans_commit(thd))
4258 goto error;
4259 thd->mdl_context.release_transactional_locks();
4260 /* Begin transaction with the same isolation level. */
4261 if (tx_chain)
4262 {
4263 if (trans_begin(thd))
4264 goto error;
4265 }
4266 else
4267 {
4268 /* Reset the isolation level and access mode if no chaining transaction.*/
4269 trans_reset_one_shot_chistics(thd);
4270 }
4271 /* Disconnect the current client connection. */
4272 if (tx_release)
4273 thd->killed= THD::KILL_CONNECTION;
4274 my_ok(thd);
4275 break;
4276 }
4277 case SQLCOM_ROLLBACK:
4278 {
4279 assert(thd->lock == NULL ||
4280 thd->locked_tables_mode == LTM_LOCK_TABLES);
4281 bool tx_chain= (lex->tx_chain == TVL_YES ||
4282 (thd->variables.completion_type == 1 &&
4283 lex->tx_chain != TVL_NO));
4284 bool tx_release= (lex->tx_release == TVL_YES ||
4285 (thd->variables.completion_type == 2 &&
4286 lex->tx_release != TVL_NO));
4287 if (trans_rollback(thd))
4288 goto error;
4289 thd->mdl_context.release_transactional_locks();
4290 /* Begin transaction with the same isolation level. */
4291 if (tx_chain)
4292 {
4293 if (trans_begin(thd))
4294 goto error;
4295 }
4296 else
4297 {
4298 /* Reset the isolation level and access mode if no chaining transaction.*/
4299 trans_reset_one_shot_chistics(thd);
4300 }
4301 /* Disconnect the current client connection. */
4302 if (tx_release)
4303 thd->killed= THD::KILL_CONNECTION;
4304 my_ok(thd);
4305 break;
4306 }
4307 case SQLCOM_RELEASE_SAVEPOINT:
4308 if (trans_release_savepoint(thd, lex->ident))
4309 goto error;
4310 my_ok(thd);
4311 break;
4312 case SQLCOM_ROLLBACK_TO_SAVEPOINT:
4313 if (trans_rollback_to_savepoint(thd, lex->ident))
4314 goto error;
4315 my_ok(thd);
4316 break;
4317 case SQLCOM_SAVEPOINT:
4318 if (trans_savepoint(thd, lex->ident))
4319 goto error;
4320 my_ok(thd);
4321 break;
4322 case SQLCOM_CREATE_PROCEDURE:
4323 case SQLCOM_CREATE_SPFUNCTION:
4324 {
4325 uint namelen;
4326 char *name;
4327
4328 assert(lex->sphead != 0);
4329 assert(lex->sphead->m_db.str); /* Must be initialized in the parser */
4330 /*
4331 Verify that the database name is allowed, optionally
4332 lowercase it.
4333 */
4334 if (check_and_convert_db_name(&lex->sphead->m_db, FALSE) != IDENT_NAME_OK)
4335 goto error;
4336
4337 if (check_access(thd, CREATE_PROC_ACL, lex->sphead->m_db.str,
4338 NULL, NULL, 0, 0))
4339 goto error;
4340
4341 name= lex->sphead->name(&namelen);
4342 #ifdef HAVE_DLOPEN
4343 if (lex->sphead->m_type == SP_TYPE_FUNCTION)
4344 {
4345 udf_func *udf = find_udf(name, namelen);
4346
4347 if (udf)
4348 {
4349 my_error(ER_UDF_EXISTS, MYF(0), name);
4350 goto error;
4351 }
4352 }
4353 #endif
4354
4355 if (sp_process_definer(thd))
4356 goto error;
4357
4358 /*
4359 Record the CURRENT_USER in binlog. The CURRENT_USER is used on slave to
4360 grant default privileges when sp_automatic_privileges variable is set.
4361 */
4362 thd->binlog_invoker();
4363
4364 if (! (res= sp_create_routine(thd, lex->sphead)))
4365 {
4366 #ifndef NO_EMBEDDED_ACCESS_CHECKS
4367 /* only add privileges if really neccessary */
4368
4369 Security_context security_context;
4370 bool restore_backup_context= false;
4371 Security_context *backup= NULL;
4372 /*
4373 We're going to issue an implicit GRANT statement so we close all
4374 open tables. We have to keep metadata locks as this ensures that
4375 this statement is atomic against concurent FLUSH TABLES WITH READ
4376 LOCK. Deadlocks which can arise due to fact that this implicit
4377 statement takes metadata locks should be detected by a deadlock
4378 detector in MDL subsystem and reported as errors.
4379
4380 No need to commit/rollback statement transaction, it's not started.
4381
4382 TODO: Long-term we should either ensure that implicit GRANT statement
4383 is written into binary log as a separate statement or make both
4384 creation of routine and implicit GRANT parts of one fully atomic
4385 statement.
4386 */
4387 assert(thd->get_transaction()->is_empty(Transaction_ctx::STMT));
4388 close_thread_tables(thd);
4389 /*
4390 Check if invoker exists on slave, then use invoker privilege to
4391 insert routine privileges to mysql.procs_priv. If invoker is not
4392 available then consider using definer.
4393
4394 Check if the definer exists on slave,
4395 then use definer privilege to insert routine privileges to mysql.procs_priv.
4396
4397 For current user of SQL thread has GLOBAL_ACL privilege,
4398 which doesn't any check routine privileges,
4399 so no routine privilege record will insert into mysql.procs_priv.
4400 */
4401
4402 if (thd->slave_thread)
4403 {
4404 LEX_CSTRING current_user;
4405 LEX_CSTRING current_host;
4406 if (thd->has_invoker())
4407 {
4408 current_host= thd->get_invoker_host();
4409 current_user= thd->get_invoker_user();
4410 }
4411 else
4412 {
4413 current_host= lex->definer->host;
4414 current_user= lex->definer->user;
4415 }
4416 if (is_acl_user(current_host.str, current_user.str))
4417 {
4418 security_context.change_security_context(thd,
4419 current_user,
4420 current_host,
4421 &thd->lex->sphead->m_db,
4422 &backup);
4423 restore_backup_context= true;
4424 }
4425 }
4426
4427 if (sp_automatic_privileges && !opt_noacl &&
4428 check_routine_access(thd, DEFAULT_CREATE_PROC_ACLS,
4429 lex->sphead->m_db.str, name,
4430 lex->sql_command == SQLCOM_CREATE_PROCEDURE, 1))
4431 {
4432 if (sp_grant_privileges(thd, lex->sphead->m_db.str, name,
4433 lex->sql_command == SQLCOM_CREATE_PROCEDURE))
4434 push_warning(thd, Sql_condition::SL_WARNING,
4435 ER_PROC_AUTO_GRANT_FAIL, ER(ER_PROC_AUTO_GRANT_FAIL));
4436 thd->clear_error();
4437 }
4438
4439 /*
4440 Restore current user with GLOBAL_ACL privilege of SQL thread
4441 */
4442 if (restore_backup_context)
4443 {
4444 assert(thd->slave_thread == 1);
4445 thd->security_context()->restore_security_context(thd, backup);
4446 }
4447 #endif
4448 my_ok(thd);
4449 }
4450 break; /* break super switch */
4451 } /* end case group bracket */
4452 case SQLCOM_CALL:
4453 {
4454 sp_head *sp;
4455
4456 /* Here we check for the execute privilege on stored procedure. */
4457 if (check_routine_access(thd, EXECUTE_ACL, lex->spname->m_db.str,
4458 lex->spname->m_name.str,
4459 lex->sql_command == SQLCOM_CALL, 0))
4460 goto error;
4461
4462 /*
4463 This will cache all SP and SF and open and lock all tables
4464 required for execution.
4465 */
4466 if (check_table_access(thd, SELECT_ACL, all_tables, FALSE,
4467 UINT_MAX, FALSE) ||
4468 open_and_lock_tables(thd, all_tables, 0))
4469 goto error;
4470
4471 /*
4472 By this moment all needed SPs should be in cache so no need to look
4473 into DB.
4474 */
4475 if (!(sp= sp_find_routine(thd, SP_TYPE_PROCEDURE, lex->spname,
4476 &thd->sp_proc_cache, TRUE)))
4477 {
4478 my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PROCEDURE",
4479 lex->spname->m_qname.str);
4480 goto error;
4481 }
4482 else
4483 {
4484 ha_rows select_limit;
4485 /* bits that should be cleared in thd->server_status */
4486 uint bits_to_be_cleared= 0;
4487 /*
4488 Check that the stored procedure doesn't contain Dynamic SQL
4489 and doesn't return result sets: such stored procedures can't
4490 be called from a function or trigger.
4491 */
4492 if (thd->in_sub_stmt)
4493 {
4494 const char *where= (thd->in_sub_stmt & SUB_STMT_TRIGGER ?
4495 "trigger" : "function");
4496 if (sp->is_not_allowed_in_function(where))
4497 goto error;
4498 }
4499
4500 #ifndef EMBEDDED_LIBRARY
4501 if (mysql_audit_notify(thd,
4502 AUDIT_EVENT(MYSQL_AUDIT_STORED_PROGRAM_EXECUTE),
4503 lex->spname->m_db.str,
4504 lex->spname->m_name.str,
4505 NULL))
4506 {
4507 goto error;
4508 }
4509 #endif /* !EMBEDDED_LIBRARY */
4510
4511 if (sp->m_flags & sp_head::MULTI_RESULTS)
4512 {
4513 if (!thd->get_protocol()->has_client_capability(CLIENT_MULTI_RESULTS))
4514 {
4515 /*
4516 The client does not support multiple result sets being sent
4517 back
4518 */
4519 my_error(ER_SP_BADSELECT, MYF(0), sp->m_qname.str);
4520 goto error;
4521 }
4522 /*
4523 If SERVER_MORE_RESULTS_EXISTS is not set,
4524 then remember that it should be cleared
4525 */
4526 bits_to_be_cleared= (~thd->server_status &
4527 SERVER_MORE_RESULTS_EXISTS);
4528 thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
4529 }
4530
4531 if (check_routine_access(thd, EXECUTE_ACL,
4532 sp->m_db.str, sp->m_name.str, TRUE, FALSE))
4533 {
4534 goto error;
4535 }
4536 select_limit= thd->variables.select_limit;
4537 thd->variables.select_limit= HA_POS_ERROR;
4538
4539 /*
4540 We never write CALL statements into binlog:
4541 - If the mode is non-prelocked, each statement will be logged
4542 separately.
4543 - If the mode is prelocked, the invoking statement will care
4544 about writing into binlog.
4545 So just execute the statement.
4546 */
4547 res= sp->execute_procedure(thd, &lex->call_value_list);
4548
4549 thd->variables.select_limit= select_limit;
4550
4551 thd->server_status&= ~bits_to_be_cleared;
4552
4553 if (!res)
4554 {
4555 my_ok(thd, (thd->get_row_count_func() < 0) ? 0 : thd->get_row_count_func());
4556 }
4557 else
4558 {
4559 assert(thd->is_error() || thd->killed);
4560 goto error; // Substatement should already have sent error
4561 }
4562 }
4563 break;
4564 }
4565 case SQLCOM_ALTER_PROCEDURE:
4566 case SQLCOM_ALTER_FUNCTION:
4567 {
4568 if (check_routine_access(thd, ALTER_PROC_ACL, lex->spname->m_db.str,
4569 lex->spname->m_name.str,
4570 lex->sql_command == SQLCOM_ALTER_PROCEDURE,
4571 false))
4572 goto error;
4573
4574 enum_sp_type sp_type= (lex->sql_command == SQLCOM_ALTER_PROCEDURE) ?
4575 SP_TYPE_PROCEDURE : SP_TYPE_FUNCTION;
4576 /*
4577 Note that if you implement the capability of ALTER FUNCTION to
4578 alter the body of the function, this command should be made to
4579 follow the restrictions that log-bin-trust-function-creators=0
4580 already puts on CREATE FUNCTION.
4581 */
4582 /* Conditionally writes to binlog */
4583 int sp_result= sp_update_routine(thd, sp_type, lex->spname,
4584 &lex->sp_chistics);
4585 if (thd->killed)
4586 goto error;
4587 switch (sp_result)
4588 {
4589 case SP_OK:
4590 my_ok(thd);
4591 break;
4592 case SP_KEY_NOT_FOUND:
4593 my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
4594 SP_COM_STRING(lex), lex->spname->m_qname.str);
4595 goto error;
4596 default:
4597 my_error(ER_SP_CANT_ALTER, MYF(0),
4598 SP_COM_STRING(lex), lex->spname->m_qname.str);
4599 goto error;
4600 }
4601 break;
4602 }
4603 case SQLCOM_DROP_PROCEDURE:
4604 case SQLCOM_DROP_FUNCTION:
4605 {
4606 #ifdef HAVE_DLOPEN
4607 if (lex->sql_command == SQLCOM_DROP_FUNCTION &&
4608 ! lex->spname->m_explicit_name)
4609 {
4610 /* DROP FUNCTION <non qualified name> */
4611 udf_func *udf = find_udf(lex->spname->m_name.str,
4612 lex->spname->m_name.length);
4613 if (udf)
4614 {
4615 if (check_access(thd, DELETE_ACL, "mysql", NULL, NULL, 1, 0))
4616 goto error;
4617
4618 if (!(res = mysql_drop_function(thd, &lex->spname->m_name)))
4619 {
4620 my_ok(thd);
4621 break;
4622 }
4623 my_error(ER_SP_DROP_FAILED, MYF(0),
4624 "FUNCTION (UDF)", lex->spname->m_name.str);
4625 goto error;
4626 }
4627
4628 if (lex->spname->m_db.str == NULL)
4629 {
4630 if (lex->drop_if_exists)
4631 {
4632 push_warning_printf(thd, Sql_condition::SL_NOTE,
4633 ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST),
4634 "FUNCTION (UDF)", lex->spname->m_name.str);
4635 res= FALSE;
4636 my_ok(thd);
4637 break;
4638 }
4639 my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
4640 "FUNCTION (UDF)", lex->spname->m_name.str);
4641 goto error;
4642 }
4643 /* Fall thought to test for a stored function */
4644 }
4645 #endif
4646
4647 const char *db= lex->spname->m_db.str;
4648 char *name= lex->spname->m_name.str;
4649
4650 if (check_routine_access(thd, ALTER_PROC_ACL, db, name,
4651 lex->sql_command == SQLCOM_DROP_PROCEDURE,
4652 false))
4653 goto error;
4654
4655 enum_sp_type sp_type= (lex->sql_command == SQLCOM_DROP_PROCEDURE) ?
4656 SP_TYPE_PROCEDURE : SP_TYPE_FUNCTION;
4657
4658 /* Conditionally writes to binlog */
4659 int sp_result= sp_drop_routine(thd, sp_type, lex->spname);
4660
4661 #ifndef NO_EMBEDDED_ACCESS_CHECKS
4662 /*
4663 We're going to issue an implicit REVOKE statement so we close all
4664 open tables. We have to keep metadata locks as this ensures that
4665 this statement is atomic against concurent FLUSH TABLES WITH READ
4666 LOCK. Deadlocks which can arise due to fact that this implicit
4667 statement takes metadata locks should be detected by a deadlock
4668 detector in MDL subsystem and reported as errors.
4669
4670 No need to commit/rollback statement transaction, it's not started.
4671
4672 TODO: Long-term we should either ensure that implicit REVOKE statement
4673 is written into binary log as a separate statement or make both
4674 dropping of routine and implicit REVOKE parts of one fully atomic
4675 statement.
4676 */
4677 assert(thd->get_transaction()->is_empty(Transaction_ctx::STMT));
4678 close_thread_tables(thd);
4679
4680 if (sp_result != SP_KEY_NOT_FOUND &&
4681 sp_automatic_privileges && !opt_noacl &&
4682 sp_revoke_privileges(thd, db, name,
4683 lex->sql_command == SQLCOM_DROP_PROCEDURE))
4684 {
4685 push_warning(thd, Sql_condition::SL_WARNING,
4686 ER_PROC_AUTO_REVOKE_FAIL,
4687 ER(ER_PROC_AUTO_REVOKE_FAIL));
4688 /* If this happens, an error should have been reported. */
4689 goto error;
4690 }
4691 #endif
4692
4693 res= sp_result;
4694 switch (sp_result) {
4695 case SP_OK:
4696 my_ok(thd);
4697 break;
4698 case SP_KEY_NOT_FOUND:
4699 if (lex->drop_if_exists)
4700 {
4701 res= write_bin_log(thd, true, thd->query().str, thd->query().length);
4702 push_warning_printf(thd, Sql_condition::SL_NOTE,
4703 ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST),
4704 SP_COM_STRING(lex), lex->spname->m_qname.str);
4705 if (!res)
4706 my_ok(thd);
4707 break;
4708 }
4709 my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
4710 SP_COM_STRING(lex), lex->spname->m_qname.str);
4711 goto error;
4712 default:
4713 my_error(ER_SP_DROP_FAILED, MYF(0),
4714 SP_COM_STRING(lex), lex->spname->m_qname.str);
4715 goto error;
4716 }
4717 break;
4718 }
4719 case SQLCOM_SHOW_CREATE_PROC:
4720 {
4721 if (sp_show_create_routine(thd, SP_TYPE_PROCEDURE, lex->spname))
4722 goto error;
4723 break;
4724 }
4725 case SQLCOM_SHOW_CREATE_FUNC:
4726 {
4727 if (sp_show_create_routine(thd, SP_TYPE_FUNCTION, lex->spname))
4728 goto error;
4729 break;
4730 }
4731 case SQLCOM_SHOW_PROC_CODE:
4732 case SQLCOM_SHOW_FUNC_CODE:
4733 {
4734 #ifndef NDEBUG
4735 sp_head *sp;
4736 enum_sp_type sp_type= (lex->sql_command == SQLCOM_SHOW_PROC_CODE) ?
4737 SP_TYPE_PROCEDURE : SP_TYPE_FUNCTION;
4738
4739 if (sp_cache_routine(thd, sp_type, lex->spname, false, &sp))
4740 goto error;
4741 if (!sp || sp->show_routine_code(thd))
4742 {
4743 /* We don't distinguish between errors for now */
4744 my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
4745 SP_COM_STRING(lex), lex->spname->m_name.str);
4746 goto error;
4747 }
4748 break;
4749 #else
4750 my_error(ER_FEATURE_DISABLED, MYF(0),
4751 "SHOW PROCEDURE|FUNCTION CODE", "--with-debug");
4752 goto error;
4753 #endif // ifndef NDEBUG
4754 }
4755 case SQLCOM_SHOW_CREATE_TRIGGER:
4756 {
4757 if (lex->spname->m_name.length > NAME_LEN)
4758 {
4759 my_error(ER_TOO_LONG_IDENT, MYF(0), lex->spname->m_name.str);
4760 goto error;
4761 }
4762
4763 if (show_create_trigger(thd, lex->spname))
4764 goto error; /* Error has been already logged. */
4765
4766 break;
4767 }
4768 case SQLCOM_CREATE_VIEW:
4769 {
4770 /*
4771 Note: SQLCOM_CREATE_VIEW also handles 'ALTER VIEW' commands
4772 as specified through the thd->lex->create_view_mode flag.
4773 */
4774 res= mysql_create_view(thd, first_table, thd->lex->create_view_mode);
4775 break;
4776 }
4777 case SQLCOM_DROP_VIEW:
4778 {
4779 if (check_table_access(thd, DROP_ACL, all_tables, FALSE, UINT_MAX, FALSE))
4780 goto error;
4781 /* Conditionally writes to binlog. */
4782 res= mysql_drop_view(thd, first_table, thd->lex->drop_mode);
4783 break;
4784 }
4785 case SQLCOM_CREATE_TRIGGER:
4786 {
4787 /* Conditionally writes to binlog. */
4788 res= mysql_create_or_drop_trigger(thd, all_tables, 1);
4789
4790 break;
4791 }
4792 case SQLCOM_DROP_TRIGGER:
4793 {
4794 /* Conditionally writes to binlog. */
4795 res= mysql_create_or_drop_trigger(thd, all_tables, 0);
4796 break;
4797 }
4798 case SQLCOM_ALTER_TABLESPACE:
4799 if (check_global_access(thd, CREATE_TABLESPACE_ACL))
4800 break;
4801 if (!(res= mysql_alter_tablespace(thd, lex->alter_tablespace_info)))
4802 my_ok(thd);
4803 break;
4804 case SQLCOM_BINLOG_BASE64_EVENT:
4805 {
4806 #ifndef EMBEDDED_LIBRARY
4807 mysql_client_binlog_statement(thd);
4808 #else /* EMBEDDED_LIBRARY */
4809 my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "embedded");
4810 #endif /* EMBEDDED_LIBRARY */
4811 break;
4812 }
4813 case SQLCOM_EXPLAIN_OTHER:
4814 {
4815 /* EXPLAIN FOR CONNECTION <id> */
4816 mysql_explain_other(thd);
4817 break;
4818 }
4819 case SQLCOM_ANALYZE:
4820 case SQLCOM_CHECK:
4821 case SQLCOM_OPTIMIZE:
4822 case SQLCOM_REPAIR:
4823 case SQLCOM_TRUNCATE:
4824 case SQLCOM_ALTER_TABLE:
4825 case SQLCOM_HA_OPEN:
4826 case SQLCOM_HA_READ:
4827 case SQLCOM_HA_CLOSE:
4828 assert(first_table == all_tables && first_table != 0);
4829 /* fall through */
4830 case SQLCOM_CREATE_SERVER:
4831 case SQLCOM_ALTER_SERVER:
4832 case SQLCOM_DROP_SERVER:
4833 case SQLCOM_SIGNAL:
4834 case SQLCOM_RESIGNAL:
4835 case SQLCOM_GET_DIAGNOSTICS:
4836 case SQLCOM_CHANGE_REPLICATION_FILTER:
4837 case SQLCOM_XA_START:
4838 case SQLCOM_XA_END:
4839 case SQLCOM_XA_PREPARE:
4840 case SQLCOM_XA_COMMIT:
4841 case SQLCOM_XA_ROLLBACK:
4842 case SQLCOM_XA_RECOVER:
4843 case SQLCOM_INSTALL_PLUGIN:
4844 case SQLCOM_UNINSTALL_PLUGIN:
4845 case SQLCOM_SHUTDOWN:
4846 case SQLCOM_ALTER_INSTANCE:
4847 assert(lex->m_sql_cmd != NULL);
4848 res= lex->m_sql_cmd->execute(thd);
4849 break;
4850
4851 #ifndef NO_EMBEDDED_ACCESS_CHECKS
4852 case SQLCOM_ALTER_USER:
4853 {
4854 LEX_USER *user, *tmp_user;
4855 bool changing_own_password= false;
4856 bool own_password_expired= thd->security_context()->password_expired();
4857 bool check_permission= true;
4858
4859 List_iterator <LEX_USER> user_list(lex->users_list);
4860 while ((tmp_user= user_list++))
4861 {
4862 bool update_password_only= FALSE;
4863 bool is_self= false;
4864
4865 /* If it is an empty lex_user update it with current user */
4866 if (!tmp_user->host.str && !tmp_user->user.str)
4867 {
4868 /* set user information as of the current user */
4869 assert(thd->security_context()->priv_host().str);
4870 tmp_user->host.str= (char *) thd->security_context()->priv_host().str;
4871 tmp_user->host.length= strlen(thd->security_context()->priv_host().str);
4872 assert(thd->security_context()->user().str);
4873 tmp_user->user.str= (char *) thd->security_context()->user().str;
4874 tmp_user->user.length= strlen(thd->security_context()->user().str);
4875 }
4876 if (!(user= get_current_user(thd, tmp_user)))
4877 goto error;
4878
4879 /* copy password expire attributes to individual lex user */
4880 user->alter_status= thd->lex->alter_password;
4881
4882 if (user->uses_identified_by_clause &&
4883 !thd->lex->mqh.specified_limits &&
4884 !user->alter_status.update_account_locked_column &&
4885 !user->alter_status.update_password_expired_column &&
4886 !user->alter_status.expire_after_days &&
4887 user->alter_status.use_default_password_lifetime &&
4888 (thd->lex->ssl_type == SSL_TYPE_NOT_SPECIFIED))
4889 update_password_only= TRUE;
4890
4891 is_self= !strcmp(thd->security_context()->user().length ?
4892 thd->security_context()->user().str : "",
4893 user->user.str) &&
4894 !my_strcasecmp(&my_charset_latin1, user->host.str,
4895 thd->security_context()->priv_host().str);
4896 /*
4897 if user executes ALTER statement to change password only
4898 for himself then skip access check.
4899 */
4900 if (update_password_only && is_self)
4901 {
4902 changing_own_password= true;
4903 continue;
4904 }
4905 else if (check_permission)
4906 {
4907 if (check_access(thd, UPDATE_ACL, "mysql", NULL, NULL, 1, 1) &&
4908 check_global_access(thd, CREATE_USER_ACL))
4909 goto error;
4910
4911 check_permission= false;
4912 }
4913
4914 if (is_self &&
4915 (user->uses_identified_by_clause ||
4916 user->uses_identified_with_clause ||
4917 user->uses_authentication_string_clause ||
4918 user->uses_identified_by_password_clause))
4919 {
4920 changing_own_password= true;
4921 break;
4922 }
4923
4924 if (update_password_only &&
4925 likely((get_server_state() == SERVER_OPERATING)) &&
4926 !strcmp(thd->security_context()->priv_user().str,""))
4927 {
4928 my_message(ER_PASSWORD_ANONYMOUS_USER, ER(ER_PASSWORD_ANONYMOUS_USER),
4929 MYF(0));
4930 goto error;
4931 }
4932 }
4933
4934 if (unlikely(own_password_expired && !changing_own_password))
4935 {
4936 my_error(ER_MUST_CHANGE_PASSWORD, MYF(0));
4937 goto error;
4938 }
4939
4940 /* Conditionally writes to binlog */
4941 if (!(res = mysql_alter_user(thd, lex->users_list, lex->drop_if_exists)))
4942 my_ok(thd);
4943 break;
4944 }
4945 #endif
4946 default:
4947 #ifndef EMBEDDED_LIBRARY
4948 assert(0); /* Impossible */
4949 #endif
4950 my_ok(thd);
4951 break;
4952 }
4953 goto finish;
4954
4955 error:
4956 res= TRUE;
4957
4958 finish:
4959 THD_STAGE_INFO(thd, stage_query_end);
4960
4961 if (res && thd->get_reprepare_observer() != NULL &&
4962 thd->get_reprepare_observer()->is_invalidated() &&
4963 thd->get_reprepare_observer()->can_retry()) {
4964 thd->skip_gtid_rollback = true;
4965 }
4966
4967 // Cleanup EXPLAIN info
4968 if (!thd->in_sub_stmt)
4969 {
4970 if (is_explainable_query(lex->sql_command))
4971 {
4972 DEBUG_SYNC(thd, "before_reset_query_plan");
4973 /*
4974 We want EXPLAIN CONNECTION to work until the explained statement ends,
4975 thus it is only now that we may fully clean up any unit of this statement.
4976 */
4977 lex->unit->assert_not_fully_clean();
4978 }
4979 thd->query_plan.set_query_plan(SQLCOM_END, NULL, false);
4980 }
4981
4982 assert(!thd->in_active_multi_stmt_transaction() ||
4983 thd->in_multi_stmt_transaction_mode());
4984
4985 if (! thd->in_sub_stmt)
4986 {
4987 #ifndef EMBEDDED_LIBRARY
4988 mysql_audit_notify(thd,
4989 first_level ? MYSQL_AUDIT_QUERY_STATUS_END :
4990 MYSQL_AUDIT_QUERY_NESTED_STATUS_END,
4991 first_level ? "MYSQL_AUDIT_QUERY_STATUS_END" :
4992 "MYSQL_AUDIT_QUERY_NESTED_STATUS_END");
4993 #endif /* !EMBEDDED_LIBRARY */
4994
4995 /* report error issued during command execution */
4996 if (thd->killed_errno())
4997 thd->send_kill_message();
4998 if (thd->is_error() || (thd->variables.option_bits & OPTION_MASTER_SQL_ERROR))
4999 trans_rollback_stmt(thd);
5000 else
5001 {
5002 /* If commit fails, we should be able to reset the OK status. */
5003 thd->get_stmt_da()->set_overwrite_status(true);
5004 trans_commit_stmt(thd);
5005 thd->get_stmt_da()->set_overwrite_status(false);
5006 }
5007 if (thd->killed == THD::KILL_QUERY ||
5008 thd->killed == THD::KILL_TIMEOUT ||
5009 thd->killed == THD::KILL_BAD_DATA)
5010 {
5011 thd->killed= THD::NOT_KILLED;
5012 thd->reset_query_for_display();
5013 }
5014 }
5015
5016 lex->unit->cleanup(true);
5017 /* Free tables */
5018 THD_STAGE_INFO(thd, stage_closing_tables);
5019 close_thread_tables(thd);
5020
5021 #ifndef NDEBUG
5022 if (lex->sql_command != SQLCOM_SET_OPTION && ! thd->in_sub_stmt)
5023 DEBUG_SYNC(thd, "execute_command_after_close_tables");
5024 #endif
5025
5026 if (! thd->in_sub_stmt && thd->transaction_rollback_request)
5027 {
5028 /*
5029 We are not in sub-statement and transaction rollback was requested by
5030 one of storage engines (e.g. due to deadlock). Rollback transaction in
5031 all storage engines including binary log.
5032 */
5033 trans_rollback_implicit(thd);
5034 thd->mdl_context.release_transactional_locks();
5035 }
5036 else if (stmt_causes_implicit_commit(thd, CF_IMPLICIT_COMMIT_END))
5037 {
5038 /* No transaction control allowed in sub-statements. */
5039 assert(! thd->in_sub_stmt);
5040 /* If commit fails, we should be able to reset the OK status. */
5041 thd->get_stmt_da()->set_overwrite_status(true);
5042 /* Commit the normal transaction if one is active. */
5043 trans_commit_implicit(thd);
5044 thd->get_stmt_da()->set_overwrite_status(false);
5045 thd->mdl_context.release_transactional_locks();
5046 }
5047 else if (! thd->in_sub_stmt && ! thd->in_multi_stmt_transaction_mode())
5048 {
5049 /*
5050 - If inside a multi-statement transaction,
5051 defer the release of metadata locks until the current
5052 transaction is either committed or rolled back. This prevents
5053 other statements from modifying the table for the entire
5054 duration of this transaction. This provides commit ordering
5055 and guarantees serializability across multiple transactions.
5056 - If in autocommit mode, or outside a transactional context,
5057 automatically release metadata locks of the current statement.
5058 */
5059 thd->mdl_context.release_transactional_locks();
5060 }
5061 else if (! thd->in_sub_stmt)
5062 {
5063 thd->mdl_context.release_statement_locks();
5064 }
5065
5066 if (thd->variables.session_track_transaction_info > TX_TRACK_NONE)
5067 {
5068 ((Transaction_state_tracker *)
5069 thd->session_tracker.get_tracker(TRANSACTION_INFO_TRACKER))
5070 ->add_trx_state_from_thd(thd);
5071 }
5072
5073 #if defined(VALGRIND_DO_QUICK_LEAK_CHECK)
5074 // Get incremental leak reports, for easier leak hunting.
5075 // ./mtr --mem --mysqld='-T 4096' --valgrind-mysqld main.1st
5076 // Note that with multiple connections, the report below may be misleading.
5077 if (test_flags & TEST_DO_QUICK_LEAK_CHECK)
5078 {
5079 static unsigned long total_leaked_bytes= 0;
5080 unsigned long leaked= 0;
5081 unsigned long dubious MY_ATTRIBUTE((unused));
5082 unsigned long reachable MY_ATTRIBUTE((unused));
5083 unsigned long suppressed MY_ATTRIBUTE((unused));
5084 /*
5085 We could possibly use VALGRIND_DO_CHANGED_LEAK_CHECK here,
5086 but that is a fairly new addition to the Valgrind api.
5087 Note: we dont want to check 'reachable' until we have done shutdown,
5088 and that is handled by the final report anyways.
5089 We print some extra information, to tell mtr to ignore this report.
5090 */
5091 sql_print_information("VALGRIND_DO_QUICK_LEAK_CHECK");
5092 VALGRIND_DO_QUICK_LEAK_CHECK;
5093 VALGRIND_COUNT_LEAKS(leaked, dubious, reachable, suppressed);
5094 if (leaked > total_leaked_bytes)
5095 {
5096 sql_print_error("VALGRIND_COUNT_LEAKS reports %lu leaked bytes "
5097 "for query '%.*s'", leaked - total_leaked_bytes,
5098 static_cast<int>(thd->query().length), thd->query().str);
5099 }
5100 total_leaked_bytes= leaked;
5101 }
5102 #endif
5103
5104 if (!res && !thd->is_error()) { // if statement succeeded
5105 binlog_gtid_end_transaction(thd); // finalize GTID life-cycle
5106 DEBUG_SYNC(thd, "persist_new_state_after_statement_succeeded");
5107 } else if (!gtid_consistency_violation_state && // if the consistency state
5108 thd->has_gtid_consistency_violation) { // was set by the failing
5109 // statement
5110 gtid_state->end_gtid_violating_transaction(thd); // just roll it back
5111 DEBUG_SYNC(thd, "restore_previous_state_after_statement_failed");
5112 }
5113
5114 thd->skip_gtid_rollback = false;
5115
5116 DBUG_RETURN(res || thd->is_error());
5117 }
5118
execute_sqlcom_select(THD * thd,TABLE_LIST * all_tables)5119 static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
5120 {
5121 LEX *lex= thd->lex;
5122 bool statement_timer_armed= false;
5123 bool res;
5124
5125 /* assign global limit variable if limit is not given */
5126 {
5127 SELECT_LEX *param= lex->unit->global_parameters();
5128 if (!param->explicit_limit)
5129 param->select_limit=
5130 new Item_int((ulonglong) thd->variables.select_limit);
5131 }
5132
5133 //check if timer is applicable to statement, if applicable then set timer.
5134 if (is_timer_applicable_to_statement(thd))
5135 statement_timer_armed= set_statement_timer(thd);
5136
5137 if (!(res= open_tables_for_query(thd, all_tables, 0)))
5138 {
5139 MYSQL_SELECT_START(const_cast<char*>(thd->query().str));
5140 if (lex->is_explain())
5141 {
5142 /*
5143 We always use Query_result_send for EXPLAIN, even if it's an EXPLAIN
5144 for SELECT ... INTO OUTFILE: a user application should be able
5145 to prepend EXPLAIN to any query and receive output for it,
5146 even if the query itself redirects the output.
5147 */
5148 Query_result *const result= new Query_result_send;
5149 if (!result)
5150 return true; /* purecov: inspected */
5151 res= handle_query(thd, lex, result, 0, 0);
5152 }
5153 else
5154 {
5155 Query_result *result= lex->result;
5156 if (!result && !(result= new Query_result_send()))
5157 return true; /* purecov: inspected */
5158 Query_result *save_result= result;
5159 Query_result *analyse_result= NULL;
5160 if (lex->proc_analyse)
5161 {
5162 if ((result= analyse_result=
5163 new Query_result_analyse(result, lex->proc_analyse)) == NULL)
5164 return true;
5165 }
5166 res= handle_query(thd, lex, result, 0, 0);
5167 delete analyse_result;
5168 if (save_result != lex->result)
5169 delete save_result;
5170 }
5171 MYSQL_SELECT_DONE((int) res, (ulong) thd->current_found_rows);
5172 }
5173
5174 if (statement_timer_armed && thd->timer)
5175 reset_statement_timer(thd);
5176
5177 DEBUG_SYNC(thd, "after_table_open");
5178 return res;
5179 }
5180
5181
5182 /****************************************************************************
5183 Check stack size; Send error if there isn't enough stack to continue
5184 ****************************************************************************/
5185
5186
5187 #if STACK_DIRECTION < 0
5188 #define used_stack(A,B) (long) (A - B)
5189 #else
5190 #define used_stack(A,B) (long) (B - A)
5191 #endif
5192
5193 #ifndef NDEBUG
5194 long max_stack_used;
5195 #endif
5196
5197 /**
5198 @note
5199 Note: The 'buf' parameter is necessary, even if it is unused here.
5200 - fix_fields functions has a "dummy" buffer large enough for the
5201 corresponding exec. (Thus we only have to check in fix_fields.)
5202 - Passing to check_stack_overrun() prevents the compiler from removing it.
5203 */
check_stack_overrun(THD * thd,long margin,uchar * buf MY_ATTRIBUTE ((unused)))5204 bool check_stack_overrun(THD *thd, long margin,
5205 uchar *buf MY_ATTRIBUTE((unused)))
5206 {
5207 long stack_used;
5208 assert(thd == current_thd);
5209 if ((stack_used=used_stack(thd->thread_stack,(char*) &stack_used)) >=
5210 (long) (my_thread_stack_size - margin))
5211 {
5212 /*
5213 Do not use stack for the message buffer to ensure correct
5214 behaviour in cases we have close to no stack left.
5215 */
5216 char* ebuff= new (std::nothrow) char[MYSQL_ERRMSG_SIZE];
5217 if (ebuff) {
5218 my_snprintf(ebuff, MYSQL_ERRMSG_SIZE, ER(ER_STACK_OVERRUN_NEED_MORE),
5219 stack_used, my_thread_stack_size, margin);
5220 my_message(ER_STACK_OVERRUN_NEED_MORE, ebuff, MYF(ME_FATALERROR));
5221 delete [] ebuff;
5222 }
5223 return 1;
5224 }
5225 #ifndef NDEBUG
5226 max_stack_used= max(max_stack_used, stack_used);
5227 #endif
5228 return 0;
5229 }
5230
5231
5232 #define MY_YACC_INIT 1000 // Start with big alloc
5233 #define MY_YACC_MAX 32000 // Because of 'short'
5234
my_yyoverflow(short ** yyss,YYSTYPE ** yyvs,YYLTYPE ** yyls,ulong * yystacksize)5235 bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, YYLTYPE **yyls, ulong *yystacksize)
5236 {
5237 Yacc_state *state= & current_thd->m_parser_state->m_yacc;
5238 ulong old_info=0;
5239 assert(state);
5240 if ((uint) *yystacksize >= MY_YACC_MAX)
5241 return 1;
5242 if (!state->yacc_yyvs)
5243 old_info= *yystacksize;
5244 *yystacksize= set_zone((*yystacksize)*2,MY_YACC_INIT,MY_YACC_MAX);
5245 if (!(state->yacc_yyvs= (uchar*)
5246 my_realloc(key_memory_bison_stack,
5247 state->yacc_yyvs,
5248 *yystacksize*sizeof(**yyvs),
5249 MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))) ||
5250 !(state->yacc_yyss= (uchar*)
5251 my_realloc(key_memory_bison_stack,
5252 state->yacc_yyss,
5253 *yystacksize*sizeof(**yyss),
5254 MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))) ||
5255 !(state->yacc_yyls= (uchar*)
5256 my_realloc(key_memory_bison_stack,
5257 state->yacc_yyls,
5258 *yystacksize*sizeof(**yyls),
5259 MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))))
5260 return 1;
5261 if (old_info)
5262 {
5263 /*
5264 Only copy the old stack on the first call to my_yyoverflow(),
5265 when replacing a static stack (YYINITDEPTH) by a dynamic stack.
5266 For subsequent calls, my_realloc already did preserve the old stack.
5267 */
5268 memcpy(state->yacc_yyss, *yyss, old_info*sizeof(**yyss));
5269 memcpy(state->yacc_yyvs, *yyvs, old_info*sizeof(**yyvs));
5270 memcpy(state->yacc_yyls, *yyls, old_info*sizeof(**yyls));
5271 }
5272 *yyss= (short*) state->yacc_yyss;
5273 *yyvs= (YYSTYPE*) state->yacc_yyvs;
5274 *yyls= (YYLTYPE*) state->yacc_yyls;
5275 return 0;
5276 }
5277
5278
5279 /**
5280 Reset the part of THD responsible for the state of command
5281 processing.
5282
5283 This needs to be called before execution of every statement
5284 (prepared or conventional). It is not called by substatements of
5285 routines.
5286
5287 @todo Remove mysql_reset_thd_for_next_command and only use the
5288 member function.
5289
5290 @todo Call it after we use THD for queries, not before.
5291 */
mysql_reset_thd_for_next_command(THD * thd)5292 void mysql_reset_thd_for_next_command(THD *thd)
5293 {
5294 thd->reset_for_next_command();
5295 }
5296
reset_for_next_command()5297 void THD::reset_for_next_command()
5298 {
5299 // TODO: Why on earth is this here?! We should probably fix this
5300 // function and move it to the proper file. /Matz
5301 THD *thd= this;
5302 DBUG_ENTER("mysql_reset_thd_for_next_command");
5303 assert(!thd->sp_runtime_ctx); /* not for substatements of routines */
5304 assert(! thd->in_sub_stmt);
5305 thd->free_list= 0;
5306 /*
5307 Those two lines below are theoretically unneeded as
5308 THD::cleanup_after_query() should take care of this already.
5309 */
5310 thd->auto_inc_intervals_in_cur_stmt_for_binlog.empty();
5311 thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
5312
5313 thd->query_start_usec_used= 0;
5314 thd->is_fatal_error= thd->time_zone_used= 0;
5315 /*
5316 Clear the status flag that are expected to be cleared at the
5317 beginning of each SQL statement.
5318 */
5319 thd->server_status&= ~SERVER_STATUS_CLEAR_SET;
5320 /*
5321 If in autocommit mode and not in a transaction, reset flag
5322 that identifies if a transaction has done some operations
5323 that cannot be safely rolled back.
5324
5325 If the flag is set an warning message is printed out in
5326 ha_rollback_trans() saying that some tables couldn't be
5327 rolled back.
5328 */
5329 if (!thd->in_multi_stmt_transaction_mode())
5330 {
5331 thd->get_transaction()->reset_unsafe_rollback_flags(
5332 Transaction_ctx::SESSION);
5333 }
5334 assert(thd->security_context()== &thd->m_main_security_ctx);
5335 thd->thread_specific_used= FALSE;
5336
5337 if (opt_bin_log)
5338 {
5339 thd->user_var_events.clear();
5340 thd->user_var_events_alloc= thd->mem_root;
5341 }
5342 thd->clear_error();
5343 thd->get_stmt_da()->reset_diagnostics_area();
5344 thd->get_stmt_da()->reset_statement_cond_count();
5345
5346 thd->rand_used= 0;
5347 thd->m_sent_row_count= thd->m_examined_row_count= 0;
5348
5349 thd->reset_current_stmt_binlog_format_row();
5350 thd->binlog_unsafe_warning_flags= 0;
5351 thd->binlog_need_explicit_defaults_ts= false;
5352
5353 thd->commit_error= THD::CE_NONE;
5354 thd->durability_property= HA_REGULAR_DURABILITY;
5355 thd->set_trans_pos(NULL, 0);
5356
5357 thd->derived_tables_processing= false;
5358
5359 // Need explicit setting, else demand all privileges to a table.
5360 thd->want_privilege= ~NO_ACCESS;
5361
5362 thd->gtid_executed_warning_issued= false;
5363
5364 thd->reset_skip_readonly_check();
5365
5366 DBUG_PRINT("debug",
5367 ("is_current_stmt_binlog_format_row(): %d",
5368 thd->is_current_stmt_binlog_format_row()));
5369
5370 DBUG_VOID_RETURN;
5371 }
5372
5373
5374 /**
5375 Create a select to return the same output as 'SELECT @@var_name'.
5376
5377 Used for SHOW COUNT(*) [ WARNINGS | ERROR].
5378
5379 This will crash with a core dump if the variable doesn't exists.
5380
5381 @param pc Current parse context
5382 @param var_name Variable name
5383 */
5384
create_select_for_variable(Parse_context * pc,const char * var_name)5385 void create_select_for_variable(Parse_context *pc, const char *var_name)
5386 {
5387 THD *thd= pc->thd;
5388 LEX *lex;
5389 LEX_STRING tmp, null_lex_string;
5390 Item *var;
5391 char buff[MAX_SYS_VAR_LENGTH*2+4+8], *end;
5392 DBUG_ENTER("create_select_for_variable");
5393
5394 lex= thd->lex;
5395 lex->sql_command= SQLCOM_SELECT;
5396 tmp.str= (char*) var_name;
5397 tmp.length=strlen(var_name);
5398 memset(&null_lex_string, 0, sizeof(null_lex_string));
5399 /*
5400 We set the name of Item to @@session.var_name because that then is used
5401 as the column name in the output.
5402 */
5403 if ((var= get_system_var(pc, OPT_SESSION, tmp, null_lex_string, false)))
5404 {
5405 end= strxmov(buff, "@@session.", var_name, NullS);
5406 var->item_name.copy(buff, end - buff);
5407 add_item_to_list(thd, var);
5408 }
5409 DBUG_VOID_RETURN;
5410 }
5411
5412
mysql_init_multi_delete(LEX * lex)5413 void mysql_init_multi_delete(LEX *lex)
5414 {
5415 lex->select_lex->select_limit= 0;
5416 lex->unit->select_limit_cnt= HA_POS_ERROR;
5417 lex->select_lex->table_list.save_and_clear(&lex->auxiliary_table_list);
5418 lex->query_tables= NULL;
5419 lex->query_tables_last= &lex->query_tables;
5420 }
5421
5422 /*
5423 When you modify mysql_parse(), you may need to mofify
5424 mysql_test_parse_for_slave() in this same file.
5425 */
5426
5427 /**
5428 Parse a query.
5429
5430 @param thd Current thread
5431 @param rawbuf Begining of the query text
5432 @param length Length of the query text
5433 @param[out] found_semicolon For multi queries, position of the character of
5434 the next query in the query text.
5435 */
5436
mysql_parse(THD * thd,Parser_state * parser_state)5437 void mysql_parse(THD *thd, Parser_state *parser_state)
5438 {
5439 int error MY_ATTRIBUTE((unused));
5440 DBUG_ENTER("mysql_parse");
5441 DBUG_PRINT("mysql_parse", ("query: '%s'", thd->query().str));
5442
5443 DBUG_EXECUTE_IF("parser_debug", turn_parser_debug_on(););
5444
5445 /*
5446 Warning.
5447 The purpose of query_cache_send_result_to_client() is to lookup the
5448 query in the query cache first, to avoid parsing and executing it.
5449 So, the natural implementation would be to:
5450 - first, call query_cache_send_result_to_client,
5451 - second, if caching failed, initialise the lexical and syntactic parser.
5452 The problem is that the query cache depends on a clean initialization
5453 of (among others) lex->safe_to_cache_query and thd->server_status,
5454 which are reset respectively in
5455 - lex_start()
5456 - mysql_reset_thd_for_next_command()
5457 So, initializing the lexical analyser *before* using the query cache
5458 is required for the cache to work properly.
5459 FIXME: cleanup the dependencies in the code to simplify this.
5460 */
5461 mysql_reset_thd_for_next_command(thd);
5462 lex_start(thd);
5463
5464 thd->m_parser_state= parser_state;
5465 invoke_pre_parse_rewrite_plugins(thd);
5466 thd->m_parser_state= NULL;
5467
5468 enable_digest_if_any_plugin_needs_it(thd, parser_state);
5469
5470 if (query_cache.send_result_to_client(thd, thd->query()) <= 0)
5471 {
5472 LEX *lex= thd->lex;
5473 const char *found_semicolon;
5474
5475 bool err= thd->get_stmt_da()->is_error();
5476
5477 if (!err)
5478 {
5479 err= parse_sql(thd, parser_state, NULL);
5480 if (!err)
5481 err= invoke_post_parse_rewrite_plugins(thd, false);
5482
5483 found_semicolon= parser_state->m_lip.found_semicolon;
5484 }
5485
5486 DEBUG_SYNC_C("sql_parse_before_rewrite");
5487
5488 if (!err)
5489 {
5490 /*
5491 Rewrite the query for logging and for the Performance Schema
5492 statement tables. (Raw logging happened earlier.)
5493
5494 Query-cache only handles SELECT, which we don't rewrite, so it's no
5495 concern of ours.
5496
5497 Sub-routines of mysql_rewrite_query() should try to only rewrite when
5498 necessary (e.g. not do password obfuscation when query contains no
5499 password).
5500
5501 If rewriting does not happen here, thd->m_rewritten_query is still
5502 empty from being reset in alloc_query().
5503 */
5504
5505 if (thd->rewritten_query().length() == 0)
5506 mysql_rewrite_query(thd);
5507
5508 if (thd->rewritten_query().length())
5509 {
5510 lex->safe_to_cache_query= false; // see comments below
5511
5512 thd->set_query_for_display(thd->rewritten_query().ptr(),
5513 thd->rewritten_query().length());
5514 } else if (thd->slave_thread) {
5515 /*
5516 In the slave, we add the information to pfs.events_statements_history,
5517 but not to pfs.threads, as that is what the test suite expects.
5518 */
5519 MYSQL_SET_STATEMENT_TEXT(thd->m_statement_psi,
5520 thd->query().str,
5521 thd->query().length);
5522 } else {
5523 thd->set_query_for_display(thd->query().str, thd->query().length);
5524 }
5525
5526 if (!(opt_general_log_raw || thd->slave_thread))
5527 {
5528 if (thd->rewritten_query().length())
5529 query_logger.general_log_write(thd, COM_QUERY,
5530 thd->rewritten_query().ptr(),
5531 thd->rewritten_query().length());
5532 else
5533 {
5534 size_t qlen= found_semicolon
5535 ? (found_semicolon - thd->query().str)
5536 : thd->query().length;
5537
5538 query_logger.general_log_write(thd, COM_QUERY,
5539 thd->query().str, qlen);
5540 }
5541 }
5542 }
5543
5544 DEBUG_SYNC_C("sql_parse_after_rewrite");
5545
5546 if (!err)
5547 {
5548 thd->m_statement_psi= MYSQL_REFINE_STATEMENT(thd->m_statement_psi,
5549 sql_statement_info[thd->lex->sql_command].m_key);
5550
5551 #ifndef NO_EMBEDDED_ACCESS_CHECKS
5552 if (mqh_used && thd->get_user_connect() &&
5553 check_mqh(thd, lex->sql_command))
5554 {
5555 if (thd->is_classic_protocol())
5556 thd->get_protocol_classic()->get_net()->error = 0;
5557 }
5558 else
5559 #endif
5560 {
5561 if (! thd->is_error())
5562 {
5563 /*
5564 Binlog logs a string starting from thd->query and having length
5565 thd->query_length; so we set thd->query_length correctly (to not
5566 log several statements in one event, when we executed only first).
5567 We set it to not see the ';' (otherwise it would get into binlog
5568 and Query_log_event::print() would give ';;' output).
5569 This also helps display only the current query in SHOW
5570 PROCESSLIST.
5571 */
5572 if (found_semicolon && (ulong) (found_semicolon - thd->query().str))
5573 thd->set_query(thd->query().str,
5574 static_cast<size_t>(found_semicolon -
5575 thd->query().str - 1));
5576 /* Actually execute the query */
5577 if (found_semicolon)
5578 {
5579 lex->safe_to_cache_query= 0;
5580 thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
5581 }
5582 lex->set_trg_event_type_for_tables();
5583 MYSQL_QUERY_EXEC_START(
5584 const_cast<char*>(thd->query().str),
5585 thd->thread_id(),
5586 (char *) (thd->db().str ? thd->db().str : ""),
5587 (char *) thd->security_context()->priv_user().str,
5588 (char *) thd->security_context()->host_or_ip().str,
5589 0);
5590 if (unlikely(thd->security_context()->password_expired() &&
5591 !lex->is_set_password_sql &&
5592 lex->sql_command != SQLCOM_SET_OPTION &&
5593 lex->sql_command != SQLCOM_ALTER_USER))
5594 {
5595 my_error(ER_MUST_CHANGE_PASSWORD, MYF(0));
5596 error= 1;
5597 }
5598 else
5599 error= mysql_execute_command(thd, true);
5600
5601 MYSQL_QUERY_EXEC_DONE(error);
5602 }
5603 }
5604 }
5605 else
5606 {
5607 /*
5608 Log the failed raw query in the Performance Schema. This statement did not
5609 parse, so there is no way to tell if it may contain a password of not.
5610
5611 The tradeoff is:
5612 a) If we do log the query, a user typing by accident a broken query
5613 containing a password will have the password exposed. This is very
5614 unlikely, and this behavior can be documented. Remediation is to use
5615 a new password when retyping the corrected query.
5616
5617 b) If we do not log the query, finding broken queries in the client
5618 application will be much more difficult. This is much more likely.
5619
5620 Considering that broken queries can typically be generated by attempts at
5621 SQL injection, finding the source of the SQL injection is critical, so the
5622 design choice is to log the query text of broken queries (a).
5623 */
5624 thd->set_query_for_display(thd->query().str, thd->query().length);
5625
5626 /* Instrument this broken statement as "statement/sql/error" */
5627 thd->m_statement_psi= MYSQL_REFINE_STATEMENT(thd->m_statement_psi,
5628 sql_statement_info[SQLCOM_END].m_key);
5629
5630 assert(thd->is_error());
5631 DBUG_PRINT("info",("Command aborted. Fatal_error: %d",
5632 thd->is_fatal_error));
5633
5634 query_cache.abort(&thd->query_cache_tls);
5635 }
5636
5637 THD_STAGE_INFO(thd, stage_freeing_items);
5638 sp_cache_enforce_limit(thd->sp_proc_cache, stored_program_cache_size);
5639 sp_cache_enforce_limit(thd->sp_func_cache, stored_program_cache_size);
5640 thd->end_statement();
5641 thd->cleanup_after_query();
5642 assert(thd->change_list.is_empty());
5643 }
5644 else
5645 {
5646 /*
5647 Query cache hit. We need to write the general log here if
5648 we haven't already logged the statement earlier due to --log-raw.
5649 Right now, we only cache SELECT results; if the cache ever
5650 becomes more generic, we should also cache the rewritten
5651 query-string together with the original query-string (which
5652 we'd still use for the matching) when we first execute the
5653 query, and then use the obfuscated query-string for logging
5654 here when the query is given again.
5655 */
5656 if (!opt_general_log_raw)
5657 query_logger.general_log_write(thd, COM_QUERY, thd->query().str,
5658 thd->query().length);
5659 parser_state->m_lip.found_semicolon= NULL;
5660 }
5661
5662 DEBUG_SYNC(thd, "query_rewritten");
5663
5664 DBUG_VOID_RETURN;
5665 }
5666
5667
5668 #ifdef HAVE_REPLICATION
5669 /**
5670 Usable by the replication SQL thread only: just parse a query to know if it
5671 can be ignored because of replicate-*-table rules.
5672
5673 @retval
5674 0 cannot be ignored
5675 @retval
5676 1 can be ignored
5677 */
5678
mysql_test_parse_for_slave(THD * thd)5679 bool mysql_test_parse_for_slave(THD *thd)
5680 {
5681 LEX *lex= thd->lex;
5682 bool ignorable= false;
5683 sql_digest_state *parent_digest= thd->m_digest;
5684 PSI_statement_locker *parent_locker= thd->m_statement_psi;
5685 DBUG_ENTER("mysql_test_parse_for_slave");
5686
5687 assert(thd->slave_thread);
5688
5689 Parser_state parser_state;
5690 if (parser_state.init(thd, thd->query().str, thd->query().length) == 0)
5691 {
5692 lex_start(thd);
5693 mysql_reset_thd_for_next_command(thd);
5694
5695 thd->m_digest= NULL;
5696 thd->m_statement_psi= NULL;
5697 if (parse_sql(thd, & parser_state, NULL) == 0)
5698 {
5699 if (all_tables_not_ok(thd, lex->select_lex->table_list.first))
5700 ignorable= true;
5701 else if (!check_database_filters(thd,
5702 thd->db().str,
5703 lex->sql_command))
5704 ignorable= true;
5705 }
5706 thd->m_digest= parent_digest;
5707 thd->m_statement_psi= parent_locker;
5708 thd->end_statement();
5709 }
5710 thd->cleanup_after_query();
5711 DBUG_RETURN(ignorable);
5712 }
5713 #endif
5714
5715
5716
5717 /**
5718 Store field definition for create.
5719
5720 @return
5721 Return 0 if ok
5722 */
5723
add_field_to_list(THD * thd,LEX_STRING * field_name,enum_field_types type,char * length,char * decimals,uint type_modifier,Item * default_value,Item * on_update_value,LEX_STRING * comment,char * change,List<String> * interval_list,const CHARSET_INFO * cs,uint uint_geom_type,Generated_column * gcol_info)5724 bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type,
5725 char *length, char *decimals,
5726 uint type_modifier,
5727 Item *default_value, Item *on_update_value,
5728 LEX_STRING *comment,
5729 char *change,
5730 List<String> *interval_list, const CHARSET_INFO *cs,
5731 uint uint_geom_type,
5732 Generated_column *gcol_info)
5733 {
5734 Create_field *new_field;
5735 LEX *lex= thd->lex;
5736 uint8 datetime_precision= decimals ? atoi(decimals) : 0;
5737 DBUG_ENTER("add_field_to_list");
5738
5739 LEX_CSTRING field_name_cstr= {field_name->str, field_name->length};
5740
5741 if (check_string_char_length(field_name_cstr, "", NAME_CHAR_LEN,
5742 system_charset_info, 1))
5743 {
5744 my_error(ER_TOO_LONG_IDENT, MYF(0), field_name->str); /* purecov: inspected */
5745 DBUG_RETURN(1); /* purecov: inspected */
5746 }
5747 if (type_modifier & PRI_KEY_FLAG)
5748 {
5749 Key *key;
5750 lex->col_list.push_back(new Key_part_spec(*field_name, 0));
5751 key= new Key(KEYTYPE_PRIMARY, null_lex_str,
5752 &default_key_create_info,
5753 0, lex->col_list);
5754 lex->alter_info.key_list.push_back(key);
5755 lex->col_list.empty();
5756 }
5757 if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG))
5758 {
5759 Key *key;
5760 lex->col_list.push_back(new Key_part_spec(*field_name, 0));
5761 key= new Key(KEYTYPE_UNIQUE, null_lex_str,
5762 &default_key_create_info, 0,
5763 lex->col_list);
5764 lex->alter_info.key_list.push_back(key);
5765 lex->col_list.empty();
5766 }
5767
5768 if (default_value)
5769 {
5770 /*
5771 Default value should be literal => basic constants =>
5772 no need fix_fields()
5773
5774 We allow only CURRENT_TIMESTAMP as function default for the TIMESTAMP or
5775 DATETIME types.
5776 */
5777 if (default_value->type() == Item::FUNC_ITEM &&
5778 (static_cast<Item_func*>(default_value)->functype() !=
5779 Item_func::NOW_FUNC ||
5780 (!real_type_with_now_as_default(type)) ||
5781 default_value->decimals != datetime_precision))
5782 {
5783 my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
5784 DBUG_RETURN(1);
5785 }
5786 else if (default_value->type() == Item::NULL_ITEM)
5787 {
5788 default_value= 0;
5789 if ((type_modifier & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) ==
5790 NOT_NULL_FLAG)
5791 {
5792 my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
5793 DBUG_RETURN(1);
5794 }
5795 }
5796 else if (type_modifier & AUTO_INCREMENT_FLAG)
5797 {
5798 my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
5799 DBUG_RETURN(1);
5800 }
5801 }
5802
5803 if (on_update_value &&
5804 (!real_type_with_now_on_update(type) ||
5805 on_update_value->decimals != datetime_precision))
5806 {
5807 my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name->str);
5808 DBUG_RETURN(1);
5809 }
5810
5811 if (!(new_field= new Create_field()) ||
5812 new_field->init(thd, field_name->str, type, length, decimals, type_modifier,
5813 default_value, on_update_value, comment, change,
5814 interval_list, cs, uint_geom_type, gcol_info))
5815 DBUG_RETURN(1);
5816
5817 lex->alter_info.create_list.push_back(new_field);
5818 lex->last_field=new_field;
5819 DBUG_RETURN(0);
5820 }
5821
5822
5823 /** Store position for column in ALTER TABLE .. ADD column. */
5824
store_position_for_column(const char * name)5825 void store_position_for_column(const char *name)
5826 {
5827 current_thd->lex->last_field->after=(char*) (name);
5828 }
5829
5830
5831 /**
5832 save order by and tables in own lists.
5833 */
5834
add_to_list(SQL_I_List<ORDER> & list,ORDER * order)5835 void add_to_list(SQL_I_List<ORDER> &list, ORDER *order)
5836 {
5837 DBUG_ENTER("add_to_list");
5838 order->item= &order->item_ptr;
5839 order->used_alias= false;
5840 order->used=0;
5841 list.link_in_list(order, &order->next);
5842 DBUG_VOID_RETURN;
5843 }
5844
5845
5846 /**
5847 Add a table to list of used tables.
5848
5849 @param table Table to add
5850 @param alias alias for table (or null if no alias)
5851 @param table_options A set of the following bits:
5852 - TL_OPTION_UPDATING : Table will be updated
5853 - TL_OPTION_FORCE_INDEX : Force usage of index
5854 - TL_OPTION_ALIAS : an alias in multi table DELETE
5855 @param lock_type How table should be locked
5856 @param mdl_type Type of metadata lock to acquire on the table.
5857 @param use_index List of indexed used in USE INDEX
5858 @param ignore_index List of indexed used in IGNORE INDEX
5859
5860 @retval
5861 0 Error
5862 @retval
5863 \# Pointer to TABLE_LIST element added to the total table list
5864 */
5865
add_table_to_list(THD * thd,Table_ident * table,LEX_STRING * alias,ulong table_options,thr_lock_type lock_type,enum_mdl_type mdl_type,List<Index_hint> * index_hints_arg,List<String> * partition_names,LEX_STRING * option)5866 TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
5867 Table_ident *table,
5868 LEX_STRING *alias,
5869 ulong table_options,
5870 thr_lock_type lock_type,
5871 enum_mdl_type mdl_type,
5872 List<Index_hint> *index_hints_arg,
5873 List<String> *partition_names,
5874 LEX_STRING *option)
5875 {
5876 TABLE_LIST *ptr;
5877 TABLE_LIST *previous_table_ref= NULL; /* The table preceding the current one. */
5878 const char *alias_str;
5879 LEX *lex= thd->lex;
5880 DBUG_ENTER("add_table_to_list");
5881
5882 if (!table)
5883 DBUG_RETURN(0); // End of memory
5884 alias_str= alias ? alias->str : table->table.str;
5885 if (!MY_TEST(table_options & TL_OPTION_ALIAS))
5886 {
5887 enum_ident_name_check ident_check_status=
5888 check_table_name(table->table.str, table->table.length, FALSE);
5889 if (ident_check_status == IDENT_NAME_WRONG)
5890 {
5891 my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
5892 DBUG_RETURN(0);
5893 }
5894 else if (ident_check_status == IDENT_NAME_TOO_LONG)
5895 {
5896 my_error(ER_TOO_LONG_IDENT, MYF(0), table->table.str);
5897 DBUG_RETURN(0);
5898 }
5899 }
5900 LEX_STRING db= to_lex_string(table->db);
5901 if (table->is_derived_table() == FALSE && table->db.str &&
5902 (check_and_convert_db_name(&db, FALSE) != IDENT_NAME_OK))
5903 DBUG_RETURN(0);
5904
5905 if (!alias) /* Alias is case sensitive */
5906 {
5907 if (table->sel)
5908 {
5909 my_message(ER_DERIVED_MUST_HAVE_ALIAS,
5910 ER(ER_DERIVED_MUST_HAVE_ALIAS), MYF(0));
5911 DBUG_RETURN(0);
5912 }
5913 if (!(alias_str= (char*) thd->memdup(alias_str,table->table.length+1)))
5914 DBUG_RETURN(0);
5915 }
5916 if (!(ptr = (TABLE_LIST *) thd->mem_calloc(sizeof(TABLE_LIST))))
5917 DBUG_RETURN(0); /* purecov: inspected */
5918 if (table->db.str)
5919 {
5920 ptr->is_fqtn= TRUE;
5921 ptr->db= const_cast<char*>(table->db.str);
5922 ptr->db_length= table->db.length;
5923 }
5924 else if (lex->copy_db_to((char**)&ptr->db, &ptr->db_length))
5925 DBUG_RETURN(0);
5926 else
5927 ptr->is_fqtn= FALSE;
5928
5929 ptr->alias= const_cast<char*>(alias_str);
5930 ptr->is_alias= alias ? TRUE : FALSE;
5931 if (lower_case_table_names && table->table.length)
5932 table->table.length= my_casedn_str(files_charset_info,
5933 const_cast<char*>(table->table.str));
5934 ptr->table_name= const_cast<char*>(table->table.str);
5935 ptr->table_name_length= table->table.length;
5936 ptr->set_tableno(0);
5937 ptr->lock_type= lock_type;
5938 ptr->updating= MY_TEST(table_options & TL_OPTION_UPDATING);
5939 /* TODO: remove TL_OPTION_FORCE_INDEX as it looks like it's not used */
5940 ptr->force_index= MY_TEST(table_options & TL_OPTION_FORCE_INDEX);
5941 ptr->ignore_leaves= MY_TEST(table_options & TL_OPTION_IGNORE_LEAVES);
5942 ptr->set_derived_unit(table->sel);
5943 if (!ptr->is_derived() && is_infoschema_db(ptr->db, ptr->db_length))
5944 {
5945 ST_SCHEMA_TABLE *schema_table;
5946 if (ptr->updating &&
5947 /* Special cases which are processed by commands itself */
5948 lex->sql_command != SQLCOM_CHECK &&
5949 lex->sql_command != SQLCOM_CHECKSUM)
5950 {
5951 my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
5952 thd->security_context()->priv_user().str,
5953 thd->security_context()->priv_host().str,
5954 INFORMATION_SCHEMA_NAME.str);
5955 DBUG_RETURN(0);
5956 }
5957 schema_table= find_schema_table(thd, ptr->table_name);
5958 if (!schema_table ||
5959 (schema_table->hidden &&
5960 ((sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0 ||
5961 /*
5962 this check is used for show columns|keys from I_S hidden table
5963 */
5964 lex->sql_command == SQLCOM_SHOW_FIELDS ||
5965 lex->sql_command == SQLCOM_SHOW_KEYS)))
5966 {
5967 my_error(ER_UNKNOWN_TABLE, MYF(0),
5968 ptr->table_name, INFORMATION_SCHEMA_NAME.str);
5969 DBUG_RETURN(0);
5970 }
5971 ptr->schema_table_name= const_cast<char*>(ptr->table_name);
5972 ptr->schema_table= schema_table;
5973 }
5974 ptr->select_lex= this;
5975 ptr->cacheable_table= 1;
5976 ptr->index_hints= index_hints_arg;
5977 ptr->option= option ? option->str : 0;
5978 /* check that used name is unique */
5979 if (lock_type != TL_IGNORE)
5980 {
5981 TABLE_LIST *first_table= table_list.first;
5982 if (lex->sql_command == SQLCOM_CREATE_VIEW)
5983 first_table= first_table ? first_table->next_local : NULL;
5984 for (TABLE_LIST *tables= first_table ;
5985 tables ;
5986 tables=tables->next_local)
5987 {
5988 if (!my_strcasecmp(table_alias_charset, alias_str, tables->alias) &&
5989 !strcmp(ptr->db, tables->db))
5990 {
5991 my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str); /* purecov: tested */
5992 DBUG_RETURN(0); /* purecov: tested */
5993 }
5994 }
5995 }
5996 /* Store the table reference preceding the current one. */
5997 if (table_list.elements > 0)
5998 {
5999 /*
6000 table_list.next points to the last inserted TABLE_LIST->next_local'
6001 element
6002 We don't use the offsetof() macro here to avoid warnings from gcc
6003 */
6004 previous_table_ref= (TABLE_LIST*) ((char*) table_list.next -
6005 ((char*) &(ptr->next_local) -
6006 (char*) ptr));
6007 /*
6008 Set next_name_resolution_table of the previous table reference to point
6009 to the current table reference. In effect the list
6010 TABLE_LIST::next_name_resolution_table coincides with
6011 TABLE_LIST::next_local. Later this may be changed in
6012 store_top_level_join_columns() for NATURAL/USING joins.
6013 */
6014 previous_table_ref->next_name_resolution_table= ptr;
6015 }
6016
6017 /*
6018 Link the current table reference in a local list (list for current select).
6019 Notice that as a side effect here we set the next_local field of the
6020 previous table reference to 'ptr'. Here we also add one element to the
6021 list 'table_list'.
6022 */
6023 table_list.link_in_list(ptr, &ptr->next_local);
6024 ptr->next_name_resolution_table= NULL;
6025 ptr->partition_names= partition_names;
6026 /* Link table in global list (all used tables) */
6027 lex->add_to_query_tables(ptr);
6028
6029 // Pure table aliases do not need to be locked:
6030 if (!MY_TEST(table_options & TL_OPTION_ALIAS))
6031 {
6032 MDL_REQUEST_INIT(& ptr->mdl_request,
6033 MDL_key::TABLE, ptr->db, ptr->table_name, mdl_type,
6034 MDL_TRANSACTION);
6035 }
6036 if (table->is_derived_table())
6037 {
6038 ptr->derived_key_list.empty();
6039 derived_table_count++;
6040 }
6041 DBUG_RETURN(ptr);
6042 }
6043
6044
6045 /**
6046 Initialize a new table list for a nested join.
6047
6048 The function initializes a structure of the TABLE_LIST type
6049 for a nested join. It sets up its nested join list as empty.
6050 The created structure is added to the front of the current
6051 join list in the st_select_lex object. Then the function
6052 changes the current nest level for joins to refer to the newly
6053 created empty list after having saved the info on the old level
6054 in the initialized structure.
6055
6056 @param thd current thread
6057
6058 @retval
6059 0 if success
6060 @retval
6061 1 otherwise
6062 */
6063
init_nested_join(THD * thd)6064 bool st_select_lex::init_nested_join(THD *thd)
6065 {
6066 DBUG_ENTER("init_nested_join");
6067
6068 TABLE_LIST *const ptr=
6069 TABLE_LIST::new_nested_join(thd->mem_root, "(nested_join)",
6070 embedding, join_list, this);
6071 if (ptr == NULL)
6072 DBUG_RETURN(true);
6073
6074 join_list->push_front(ptr);
6075 embedding= ptr;
6076 join_list= &ptr->nested_join->join_list;
6077
6078 DBUG_RETURN(false);
6079 }
6080
6081
6082 /**
6083 End a nested join table list.
6084
6085 The function returns to the previous join nest level.
6086 If the current level contains only one member, the function
6087 moves it one level up, eliminating the nest.
6088
6089 @param thd current thread
6090
6091 @return
6092 - Pointer to TABLE_LIST element added to the total table list, if success
6093 - 0, otherwise
6094 */
6095
end_nested_join(THD * thd)6096 TABLE_LIST *st_select_lex::end_nested_join(THD *thd)
6097 {
6098 TABLE_LIST *ptr;
6099 NESTED_JOIN *nested_join;
6100 DBUG_ENTER("end_nested_join");
6101
6102 assert(embedding);
6103 ptr= embedding;
6104 join_list= ptr->join_list;
6105 embedding= ptr->embedding;
6106 nested_join= ptr->nested_join;
6107 if (nested_join->join_list.elements == 1)
6108 {
6109 TABLE_LIST *embedded= nested_join->join_list.head();
6110 join_list->pop();
6111 embedded->join_list= join_list;
6112 embedded->embedding= embedding;
6113 join_list->push_front(embedded);
6114 ptr= embedded;
6115 }
6116 else if (nested_join->join_list.elements == 0)
6117 {
6118 join_list->pop();
6119 ptr= 0; // return value
6120 }
6121 DBUG_RETURN(ptr);
6122 }
6123
6124
6125 /**
6126 Nest last join operation.
6127
6128 The function nest last join operation as if it was enclosed in braces.
6129
6130 @param thd current thread
6131
6132 @retval
6133 0 Error
6134 @retval
6135 \# Pointer to TABLE_LIST element created for the new nested join
6136 */
6137
nest_last_join(THD * thd)6138 TABLE_LIST *st_select_lex::nest_last_join(THD *thd)
6139 {
6140 DBUG_ENTER("nest_last_join");
6141
6142 TABLE_LIST *const ptr=
6143 TABLE_LIST::new_nested_join(thd->mem_root, "(nest_last_join)",
6144 embedding, join_list, this);
6145 if (ptr == NULL)
6146 DBUG_RETURN(NULL);
6147
6148 List<TABLE_LIST> *const embedded_list= &ptr->nested_join->join_list;
6149
6150 for (uint i=0; i < 2; i++)
6151 {
6152 TABLE_LIST *table= join_list->pop();
6153 table->join_list= embedded_list;
6154 table->embedding= ptr;
6155 embedded_list->push_back(table);
6156 if (table->natural_join)
6157 {
6158 ptr->is_natural_join= TRUE;
6159 /*
6160 If this is a JOIN ... USING, move the list of joined fields to the
6161 table reference that describes the join.
6162 */
6163 if (prev_join_using)
6164 ptr->join_using_fields= prev_join_using;
6165 }
6166 }
6167 join_list->push_front(ptr);
6168
6169 DBUG_RETURN(ptr);
6170 }
6171
6172
6173 /**
6174 Add a table to the current join list.
6175
6176 The function puts a table in front of the current join list
6177 of st_select_lex object.
6178 Thus, joined tables are put into this list in the reverse order
6179 (the most outer join operation follows first).
6180
6181 @param table the table to add
6182
6183 @return
6184 None
6185 */
6186
add_joined_table(TABLE_LIST * table)6187 void st_select_lex::add_joined_table(TABLE_LIST *table)
6188 {
6189 DBUG_ENTER("add_joined_table");
6190 join_list->push_front(table);
6191 table->join_list= join_list;
6192 table->embedding= embedding;
6193 DBUG_VOID_RETURN;
6194 }
6195
6196
6197 /**
6198 Convert a right join into equivalent left join.
6199
6200 The function takes the current join list t[0],t[1] ... and
6201 effectively converts it into the list t[1],t[0] ...
6202 Although the outer_join flag for the new nested table contains
6203 JOIN_TYPE_RIGHT, it will be handled as the inner table of a left join
6204 operation.
6205
6206 EXAMPLES
6207 @verbatim
6208 SELECT * FROM t1 RIGHT JOIN t2 ON on_expr =>
6209 SELECT * FROM t2 LEFT JOIN t1 ON on_expr
6210
6211 SELECT * FROM t1,t2 RIGHT JOIN t3 ON on_expr =>
6212 SELECT * FROM t1,t3 LEFT JOIN t2 ON on_expr
6213
6214 SELECT * FROM t1,t2 RIGHT JOIN (t3,t4) ON on_expr =>
6215 SELECT * FROM t1,(t3,t4) LEFT JOIN t2 ON on_expr
6216
6217 SELECT * FROM t1 LEFT JOIN t2 ON on_expr1 RIGHT JOIN t3 ON on_expr2 =>
6218 SELECT * FROM t3 LEFT JOIN (t1 LEFT JOIN t2 ON on_expr2) ON on_expr1
6219 @endverbatim
6220
6221 @param thd current thread
6222
6223 @return
6224 - Pointer to the table representing the inner table, if success
6225 - 0, otherwise
6226 */
6227
convert_right_join()6228 TABLE_LIST *st_select_lex::convert_right_join()
6229 {
6230 TABLE_LIST *tab2= join_list->pop();
6231 TABLE_LIST *tab1= join_list->pop();
6232 DBUG_ENTER("convert_right_join");
6233
6234 join_list->push_front(tab2);
6235 join_list->push_front(tab1);
6236 tab1->outer_join|= JOIN_TYPE_RIGHT;
6237
6238 DBUG_RETURN(tab1);
6239 }
6240
6241 /**
6242 Set lock for all tables in current select level.
6243
6244 @param lock_type Lock to set for tables
6245
6246 @note
6247 If lock is a write lock, then tables->updating is set 1
6248 This is to get tables_ok to know that the table is updated by the
6249 query
6250 Set type of metadata lock to request according to lock_type.
6251 */
6252
set_lock_for_tables(thr_lock_type lock_type)6253 void st_select_lex::set_lock_for_tables(thr_lock_type lock_type)
6254 {
6255 bool for_update= lock_type >= TL_READ_NO_INSERT;
6256 enum_mdl_type mdl_type= mdl_type_for_dml(lock_type);
6257 DBUG_ENTER("set_lock_for_tables");
6258 DBUG_PRINT("enter", ("lock_type: %d for_update: %d", lock_type,
6259 for_update));
6260 for (TABLE_LIST *tables= table_list.first;
6261 tables;
6262 tables= tables->next_local)
6263 {
6264 tables->lock_type= lock_type;
6265 tables->updating= for_update;
6266 tables->mdl_request.set_type(mdl_type);
6267 }
6268 DBUG_VOID_RETURN;
6269 }
6270
6271
6272 /**
6273 Create a fake SELECT_LEX for a unit.
6274
6275 The method create a fake SELECT_LEX object for a unit.
6276 This object is created for any union construct containing a union
6277 operation and also for any single select union construct of the form
6278 @verbatim
6279 (SELECT ... ORDER BY order_list [LIMIT n]) ORDER BY ...
6280 @endvarbatim
6281 or of the form
6282 @varbatim
6283 (SELECT ... ORDER BY LIMIT n) ORDER BY ...
6284 @endvarbatim
6285
6286 @param thd_arg thread handle
6287
6288 @note
6289 The object is used to retrieve rows from the temporary table
6290 where the result on the union is obtained.
6291
6292 @retval
6293 1 on failure to create the object
6294 @retval
6295 0 on success
6296 */
6297
add_fake_select_lex(THD * thd_arg)6298 bool st_select_lex_unit::add_fake_select_lex(THD *thd_arg)
6299 {
6300 SELECT_LEX *first_sl= first_select();
6301 DBUG_ENTER("add_fake_select_lex");
6302 assert(!fake_select_lex);
6303 assert(thd_arg == thd);
6304
6305 if (!(fake_select_lex= thd_arg->lex->new_empty_query_block()))
6306 DBUG_RETURN(true); /* purecov: inspected */
6307 fake_select_lex->include_standalone(this, &fake_select_lex);
6308 fake_select_lex->select_number= INT_MAX;
6309 fake_select_lex->linkage= GLOBAL_OPTIONS_TYPE;
6310 fake_select_lex->select_limit= 0;
6311
6312 fake_select_lex->set_context(first_sl->context.outer_context);
6313
6314 /* allow item list resolving in fake select for ORDER BY */
6315 fake_select_lex->context.resolve_in_select_list= TRUE;
6316
6317 if (!is_union())
6318 {
6319 /*
6320 This works only for
6321 (SELECT ... ORDER BY list [LIMIT n]) ORDER BY order_list [LIMIT m],
6322 (SELECT ... LIMIT n) ORDER BY order_list [LIMIT m]
6323 just before the parser starts processing order_list
6324 */
6325 fake_select_lex->no_table_names_allowed= 1;
6326 }
6327 thd->lex->pop_context();
6328 DBUG_RETURN(false);
6329 }
6330
6331
6332 /**
6333 Push a new name resolution context for a JOIN ... ON clause to the
6334 context stack of a query block.
6335
6336 Create a new name resolution context for a JOIN ... ON clause,
6337 set the first and last leaves of the list of table references
6338 to be used for name resolution, and push the newly created
6339 context to the stack of contexts of the query.
6340
6341 @param pc current parse context
6342 @param left_op left operand of the JOIN
6343 @param right_op rigth operand of the JOIN
6344
6345 @todo Research if we should set the "outer_context" member of the new ON
6346 context.
6347
6348 @retval
6349 FALSE if all is OK
6350 @retval
6351 TRUE if a memory allocation error occured
6352 */
6353
6354 bool
push_new_name_resolution_context(Parse_context * pc,TABLE_LIST * left_op,TABLE_LIST * right_op)6355 push_new_name_resolution_context(Parse_context *pc,
6356 TABLE_LIST *left_op, TABLE_LIST *right_op)
6357 {
6358 THD *thd= pc->thd;
6359 Name_resolution_context *on_context;
6360 if (!(on_context= new (thd->mem_root) Name_resolution_context))
6361 return TRUE;
6362 on_context->init();
6363 on_context->first_name_resolution_table=
6364 left_op->first_leaf_for_name_resolution();
6365 on_context->last_name_resolution_table=
6366 right_op->last_leaf_for_name_resolution();
6367 on_context->select_lex= pc->select;
6368 on_context->next_context= pc->select->first_context;
6369 pc->select->first_context= on_context;
6370
6371 return thd->lex->push_context(on_context);
6372 }
6373
6374
6375 /**
6376 Add an ON condition to the second operand of a JOIN ... ON.
6377
6378 Add an ON condition to the right operand of a JOIN ... ON clause.
6379
6380 @param b the second operand of a JOIN ... ON
6381 @param expr the condition to be added to the ON clause
6382 */
6383
add_join_on(TABLE_LIST * b,Item * expr)6384 void add_join_on(TABLE_LIST *b, Item *expr)
6385 {
6386 if (expr)
6387 {
6388 b->set_join_cond_optim((Item*)1); // m_join_cond_optim is not ready
6389 if (!b->join_cond())
6390 b->set_join_cond(expr);
6391 else
6392 {
6393 /*
6394 If called from the parser, this happens if you have both a
6395 right and left join. If called later, it happens if we add more
6396 than one condition to the ON clause.
6397 */
6398 b->set_join_cond(new Item_cond_and(b->join_cond(), expr));
6399 }
6400 b->join_cond()->top_level_item();
6401 }
6402 }
6403
6404
6405 /**
6406 Mark that there is a NATURAL JOIN or JOIN ... USING between two
6407 tables.
6408
6409 This function marks that table b should be joined with a either via
6410 a NATURAL JOIN or via JOIN ... USING. Both join types are special
6411 cases of each other, so we treat them together. The function
6412 setup_conds() creates a list of equal condition between all fields
6413 of the same name for NATURAL JOIN or the fields in 'using_fields'
6414 for JOIN ... USING. The list of equality conditions is stored
6415 either in b->join_cond(), or in JOIN::conds, depending on whether there
6416 was an outer join.
6417
6418 EXAMPLE
6419 @verbatim
6420 SELECT * FROM t1 NATURAL LEFT JOIN t2
6421 <=>
6422 SELECT * FROM t1 LEFT JOIN t2 ON (t1.i=t2.i and t1.j=t2.j ... )
6423
6424 SELECT * FROM t1 NATURAL JOIN t2 WHERE <some_cond>
6425 <=>
6426 SELECT * FROM t1, t2 WHERE (t1.i=t2.i and t1.j=t2.j and <some_cond>)
6427
6428 SELECT * FROM t1 JOIN t2 USING(j) WHERE <some_cond>
6429 <=>
6430 SELECT * FROM t1, t2 WHERE (t1.j=t2.j and <some_cond>)
6431 @endverbatim
6432
6433 @param a Left join argument
6434 @param b Right join argument
6435 @param using_fields Field names from USING clause
6436 */
6437
add_join_natural(TABLE_LIST * a,TABLE_LIST * b,List<String> * using_fields,SELECT_LEX * lex)6438 void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List<String> *using_fields,
6439 SELECT_LEX *lex)
6440 {
6441 b->natural_join= a;
6442 lex->prev_join_using= using_fields;
6443 }
6444
6445
6446 /**
6447 kill on thread.
6448
6449 @param thd Thread class
6450 @param id Thread id
6451 @param only_kill_query Should it kill the query or the connection
6452
6453 @note
6454 This is written such that we have a short lock on LOCK_thd_list
6455 */
6456
6457
kill_one_thread(THD * thd,my_thread_id id,bool only_kill_query)6458 static uint kill_one_thread(THD *thd, my_thread_id id, bool only_kill_query)
6459 {
6460 THD *tmp= NULL;
6461 uint error=ER_NO_SUCH_THREAD;
6462 Find_thd_with_id find_thd_with_id(id);
6463
6464 DBUG_ENTER("kill_one_thread");
6465 DBUG_PRINT("enter", ("id=%u only_kill=%d", id, only_kill_query));
6466 tmp= Global_THD_manager::get_instance()->find_thd(&find_thd_with_id);
6467 if (tmp)
6468 {
6469 /*
6470 If we're SUPER, we can KILL anything, including system-threads.
6471 No further checks.
6472
6473 KILLer: thd->m_security_ctx->user could in theory be NULL while
6474 we're still in "unauthenticated" state. This is a theoretical
6475 case (the code suggests this could happen, so we play it safe).
6476
6477 KILLee: tmp->m_security_ctx->user will be NULL for system threads.
6478 We need to check so Jane Random User doesn't crash the server
6479 when trying to kill a) system threads or b) unauthenticated users'
6480 threads (Bug#43748).
6481
6482 If user of both killer and killee are non-NULL, proceed with
6483 slayage if both are string-equal.
6484 */
6485
6486 if ((thd->security_context()->check_access(SUPER_ACL)) ||
6487 thd->security_context()->user_matches(tmp->security_context()))
6488 {
6489 /* process the kill only if thread is not already undergoing any kill
6490 connection.
6491 */
6492 if (tmp->killed != THD::KILL_CONNECTION)
6493 {
6494 tmp->awake(only_kill_query ? THD::KILL_QUERY : THD::KILL_CONNECTION);
6495 }
6496 error= 0;
6497 }
6498 else
6499 error=ER_KILL_DENIED_ERROR;
6500 mysql_mutex_unlock(&tmp->LOCK_thd_data);
6501 }
6502 DEBUG_SYNC(thd, "kill_thd_end");
6503 DBUG_PRINT("exit", ("%d", error));
6504 DBUG_RETURN(error);
6505 }
6506
6507
6508 /*
6509 kills a thread and sends response
6510
6511 SYNOPSIS
6512 sql_kill()
6513 thd Thread class
6514 id Thread id
6515 only_kill_query Should it kill the query or the connection
6516 */
6517
6518 static
sql_kill(THD * thd,my_thread_id id,bool only_kill_query)6519 void sql_kill(THD *thd, my_thread_id id, bool only_kill_query)
6520 {
6521 uint error;
6522 if (!(error= kill_one_thread(thd, id, only_kill_query)))
6523 {
6524 if (! thd->killed)
6525 my_ok(thd);
6526 }
6527 else
6528 my_error(error, MYF(0), id);
6529 }
6530
6531 /**
6532 This class implements callback function used by killall_non_super_threads
6533 to kill all threads that do not have the SUPER privilege
6534 */
6535
6536 class Kill_non_super_conn : public Do_THD_Impl
6537 {
6538 private:
6539 /* THD of connected client. */
6540 THD *m_client_thd;
6541
6542 public:
Kill_non_super_conn(THD * thd)6543 Kill_non_super_conn(THD *thd) :
6544 m_client_thd(thd)
6545 {
6546 assert(m_client_thd->security_context()->check_access(SUPER_ACL));
6547 }
6548
operator ()(THD * thd_to_kill)6549 virtual void operator()(THD *thd_to_kill)
6550 {
6551 mysql_mutex_lock(&thd_to_kill->LOCK_thd_data);
6552
6553 /* Kill only if non super thread and non slave thread.
6554 If an account has not yet been assigned to the security context of the
6555 thread we cannot tell if the account is super user or not. In this case
6556 we cannot kill that thread. In offline mode, after the account is
6557 assigned to this thread and it turns out it is not super user thread,
6558 the authentication for this thread will fail and the thread will be
6559 terminated.
6560 */
6561 if (thd_to_kill->security_context()->has_account_assigned()
6562 && !(thd_to_kill->security_context()->check_access(SUPER_ACL))
6563 && thd_to_kill->killed != THD::KILL_CONNECTION
6564 && !thd_to_kill->slave_thread)
6565 thd_to_kill->awake(THD::KILL_CONNECTION);
6566
6567 mysql_mutex_unlock(&thd_to_kill->LOCK_thd_data);
6568 }
6569 };
6570
6571 /*
6572 kills all the threads that do not have the
6573 SUPER privilege.
6574
6575 SYNOPSIS
6576 killall_non_super_threads()
6577 thd Thread class
6578 */
6579
killall_non_super_threads(THD * thd)6580 void killall_non_super_threads(THD *thd)
6581 {
6582 Kill_non_super_conn kill_non_super_conn(thd);
6583 Global_THD_manager *thd_manager= Global_THD_manager::get_instance();
6584 thd_manager->do_for_all_thd(&kill_non_super_conn);
6585 }
6586
6587 /** If pointer is not a null pointer, append filename to it. */
6588
append_file_to_dir(THD * thd,const char ** filename_ptr,const char * table_name)6589 bool append_file_to_dir(THD *thd, const char **filename_ptr,
6590 const char *table_name)
6591 {
6592 char buff[FN_REFLEN],*ptr, *end;
6593 if (!*filename_ptr)
6594 return 0; // nothing to do
6595
6596 /* Check that the filename is not too long and it's a hard path */
6597 if (strlen(*filename_ptr)+strlen(table_name) >= FN_REFLEN-1 ||
6598 !test_if_hard_path(*filename_ptr))
6599 {
6600 my_error(ER_WRONG_TABLE_NAME, MYF(0), *filename_ptr);
6601 return 1;
6602 }
6603 /* Fix is using unix filename format on dos */
6604 my_stpcpy(buff,*filename_ptr);
6605 end=convert_dirname(buff, *filename_ptr, NullS);
6606 if (!(ptr= (char*) thd->alloc((size_t) (end-buff) + strlen(table_name)+1)))
6607 return 1; // End of memory
6608 *filename_ptr=ptr;
6609 strxmov(ptr,buff,table_name,NullS);
6610 return 0;
6611 }
6612
6613
comp_eq_creator(bool invert)6614 Comp_creator *comp_eq_creator(bool invert)
6615 {
6616 return invert?(Comp_creator *)&ne_creator:(Comp_creator *)&eq_creator;
6617 }
6618
comp_equal_creator(bool invert)6619 Comp_creator *comp_equal_creator(bool invert)
6620 {
6621 assert(!invert); // Function never called with true.
6622 return &equal_creator;
6623 }
6624
6625
comp_ge_creator(bool invert)6626 Comp_creator *comp_ge_creator(bool invert)
6627 {
6628 return invert?(Comp_creator *)<_creator:(Comp_creator *)&ge_creator;
6629 }
6630
6631
comp_gt_creator(bool invert)6632 Comp_creator *comp_gt_creator(bool invert)
6633 {
6634 return invert?(Comp_creator *)&le_creator:(Comp_creator *)>_creator;
6635 }
6636
6637
comp_le_creator(bool invert)6638 Comp_creator *comp_le_creator(bool invert)
6639 {
6640 return invert?(Comp_creator *)>_creator:(Comp_creator *)&le_creator;
6641 }
6642
6643
comp_lt_creator(bool invert)6644 Comp_creator *comp_lt_creator(bool invert)
6645 {
6646 return invert?(Comp_creator *)&ge_creator:(Comp_creator *)<_creator;
6647 }
6648
6649
comp_ne_creator(bool invert)6650 Comp_creator *comp_ne_creator(bool invert)
6651 {
6652 return invert?(Comp_creator *)&eq_creator:(Comp_creator *)&ne_creator;
6653 }
6654
6655
6656 /**
6657 Construct ALL/ANY/SOME subquery Item.
6658
6659 @param left_expr pointer to left expression
6660 @param cmp compare function creator
6661 @param all true if we create ALL subquery
6662 @param select_lex pointer on parsed subquery structure
6663
6664 @return
6665 constructed Item (or 0 if out of memory)
6666 */
all_any_subquery_creator(Item * left_expr,chooser_compare_func_creator cmp,bool all,SELECT_LEX * select_lex)6667 Item * all_any_subquery_creator(Item *left_expr,
6668 chooser_compare_func_creator cmp,
6669 bool all,
6670 SELECT_LEX *select_lex)
6671 {
6672 if ((cmp == &comp_eq_creator) && !all) // = ANY <=> IN
6673 return new Item_in_subselect(left_expr, select_lex);
6674
6675 if ((cmp == &comp_ne_creator) && all) // <> ALL <=> NOT IN
6676 return new Item_func_not(new Item_in_subselect(left_expr, select_lex));
6677
6678 Item_allany_subselect *it=
6679 new Item_allany_subselect(left_expr, cmp, select_lex, all);
6680 if (all)
6681 return it->upper_item= new Item_func_not_all(it); /* ALL */
6682
6683 return it->upper_item= new Item_func_nop_all(it); /* ANY/SOME */
6684 }
6685
6686
6687 /**
6688 Set proper open mode and table type for element representing target table
6689 of CREATE TABLE statement, also adjust statement table list if necessary.
6690 */
6691
create_table_set_open_action_and_adjust_tables(LEX * lex)6692 void create_table_set_open_action_and_adjust_tables(LEX *lex)
6693 {
6694 TABLE_LIST *create_table= lex->query_tables;
6695
6696 if (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)
6697 create_table->open_type= OT_TEMPORARY_ONLY;
6698 else
6699 create_table->open_type= OT_BASE_ONLY;
6700
6701 if (!lex->select_lex->item_list.elements)
6702 {
6703 /*
6704 Avoid opening and locking target table for ordinary CREATE TABLE
6705 or CREATE TABLE LIKE for write (unlike in CREATE ... SELECT we
6706 won't do any insertions in it anyway). Not doing this causes
6707 problems when running CREATE TABLE IF NOT EXISTS for already
6708 existing log table.
6709 */
6710 create_table->lock_type= TL_READ;
6711 }
6712 }
6713
6714
6715 /**
6716 negate given expression.
6717
6718 @param pc current parse context
6719 @param expr expression for negation
6720
6721 @return
6722 negated expression
6723 */
6724
negate_expression(Parse_context * pc,Item * expr)6725 Item *negate_expression(Parse_context *pc, Item *expr)
6726 {
6727 Item *negated;
6728 if (expr->type() == Item::FUNC_ITEM &&
6729 ((Item_func *) expr)->functype() == Item_func::NOT_FUNC)
6730 {
6731 /* it is NOT(NOT( ... )) */
6732 Item *arg= ((Item_func *) expr)->arguments()[0];
6733 enum_parsing_context place= pc->select->parsing_place;
6734 if (arg->is_bool_func() || place == CTX_WHERE || place == CTX_HAVING)
6735 return arg;
6736 /*
6737 if it is not boolean function then we have to emulate value of
6738 not(not(a)), it will be a != 0
6739 */
6740 return new Item_func_ne(arg, new Item_int_0());
6741 }
6742
6743 if ((negated= expr->neg_transformer(pc->thd)) != 0)
6744 return negated;
6745 return new Item_func_not(expr);
6746 }
6747
6748 /**
6749 Set the specified definer to the default value, which is the
6750 current user in the thread.
6751
6752 @param[in] thd thread handler
6753 @param[out] definer definer
6754 */
6755
get_default_definer(THD * thd,LEX_USER * definer)6756 void get_default_definer(THD *thd, LEX_USER *definer)
6757 {
6758 const Security_context *sctx= thd->security_context();
6759
6760 definer->user.str= (char *) sctx->priv_user().str;
6761 definer->user.length= strlen(definer->user.str);
6762
6763 definer->host.str= (char *) sctx->priv_host().str;
6764 definer->host.length= strlen(definer->host.str);
6765
6766 definer->plugin= EMPTY_CSTR;
6767 definer->auth= NULL_CSTR;
6768 definer->uses_identified_with_clause= false;
6769 definer->uses_identified_by_clause= false;
6770 definer->uses_authentication_string_clause= false;
6771 definer->uses_identified_by_password_clause= false;
6772 definer->alter_status.update_password_expired_column= false;
6773 definer->alter_status.use_default_password_lifetime= true;
6774 definer->alter_status.expire_after_days= 0;
6775 definer->alter_status.update_account_locked_column= false;
6776 definer->alter_status.account_locked= false;
6777 }
6778
6779
6780 /**
6781 Create default definer for the specified THD.
6782
6783 @param[in] thd thread handler
6784
6785 @return
6786 - On success, return a valid pointer to the created and initialized
6787 LEX_USER, which contains definer information.
6788 - On error, return 0.
6789 */
6790
create_default_definer(THD * thd)6791 LEX_USER *create_default_definer(THD *thd)
6792 {
6793 LEX_USER *definer;
6794
6795 if (! (definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER))))
6796 return 0;
6797
6798 thd->get_definer(definer);
6799
6800 return definer;
6801 }
6802
6803
6804 /**
6805 Retuns information about user or current user.
6806
6807 @param[in] thd thread handler
6808 @param[in] user user
6809
6810 @return
6811 - On success, return a valid pointer to initialized
6812 LEX_USER, which contains user information.
6813 - On error, return 0.
6814 */
6815
get_current_user(THD * thd,LEX_USER * user)6816 LEX_USER *get_current_user(THD *thd, LEX_USER *user)
6817 {
6818 if (!user->user.str) // current_user
6819 {
6820 LEX_USER *default_definer= create_default_definer(thd);
6821 if (default_definer)
6822 {
6823 /*
6824 Inherit parser semantics from the statement in which the user parameter
6825 was used.
6826 This is needed because a st_lex_user is both used as a component in an
6827 AST and as a specifier for a particular user in the ACL subsystem.
6828 */
6829 default_definer->uses_authentication_string_clause=
6830 user->uses_authentication_string_clause;
6831 default_definer->uses_identified_by_clause=
6832 user->uses_identified_by_clause;
6833 default_definer->uses_identified_by_password_clause=
6834 user->uses_identified_by_password_clause;
6835 default_definer->uses_identified_with_clause=
6836 user->uses_identified_with_clause;
6837 default_definer->plugin.str= user->plugin.str;
6838 default_definer->plugin.length= user->plugin.length;
6839 default_definer->auth.str= user->auth.str;
6840 default_definer->auth.length= user->auth.length;
6841 default_definer->alter_status= user->alter_status;
6842
6843 return default_definer;
6844 }
6845 }
6846
6847 return user;
6848 }
6849
6850
6851 /**
6852 Check that byte length of a string does not exceed some limit.
6853
6854 @param str string to be checked
6855 @param err_msg error message to be displayed if the string is too long
6856 @param max_length max length
6857
6858 @retval
6859 FALSE the passed string is not longer than max_length
6860 @retval
6861 TRUE the passed string is longer than max_length
6862
6863 NOTE
6864 The function is not used in existing code but can be useful later?
6865 */
6866
check_string_byte_length(const LEX_CSTRING & str,const char * err_msg,size_t max_byte_length)6867 static bool check_string_byte_length(const LEX_CSTRING &str,
6868 const char *err_msg,
6869 size_t max_byte_length)
6870 {
6871 if (str.length <= max_byte_length)
6872 return FALSE;
6873
6874 my_error(ER_WRONG_STRING_LENGTH, MYF(0), str.str, err_msg, max_byte_length);
6875
6876 return TRUE;
6877 }
6878
6879
6880 /*
6881 Check that char length of a string does not exceed some limit.
6882
6883 SYNOPSIS
6884 check_string_char_length()
6885 str string to be checked
6886 err_msg error message to be displayed if the string is too long
6887 max_char_length max length in symbols
6888 cs string charset
6889
6890 RETURN
6891 FALSE the passed string is not longer than max_char_length
6892 TRUE the passed string is longer than max_char_length
6893 */
6894
6895
check_string_char_length(const LEX_CSTRING & str,const char * err_msg,size_t max_char_length,const CHARSET_INFO * cs,bool no_error)6896 bool check_string_char_length(const LEX_CSTRING &str, const char *err_msg,
6897 size_t max_char_length, const CHARSET_INFO *cs,
6898 bool no_error)
6899 {
6900 int well_formed_error;
6901 size_t res= cs->cset->well_formed_len(cs, str.str, str.str + str.length,
6902 max_char_length, &well_formed_error);
6903
6904 if (!well_formed_error && str.length == res)
6905 return FALSE;
6906
6907 if (!no_error)
6908 {
6909 ErrConvString err(str.str, str.length, cs);
6910 my_error(ER_WRONG_STRING_LENGTH, MYF(0), err.ptr(), err_msg, max_char_length);
6911 }
6912 return TRUE;
6913 }
6914
6915
6916 /*
6917 Check if path does not contain mysql data home directory
6918 SYNOPSIS
6919 test_if_data_home_dir()
6920 dir directory
6921 conv_home_dir converted data home directory
6922 home_dir_len converted data home directory length
6923
6924 RETURN VALUES
6925 0 ok
6926 1 error
6927 */
6928 C_MODE_START
6929
test_if_data_home_dir(const char * dir)6930 int test_if_data_home_dir(const char *dir)
6931 {
6932 char path[FN_REFLEN];
6933 size_t dir_len;
6934 DBUG_ENTER("test_if_data_home_dir");
6935
6936 if (!dir)
6937 DBUG_RETURN(0);
6938
6939 (void) fn_format(path, dir, "", "",
6940 (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
6941 dir_len= strlen(path);
6942 if (mysql_unpacked_real_data_home_len<= dir_len)
6943 {
6944 if (dir_len > mysql_unpacked_real_data_home_len &&
6945 path[mysql_unpacked_real_data_home_len] != FN_LIBCHAR)
6946 DBUG_RETURN(0);
6947
6948 if (lower_case_file_system)
6949 {
6950 if (!my_strnncoll(default_charset_info, (const uchar*) path,
6951 mysql_unpacked_real_data_home_len,
6952 (const uchar*) mysql_unpacked_real_data_home,
6953 mysql_unpacked_real_data_home_len))
6954 DBUG_RETURN(1);
6955 }
6956 else if (!memcmp(path, mysql_unpacked_real_data_home,
6957 mysql_unpacked_real_data_home_len))
6958 DBUG_RETURN(1);
6959 }
6960 DBUG_RETURN(0);
6961 }
6962
6963 C_MODE_END
6964
6965
6966 /**
6967 Check that host name string is valid.
6968
6969 @param[in] str string to be checked
6970
6971 @return Operation status
6972 @retval FALSE host name is ok
6973 @retval TRUE host name string is longer than max_length or
6974 has invalid symbols
6975 */
6976
check_host_name(const LEX_CSTRING & str)6977 bool check_host_name(const LEX_CSTRING &str)
6978 {
6979 const char *name= str.str;
6980 const char *end= str.str + str.length;
6981 if (check_string_byte_length(str, ER(ER_HOSTNAME), HOSTNAME_LENGTH))
6982 return TRUE;
6983
6984 while (name != end)
6985 {
6986 if (*name == '@')
6987 {
6988 my_printf_error(ER_UNKNOWN_ERROR,
6989 "Malformed hostname (illegal symbol: '%c')", MYF(0),
6990 *name);
6991 return TRUE;
6992 }
6993 name++;
6994 }
6995 return FALSE;
6996 }
6997
6998
6999 class Parser_oom_handler : public Internal_error_handler
7000 {
7001 public:
Parser_oom_handler()7002 Parser_oom_handler()
7003 : m_has_errors(false), m_is_mem_error(false)
7004 {}
handle_condition(THD * thd,uint sql_errno,const char * sqlstate,Sql_condition::enum_severity_level * level,const char * msg)7005 virtual bool handle_condition(THD *thd,
7006 uint sql_errno,
7007 const char* sqlstate,
7008 Sql_condition::enum_severity_level *level,
7009 const char* msg)
7010 {
7011 if (*level == Sql_condition::SL_ERROR)
7012 {
7013 m_has_errors= true;
7014 /* Out of memory error is reported only once. Return as handled */
7015 if (m_is_mem_error && sql_errno == EE_CAPACITY_EXCEEDED)
7016 return true;
7017 if (sql_errno == EE_CAPACITY_EXCEEDED)
7018 {
7019 m_is_mem_error= true;
7020 my_error(ER_CAPACITY_EXCEEDED, MYF(0),
7021 static_cast<ulonglong>(thd->variables.parser_max_mem_size),
7022 "parser_max_mem_size",
7023 ER_THD(thd, ER_CAPACITY_EXCEEDED_IN_PARSER));
7024 return true;
7025 }
7026 }
7027 return false;
7028 }
7029 private:
7030 bool m_has_errors;
7031 bool m_is_mem_error;
7032 };
7033
7034
7035 extern int MYSQLparse(class THD *thd); // from sql_yacc.cc
7036
7037
7038 /**
7039 This is a wrapper of MYSQLparse(). All the code should call parse_sql()
7040 instead of MYSQLparse().
7041
7042 As a by product of parsing, the parser can also generate a query digest.
7043 To compute a digest, invoke this function as follows.
7044
7045 @verbatim
7046 THD *thd = ...;
7047 const char *query_text = ...;
7048 uint query_length = ...;
7049 Object_creation_ctx *ctx = ...;
7050 bool rc;
7051
7052 Parser_state parser_state;
7053 if (parser_state.init(thd, query_text, query_length)
7054 {
7055 ... handle error
7056 }
7057
7058 parser_state.m_input.m_has_digest= true;
7059 parser_state.m_input.m_compute_digest= true;
7060
7061 rc= parse_sql(the, &parser_state, ctx);
7062 if (! rc)
7063 {
7064 unsigned char md5[MD5_HASH_SIZE];
7065 char digest_text[1024];
7066 bool truncated;
7067 const sql_digest_storage *digest= & thd->m_digest->m_digest_storage;
7068
7069 compute_digest_md5(digest, & md5[0]);
7070 compute_digest_text(digest, & digest_text[0], sizeof(digest_text), & truncated);
7071 }
7072 @endverbatim
7073
7074 @param thd Thread context.
7075 @param parser_state Parser state.
7076 @param creation_ctx Object creation context.
7077
7078 @return Error status.
7079 @retval FALSE on success.
7080 @retval TRUE on parsing error.
7081 */
7082
parse_sql(THD * thd,Parser_state * parser_state,Object_creation_ctx * creation_ctx)7083 bool parse_sql(THD *thd,
7084 Parser_state *parser_state,
7085 Object_creation_ctx *creation_ctx)
7086 {
7087 DBUG_ENTER("parse_sql");
7088 bool ret_value;
7089 assert(thd->m_parser_state == NULL);
7090 // TODO fix to allow parsing gcol exprs after main query.
7091 // assert(thd->lex->m_sql_cmd == NULL);
7092
7093 MYSQL_QUERY_PARSE_START(const_cast<char*>(thd->query().str));
7094 /* Backup creation context. */
7095
7096 Object_creation_ctx *backup_ctx= NULL;
7097
7098 if (creation_ctx)
7099 backup_ctx= creation_ctx->set_n_backup(thd);
7100
7101 /* Set parser state. */
7102
7103 thd->m_parser_state= parser_state;
7104
7105 parser_state->m_digest_psi= NULL;
7106 parser_state->m_lip.m_digest= NULL;
7107
7108 /*
7109 Only consider statements that are supposed to have a digest,
7110 like top level queries.
7111 */
7112 if (parser_state->m_input.m_has_digest) {
7113 /*
7114 For these statements,
7115 see if the digest computation is required.
7116 */
7117 if (thd->m_digest != NULL)
7118 {
7119 /* Start Digest */
7120 parser_state->m_digest_psi= MYSQL_DIGEST_START(thd->m_statement_psi);
7121
7122 if (parser_state->m_input.m_compute_digest ||
7123 (parser_state->m_digest_psi != NULL))
7124 {
7125 /*
7126 If either:
7127 - the caller wants to compute a digest
7128 - the performance schema wants to compute a digest
7129 set the digest listener in the lexer.
7130 */
7131 parser_state->m_lip.m_digest= thd->m_digest;
7132 parser_state->m_lip.m_digest->m_digest_storage.m_charset_number= thd->charset()->number;
7133 }
7134 }
7135 }
7136
7137 /* Parse the query. */
7138
7139 /*
7140 Use a temporary DA while parsing. We don't know until after parsing
7141 whether the current command is a diagnostic statement, in which case
7142 we'll need to have the previous DA around to answer questions about it.
7143 */
7144 Diagnostics_area *parser_da= thd->get_parser_da();
7145 Diagnostics_area *da= thd->get_stmt_da();
7146
7147 Parser_oom_handler poomh;
7148 // Note that we may be called recursively here, on INFORMATION_SCHEMA queries.
7149
7150 set_memroot_max_capacity(thd->mem_root, thd->variables.parser_max_mem_size);
7151 set_memroot_error_reporting(thd->mem_root, true);
7152 thd->push_internal_handler(&poomh);
7153
7154 thd->push_diagnostics_area(parser_da, false);
7155
7156 bool mysql_parse_status= MYSQLparse(thd) != 0;
7157
7158 thd->pop_internal_handler();
7159 set_memroot_max_capacity(thd->mem_root, 0);
7160 set_memroot_error_reporting(thd->mem_root, false);
7161 /*
7162 Unwind diagnostics area.
7163
7164 If any issues occurred during parsing, they will become
7165 the sole conditions for the current statement.
7166
7167 Otherwise, if we have a diagnostic statement on our hands,
7168 we'll preserve the previous diagnostics area here so we
7169 can answer questions about it. This specifically means
7170 that repeatedly asking about a DA won't clear it.
7171
7172 Otherwise, it's a regular command with no issues during
7173 parsing, so we'll just clear the DA in preparation for
7174 the processing of this command.
7175 */
7176
7177 if (parser_da->current_statement_cond_count() != 0)
7178 {
7179 /*
7180 Error/warning during parsing: top DA should contain parse error(s)! Any
7181 pre-existing conditions will be replaced. The exception is diagnostics
7182 statements, in which case we wish to keep the errors so they can be sent
7183 to the client.
7184 */
7185 if (thd->lex->sql_command != SQLCOM_SHOW_WARNS &&
7186 thd->lex->sql_command != SQLCOM_GET_DIAGNOSTICS)
7187 da->reset_condition_info(thd);
7188
7189 /*
7190 We need to put any errors in the DA as well as the condition list.
7191 */
7192 if (parser_da->is_error() && !da->is_error())
7193 {
7194 da->set_error_status(parser_da->mysql_errno(),
7195 parser_da->message_text(),
7196 parser_da->returned_sqlstate());
7197 }
7198
7199 da->copy_sql_conditions_from_da(thd, parser_da);
7200
7201 parser_da->reset_diagnostics_area();
7202 parser_da->reset_condition_info(thd);
7203
7204 /*
7205 Do not clear the condition list when starting execution as it
7206 now contains not the results of the previous executions, but
7207 a non-zero number of errors/warnings thrown during parsing!
7208 */
7209 thd->lex->keep_diagnostics= DA_KEEP_PARSE_ERROR;
7210 }
7211
7212 thd->pop_diagnostics_area();
7213
7214 /*
7215 Check that if MYSQLparse() failed either thd->is_error() is set, or an
7216 internal error handler is set.
7217
7218 The assert will not catch a situation where parsing fails without an
7219 error reported if an error handler exists. The problem is that the
7220 error handler might have intercepted the error, so thd->is_error() is
7221 not set. However, there is no way to be 100% sure here (the error
7222 handler might be for other errors than parsing one).
7223 */
7224
7225 assert(!mysql_parse_status ||
7226 (mysql_parse_status && thd->is_error()) ||
7227 (mysql_parse_status && thd->get_internal_handler()));
7228
7229 /* Reset parser state. */
7230
7231 thd->m_parser_state= NULL;
7232
7233 /* Restore creation context. */
7234
7235 if (creation_ctx)
7236 creation_ctx->restore_env(thd, backup_ctx);
7237
7238 /* That's it. */
7239
7240 ret_value= mysql_parse_status || thd->is_fatal_error;
7241
7242 if ((ret_value == 0) &&
7243 (parser_state->m_digest_psi != NULL))
7244 {
7245 /*
7246 On parsing success, record the digest in the performance schema.
7247 */
7248 assert(thd->m_digest != NULL);
7249 MYSQL_DIGEST_END(parser_state->m_digest_psi,
7250 & thd->m_digest->m_digest_storage);
7251 }
7252
7253 MYSQL_QUERY_PARSE_DONE(ret_value);
7254 DBUG_RETURN(ret_value);
7255 }
7256
7257 /**
7258 @} (end of group Runtime_Environment)
7259 */
7260
7261
7262
7263 /**
7264 Check and merge "CHARACTER SET cs [ COLLATE cl ]" clause
7265
7266 @param cs character set pointer.
7267 @param cl collation pointer.
7268
7269 Check if collation "cl" is applicable to character set "cs".
7270
7271 If "cl" is NULL (e.g. when COLLATE clause is not specified),
7272 then simply "cs" is returned.
7273
7274 @return Error status.
7275 @retval NULL, if "cl" is not applicable to "cs".
7276 @retval pointer to merged CHARSET_INFO on success.
7277 */
7278
7279
7280 const CHARSET_INFO*
merge_charset_and_collation(const CHARSET_INFO * cs,const CHARSET_INFO * cl)7281 merge_charset_and_collation(const CHARSET_INFO *cs, const CHARSET_INFO *cl)
7282 {
7283 if (cl)
7284 {
7285 if (!my_charset_same(cs, cl))
7286 {
7287 my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), cl->name, cs->csname);
7288 return NULL;
7289 }
7290 return cl;
7291 }
7292 return cs;
7293 }
7294