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