1 /* Copyright (c) 2000, 2020, 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 #define MYSQL_LEX 1
24 #include "my_global.h"
25 #include "sql_priv.h"
26 #include "unireg.h" // REQUIRED: for other includes
27 #include "sql_parse.h" // sql_kill, *_precheck, *_prepare
28 #include "lock.h" // try_transactional_lock,
29 // check_transactional_lock,
30 // set_handler_table_locks,
31 // lock_global_read_lock,
32 // make_global_read_lock_block_commit
33 #include "sql_base.h" // find_temporary_table
34 #include "sql_cache.h" // QUERY_CACHE_FLAGS_SIZE, query_cache_*
35 #include "sql_show.h" // mysqld_list_*, mysqld_show_*,
36 // calc_sum_of_all_status
37 #include "mysqld.h"
38 #include "sql_locale.h" // my_locale_en_US
39 #include "log.h" // flush_error_log
40 #include "sql_view.h" // mysql_create_view, mysql_drop_view
41 #include "sql_delete.h" // mysql_delete
42 #include "sql_insert.h" // mysql_insert
43 #include "sql_update.h" // mysql_update, mysql_multi_update
44 #include "sql_partition.h" // struct partition_info
45 #ifdef WITH_PARTITION_STORAGE_ENGINE
46 #include "partition_info.h" // has_external_data_or_index_dir
47 #endif /* WITH_PARTITION_STORAGE_ENGINE */
48 #include "sql_db.h" // mysql_change_db, mysql_create_db,
49 // mysql_rm_db, mysql_upgrade_db,
50 // mysql_alter_db,
51 // check_db_dir_existence,
52 // my_dbopt_cleanup
53 #include "sql_table.h" // mysql_create_like_table,
54 // mysql_create_table,
55 // mysql_alter_table,
56 // mysql_backup_table,
57 // mysql_restore_table
58 #include "sql_reload.h" // reload_acl_and_cache
59 #include "sql_admin.h" // mysql_assign_to_keycache
60 #include "sql_connect.h" // check_user,
61 // decrease_user_connections,
62 // thd_init_client_charset, check_mqh,
63 // reset_mqh
64 #include "sql_rename.h" // mysql_rename_table
65 #include "sql_tablespace.h" // mysql_alter_tablespace
66 #include "hostname.h" // hostname_cache_refresh
67 #include "sql_acl.h" // *_ACL, check_grant, is_acl_user,
68 // has_any_table_level_privileges,
69 // mysql_drop_user, mysql_rename_user,
70 // check_grant_routine,
71 // mysql_routine_grant,
72 // mysql_show_grants,
73 // sp_grant_privileges, ...
74 #include "sql_test.h" // mysql_print_status
75 #include "sql_select.h" // handle_select, mysql_select,
76 #include "sql_load.h" // mysql_load
77 #include "sql_servers.h" // create_servers, alter_servers,
78 // drop_servers, servers_reload
79 #include "sql_handler.h" // mysql_ha_open, mysql_ha_close,
80 // mysql_ha_read
81 #include "sql_binlog.h" // mysql_client_binlog_statement
82 #include "sql_do.h" // mysql_do
83 #include "sql_help.h" // mysqld_help
84 #include "sql_zip_dict.h" // mysqld_create_zip_dict, mysqld_drop_zip_dict
85 #include "rpl_constants.h" // Incident, INCIDENT_LOST_EVENTS
86 #include "log_event.h"
87 #include "rpl_slave.h"
88 #include "rpl_master.h"
89 #include "rpl_filter.h"
90 #include <m_ctype.h>
91 #include <myisam.h>
92 #include <my_dir.h>
93 #include "rpl_handler.h"
94
95 #include "sp_head.h"
96 #include "sp_rcontext.h"
97 #include "sp_instr.h"
98 #include "sp.h"
99 #include "sp_cache.h"
100 #include "events.h"
101 #include "sql_trigger.h"
102 #include "transaction.h"
103 #include "sql_audit.h"
104 #include "sql_prepare.h"
105 #include "debug_sync.h"
106 #include "probes_mysql.h"
107 #include "set_var.h"
108 #include "opt_trace.h"
109 #include "mysql/psi/mysql_statement.h"
110 #include "sql_bootstrap.h"
111 #include "opt_explain.h"
112 #include "sql_rewrite.h"
113 #include "global_threads.h"
114 #include "sql_analyse.h"
115 #include "table_cache.h" // table_cache_manager
116
117 #include "sql_digest.h"
118
119 #include <algorithm>
120 using std::max;
121 using std::min;
122
123 #include "sql_timer.h" // thd_timer_set, thd_timer_reset
124 #include "userstat.h"
125
126 #define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
127
128 /**
129 @defgroup Runtime_Environment Runtime Environment
130 @{
131 */
132
133 /* Used in error handling only */
134 #define SP_TYPE_STRING(LP) \
135 ((LP)->sphead->m_type == SP_TYPE_FUNCTION ? "FUNCTION" : "PROCEDURE")
136 #define SP_COM_STRING(LP) \
137 ((LP)->sql_command == SQLCOM_CREATE_SPFUNCTION || \
138 (LP)->sql_command == SQLCOM_ALTER_FUNCTION || \
139 (LP)->sql_command == SQLCOM_SHOW_CREATE_FUNC || \
140 (LP)->sql_command == SQLCOM_DROP_FUNCTION ? \
141 "FUNCTION" : "PROCEDURE")
142
143 static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables);
144 static bool check_show_access(THD *thd, TABLE_LIST *table);
145 static void sql_kill(THD *thd, ulong id, bool only_kill_query);
146 static bool lock_tables_precheck(THD *thd, TABLE_LIST *tables);
147
148 static inline ulonglong get_query_exec_time(THD *thd, ulonglong cur_utime);
149
150 const char *any_db="*any*"; // Special symbol for check_access
151
152 const LEX_STRING command_name[]={
153 { C_STRING_WITH_LEN("Sleep") },
154 { C_STRING_WITH_LEN("Quit") },
155 { C_STRING_WITH_LEN("Init DB") },
156 { C_STRING_WITH_LEN("Query") },
157 { C_STRING_WITH_LEN("Field List") },
158 { C_STRING_WITH_LEN("Create DB") },
159 { C_STRING_WITH_LEN("Drop DB") },
160 { C_STRING_WITH_LEN("Refresh") },
161 { C_STRING_WITH_LEN("Shutdown") },
162 { C_STRING_WITH_LEN("Statistics") },
163 { C_STRING_WITH_LEN("Processlist") },
164 { C_STRING_WITH_LEN("Connect") },
165 { C_STRING_WITH_LEN("Kill") },
166 { C_STRING_WITH_LEN("Debug") },
167 { C_STRING_WITH_LEN("Ping") },
168 { C_STRING_WITH_LEN("Time") },
169 { C_STRING_WITH_LEN("Delayed insert") },
170 { C_STRING_WITH_LEN("Change user") },
171 { C_STRING_WITH_LEN("Binlog Dump") },
172 { C_STRING_WITH_LEN("Table Dump") },
173 { C_STRING_WITH_LEN("Connect Out") },
174 { C_STRING_WITH_LEN("Register Slave") },
175 { C_STRING_WITH_LEN("Prepare") },
176 { C_STRING_WITH_LEN("Execute") },
177 { C_STRING_WITH_LEN("Long Data") },
178 { C_STRING_WITH_LEN("Close stmt") },
179 { C_STRING_WITH_LEN("Reset stmt") },
180 { C_STRING_WITH_LEN("Set option") },
181 { C_STRING_WITH_LEN("Fetch") },
182 { C_STRING_WITH_LEN("Daemon") },
183 { C_STRING_WITH_LEN("Binlog Dump GTID") },
184 { C_STRING_WITH_LEN("Error") } // Last command number
185 };
186
187 const char *xa_state_names[]={
188 "NON-EXISTING", "ACTIVE", "IDLE", "PREPARED", "ROLLBACK ONLY"
189 };
190
191
192 Slow_log_throttle log_throttle_qni(&opt_log_throttle_queries_not_using_indexes,
193 &LOCK_log_throttle_qni,
194 Log_throttle::LOG_THROTTLE_WINDOW_SIZE,
195 slow_log_print,
196 "throttle: %10lu 'index "
197 "not used' warning(s) suppressed.");
198
199
200 #ifdef HAVE_REPLICATION
201 /**
202 Returns true if all tables should be ignored.
203 */
all_tables_not_ok(THD * thd,TABLE_LIST * tables)204 inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables)
205 {
206 return rpl_filter->is_on() && tables && !thd->sp_runtime_ctx &&
207 !rpl_filter->tables_ok(thd->db, tables);
208 }
209
210 /**
211 Checks whether the event for the given database, db, should
212 be ignored or not. This is done by checking whether there are
213 active rules in ignore_db or in do_db containers. If there
214 are, then check if there is a match, if not then check the
215 wild_do rules.
216
217 NOTE: This means that when using this function replicate-do-db
218 and replicate-ignore-db take precedence over wild do
219 rules.
220
221 @param thd Thread handle.
222 @param db Database name used while evaluating the filtering
223 rules.
224 @param sql_cmd Represents the current query that needs to be
225 verified against the database filter rules.
226 @return TRUE Query should not be filtered out from the execution.
227 FALSE Query should be filtered out from the execution.
228
229 */
check_database_filters(THD * thd,char * db,enum_sql_command sql_cmd)230 inline bool check_database_filters(THD *thd, char* db, enum_sql_command sql_cmd)
231 {
232 DBUG_ENTER("check_database_filters");
233 DBUG_ASSERT(thd->slave_thread);
234 if (!db)
235 DBUG_RETURN(TRUE);
236 switch (sql_cmd)
237 {
238 case SQLCOM_BEGIN:
239 case SQLCOM_COMMIT:
240 case SQLCOM_SAVEPOINT:
241 case SQLCOM_ROLLBACK:
242 case SQLCOM_ROLLBACK_TO_SAVEPOINT:
243 DBUG_RETURN(TRUE);
244 default:
245 break;
246 }
247 bool db_ok= rpl_filter->db_ok(db);
248 /*
249 No filters exist in ignore/do_db ? Then, just check
250 wild_do_table filtering for 'DATABASE' related
251 statements (CREATE/DROP/ALTER DATABASE)
252 */
253 if (db_ok &&
254 (rpl_filter->get_do_db()->is_empty() &&
255 rpl_filter->get_ignore_db()->is_empty()))
256 {
257 switch (sql_cmd)
258 {
259 case SQLCOM_CREATE_DB:
260 case SQLCOM_ALTER_DB:
261 case SQLCOM_ALTER_DB_UPGRADE:
262 case SQLCOM_DROP_DB:
263 db_ok= rpl_filter->db_ok_with_wild_table(db);
264 default:
265 break;
266 }
267 }
268 DBUG_RETURN(db_ok);
269 }
270 #endif
271
272
some_non_temp_table_to_be_updated(THD * thd,TABLE_LIST * tables)273 static bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables)
274 {
275 for (TABLE_LIST *table= tables; table; table= table->next_global)
276 {
277 DBUG_ASSERT(table->db && table->table_name);
278 if (table->updating && !find_temporary_table(thd, table))
279 return 1;
280 }
281 return 0;
282 }
283
284
285 /*
286 Implicitly commit a active transaction if statement requires so.
287
288 @param thd Thread handle.
289 @param mask Bitmask used for the SQL command match.
290
291 */
stmt_causes_implicit_commit(const THD * thd,uint mask)292 bool stmt_causes_implicit_commit(const THD *thd, uint mask)
293 {
294 const LEX *lex= thd->lex;
295 bool skip= FALSE;
296 DBUG_ENTER("stmt_causes_implicit_commit");
297
298 if (!(sql_command_flags[lex->sql_command] & mask))
299 DBUG_RETURN(FALSE);
300
301 switch (lex->sql_command) {
302 case SQLCOM_DROP_TABLE:
303 skip= lex->drop_temporary;
304 break;
305 case SQLCOM_ALTER_TABLE:
306 case SQLCOM_CREATE_TABLE:
307 /* If CREATE TABLE of non-temporary table, do implicit commit */
308 skip= (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE);
309 break;
310 case SQLCOM_SET_OPTION:
311 skip= lex->autocommit ? FALSE : TRUE;
312 break;
313 default:
314 break;
315 }
316
317 DBUG_RETURN(!skip);
318 }
319
320
321 /**
322 Mark all commands that somehow changes a table.
323
324 This is used to check number of updates / hour.
325
326 sql_command is actually set to SQLCOM_END sometimes
327 so we need the +1 to include it in the array.
328
329 See COMMAND_FLAG_xxx for different type of commands
330 2 - query that returns meaningful ROW_COUNT() -
331 a number of modified rows
332 */
333
334 uint sql_command_flags[SQLCOM_END+1];
335 uint server_command_flags[COM_END+1];
336
init_update_queries(void)337 void init_update_queries(void)
338 {
339 /* Initialize the server command flags array. */
340 memset(server_command_flags, 0, sizeof(server_command_flags));
341
342 server_command_flags[COM_STATISTICS]= CF_SKIP_QUESTIONS;
343 server_command_flags[COM_PING]= CF_SKIP_QUESTIONS;
344 server_command_flags[COM_STMT_PREPARE]= CF_SKIP_QUESTIONS;
345 server_command_flags[COM_STMT_CLOSE]= CF_SKIP_QUESTIONS;
346 server_command_flags[COM_STMT_RESET]= CF_SKIP_QUESTIONS;
347
348 /* Initialize the sql command flags array. */
349 memset(sql_command_flags, 0, sizeof(sql_command_flags));
350
351 /*
352 In general, DDL statements do not generate row events and do not go
353 through a cache before being written to the binary log. However, the
354 CREATE TABLE...SELECT is an exception because it may generate row
355 events. For that reason, the SQLCOM_CREATE_TABLE which represents
356 a CREATE TABLE, including the CREATE TABLE...SELECT, has the
357 CF_CAN_GENERATE_ROW_EVENTS flag. The distinction between a regular
358 CREATE TABLE and the CREATE TABLE...SELECT is made in other parts of
359 the code, in particular in the Query_log_event's constructor.
360 */
361 sql_command_flags[SQLCOM_CREATE_TABLE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
362 CF_AUTO_COMMIT_TRANS |
363 CF_CAN_GENERATE_ROW_EVENTS;
364 sql_command_flags[SQLCOM_CREATE_INDEX]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
365 sql_command_flags[SQLCOM_ALTER_TABLE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND |
366 CF_AUTO_COMMIT_TRANS;
367 sql_command_flags[SQLCOM_TRUNCATE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND |
368 CF_AUTO_COMMIT_TRANS;
369 sql_command_flags[SQLCOM_DROP_TABLE]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
370 sql_command_flags[SQLCOM_LOAD]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
371 CF_CAN_GENERATE_ROW_EVENTS;
372 sql_command_flags[SQLCOM_CREATE_COMPRESSION_DICTIONARY]= CF_CHANGES_DATA |
373 CF_AUTO_COMMIT_TRANS;
374 sql_command_flags[SQLCOM_DROP_COMPRESSION_DICTIONARY]= CF_CHANGES_DATA |
375 CF_AUTO_COMMIT_TRANS;
376 sql_command_flags[SQLCOM_CREATE_DB]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
377 sql_command_flags[SQLCOM_DROP_DB]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
378 sql_command_flags[SQLCOM_ALTER_DB_UPGRADE]= CF_AUTO_COMMIT_TRANS;
379 sql_command_flags[SQLCOM_ALTER_DB]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
380 sql_command_flags[SQLCOM_RENAME_TABLE]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
381 sql_command_flags[SQLCOM_DROP_INDEX]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
382 sql_command_flags[SQLCOM_CREATE_VIEW]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
383 CF_AUTO_COMMIT_TRANS;
384 sql_command_flags[SQLCOM_DROP_VIEW]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
385 sql_command_flags[SQLCOM_CREATE_TRIGGER]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
386 sql_command_flags[SQLCOM_DROP_TRIGGER]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
387 sql_command_flags[SQLCOM_CREATE_EVENT]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
388 sql_command_flags[SQLCOM_ALTER_EVENT]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
389 sql_command_flags[SQLCOM_DROP_EVENT]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
390
391 sql_command_flags[SQLCOM_UPDATE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
392 CF_CAN_GENERATE_ROW_EVENTS |
393 CF_OPTIMIZER_TRACE |
394 CF_CAN_BE_EXPLAINED;
395 sql_command_flags[SQLCOM_UPDATE_MULTI]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
396 CF_CAN_GENERATE_ROW_EVENTS |
397 CF_OPTIMIZER_TRACE |
398 CF_CAN_BE_EXPLAINED;
399 // This is INSERT VALUES(...), can be VALUES(stored_func()) so we trace it
400 sql_command_flags[SQLCOM_INSERT]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
401 CF_CAN_GENERATE_ROW_EVENTS |
402 CF_OPTIMIZER_TRACE |
403 CF_CAN_BE_EXPLAINED;
404 sql_command_flags[SQLCOM_INSERT_SELECT]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
405 CF_CAN_GENERATE_ROW_EVENTS |
406 CF_OPTIMIZER_TRACE |
407 CF_CAN_BE_EXPLAINED;
408 sql_command_flags[SQLCOM_DELETE]= 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_DELETE_MULTI]= 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_REPLACE]= 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_REPLACE_SELECT]= 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_SELECT]= CF_REEXECUTION_FRAGILE |
425 CF_CAN_GENERATE_ROW_EVENTS |
426 CF_OPTIMIZER_TRACE |
427 CF_CAN_BE_EXPLAINED;
428 // (1) so that subquery is traced when doing "SET @var = (subquery)"
429 /*
430 @todo SQLCOM_SET_OPTION should have CF_CAN_GENERATE_ROW_EVENTS
431 set, because it may invoke a stored function that generates row
432 events. /Sven
433 */
434 sql_command_flags[SQLCOM_SET_OPTION]= CF_REEXECUTION_FRAGILE |
435 CF_AUTO_COMMIT_TRANS |
436 CF_CAN_GENERATE_ROW_EVENTS |
437 CF_OPTIMIZER_TRACE; // (1)
438 // (1) so that subquery is traced when doing "DO @var := (subquery)"
439 sql_command_flags[SQLCOM_DO]= CF_REEXECUTION_FRAGILE |
440 CF_CAN_GENERATE_ROW_EVENTS |
441 CF_OPTIMIZER_TRACE; // (1)
442
443 sql_command_flags[SQLCOM_SHOW_STATUS_PROC]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
444 sql_command_flags[SQLCOM_SHOW_STATUS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
445 sql_command_flags[SQLCOM_SHOW_DATABASES]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
446 sql_command_flags[SQLCOM_SHOW_TRIGGERS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
447 sql_command_flags[SQLCOM_SHOW_EVENTS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
448 sql_command_flags[SQLCOM_SHOW_OPEN_TABLES]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
449 sql_command_flags[SQLCOM_SHOW_PLUGINS]= CF_STATUS_COMMAND;
450 sql_command_flags[SQLCOM_SHOW_FIELDS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
451 sql_command_flags[SQLCOM_SHOW_KEYS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
452 sql_command_flags[SQLCOM_SHOW_VARIABLES]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
453 sql_command_flags[SQLCOM_SHOW_CHARSETS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
454 sql_command_flags[SQLCOM_SHOW_COLLATIONS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
455 sql_command_flags[SQLCOM_SHOW_BINLOGS]= CF_STATUS_COMMAND;
456 sql_command_flags[SQLCOM_SHOW_SLAVE_HOSTS]= CF_STATUS_COMMAND;
457 sql_command_flags[SQLCOM_SHOW_BINLOG_EVENTS]= CF_STATUS_COMMAND;
458 sql_command_flags[SQLCOM_SHOW_STORAGE_ENGINES]= CF_STATUS_COMMAND;
459 sql_command_flags[SQLCOM_SHOW_PRIVILEGES]= CF_STATUS_COMMAND;
460 sql_command_flags[SQLCOM_SHOW_WARNS]= CF_STATUS_COMMAND | CF_DIAGNOSTIC_STMT;
461 sql_command_flags[SQLCOM_SHOW_ERRORS]= CF_STATUS_COMMAND | CF_DIAGNOSTIC_STMT;
462 sql_command_flags[SQLCOM_SHOW_ENGINE_STATUS]= CF_STATUS_COMMAND;
463 sql_command_flags[SQLCOM_SHOW_ENGINE_MUTEX]= CF_STATUS_COMMAND;
464 sql_command_flags[SQLCOM_SHOW_ENGINE_LOGS]= CF_STATUS_COMMAND;
465 sql_command_flags[SQLCOM_SHOW_PROCESSLIST]= CF_STATUS_COMMAND;
466 sql_command_flags[SQLCOM_SHOW_GRANTS]= CF_STATUS_COMMAND;
467 sql_command_flags[SQLCOM_SHOW_CREATE_DB]= CF_STATUS_COMMAND;
468 sql_command_flags[SQLCOM_SHOW_CREATE]= CF_STATUS_COMMAND;
469 sql_command_flags[SQLCOM_SHOW_MASTER_STAT]= CF_STATUS_COMMAND;
470 sql_command_flags[SQLCOM_SHOW_SLAVE_STAT]= CF_STATUS_COMMAND;
471 sql_command_flags[SQLCOM_SHOW_SLAVE_NOLOCK_STAT]= CF_STATUS_COMMAND;
472 sql_command_flags[SQLCOM_SHOW_CREATE_PROC]= CF_STATUS_COMMAND;
473 sql_command_flags[SQLCOM_SHOW_CREATE_FUNC]= CF_STATUS_COMMAND;
474 sql_command_flags[SQLCOM_SHOW_CREATE_TRIGGER]= CF_STATUS_COMMAND;
475 sql_command_flags[SQLCOM_SHOW_STATUS_FUNC]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
476 sql_command_flags[SQLCOM_SHOW_PROC_CODE]= CF_STATUS_COMMAND;
477 sql_command_flags[SQLCOM_SHOW_FUNC_CODE]= CF_STATUS_COMMAND;
478 sql_command_flags[SQLCOM_SHOW_CREATE_EVENT]= CF_STATUS_COMMAND;
479 sql_command_flags[SQLCOM_SHOW_PROFILES]= CF_STATUS_COMMAND;
480 sql_command_flags[SQLCOM_SHOW_PROFILE]= CF_STATUS_COMMAND;
481 sql_command_flags[SQLCOM_BINLOG_BASE64_EVENT]= CF_STATUS_COMMAND |
482 CF_CAN_GENERATE_ROW_EVENTS;
483
484 sql_command_flags[SQLCOM_SHOW_TABLES]= (CF_STATUS_COMMAND |
485 CF_SHOW_TABLE_COMMAND |
486 CF_REEXECUTION_FRAGILE);
487 sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]= (CF_STATUS_COMMAND |
488 CF_SHOW_TABLE_COMMAND |
489 CF_REEXECUTION_FRAGILE);
490 sql_command_flags[SQLCOM_SHOW_USER_STATS]= CF_STATUS_COMMAND;
491 sql_command_flags[SQLCOM_SHOW_TABLE_STATS]= CF_STATUS_COMMAND;
492 sql_command_flags[SQLCOM_SHOW_INDEX_STATS]= CF_STATUS_COMMAND;
493 sql_command_flags[SQLCOM_SHOW_CLIENT_STATS]= CF_STATUS_COMMAND;
494 sql_command_flags[SQLCOM_SHOW_THREAD_STATS]= CF_STATUS_COMMAND;
495
496 sql_command_flags[SQLCOM_CREATE_USER]= CF_CHANGES_DATA;
497 sql_command_flags[SQLCOM_RENAME_USER]= CF_CHANGES_DATA;
498 sql_command_flags[SQLCOM_DROP_USER]= CF_CHANGES_DATA;
499 sql_command_flags[SQLCOM_ALTER_USER]= CF_CHANGES_DATA;
500 sql_command_flags[SQLCOM_GRANT]= CF_CHANGES_DATA;
501 sql_command_flags[SQLCOM_REVOKE]= CF_CHANGES_DATA;
502 sql_command_flags[SQLCOM_REVOKE_ALL]= CF_CHANGES_DATA;
503 sql_command_flags[SQLCOM_OPTIMIZE]= CF_CHANGES_DATA;
504 sql_command_flags[SQLCOM_CREATE_FUNCTION]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
505 sql_command_flags[SQLCOM_CREATE_PROCEDURE]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
506 sql_command_flags[SQLCOM_CREATE_SPFUNCTION]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
507 sql_command_flags[SQLCOM_DROP_PROCEDURE]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
508 sql_command_flags[SQLCOM_DROP_FUNCTION]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
509 sql_command_flags[SQLCOM_ALTER_PROCEDURE]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
510 sql_command_flags[SQLCOM_ALTER_FUNCTION]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
511 sql_command_flags[SQLCOM_INSTALL_PLUGIN]= CF_CHANGES_DATA;
512 sql_command_flags[SQLCOM_UNINSTALL_PLUGIN]= CF_CHANGES_DATA;
513
514 /* Does not change the contents of the diagnostics area. */
515 sql_command_flags[SQLCOM_GET_DIAGNOSTICS]= CF_DIAGNOSTIC_STMT;
516
517 /*
518 (1): without it, in "CALL some_proc((subq))", subquery would not be
519 traced.
520 */
521 sql_command_flags[SQLCOM_CALL]= CF_REEXECUTION_FRAGILE |
522 CF_CAN_GENERATE_ROW_EVENTS |
523 CF_OPTIMIZER_TRACE; // (1)
524 sql_command_flags[SQLCOM_EXECUTE]= CF_CAN_GENERATE_ROW_EVENTS;
525
526 /*
527 The following admin table operations are allowed
528 on log tables.
529 */
530 sql_command_flags[SQLCOM_REPAIR]= CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS;
531 sql_command_flags[SQLCOM_OPTIMIZE]|= CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS;
532 sql_command_flags[SQLCOM_ANALYZE]= CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS;
533 sql_command_flags[SQLCOM_CHECK]= CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS;
534
535 sql_command_flags[SQLCOM_CREATE_USER]|= CF_AUTO_COMMIT_TRANS;
536 sql_command_flags[SQLCOM_DROP_USER]|= CF_AUTO_COMMIT_TRANS;
537 sql_command_flags[SQLCOM_RENAME_USER]|= CF_AUTO_COMMIT_TRANS;
538 sql_command_flags[SQLCOM_ALTER_USER]|= CF_AUTO_COMMIT_TRANS;
539 sql_command_flags[SQLCOM_REVOKE]|= CF_AUTO_COMMIT_TRANS;
540 sql_command_flags[SQLCOM_REVOKE_ALL]|= CF_AUTO_COMMIT_TRANS;
541 sql_command_flags[SQLCOM_GRANT]|= CF_AUTO_COMMIT_TRANS;
542
543 sql_command_flags[SQLCOM_ASSIGN_TO_KEYCACHE]= CF_AUTO_COMMIT_TRANS;
544 sql_command_flags[SQLCOM_PRELOAD_KEYS]= CF_AUTO_COMMIT_TRANS;
545
546 sql_command_flags[SQLCOM_FLUSH]= CF_AUTO_COMMIT_TRANS;
547 sql_command_flags[SQLCOM_RESET]= CF_AUTO_COMMIT_TRANS;
548 sql_command_flags[SQLCOM_CREATE_SERVER]= CF_AUTO_COMMIT_TRANS;
549 sql_command_flags[SQLCOM_ALTER_SERVER]= CF_AUTO_COMMIT_TRANS;
550 sql_command_flags[SQLCOM_DROP_SERVER]= CF_AUTO_COMMIT_TRANS;
551 sql_command_flags[SQLCOM_CHANGE_MASTER]= CF_AUTO_COMMIT_TRANS;
552 sql_command_flags[SQLCOM_SLAVE_START]= CF_AUTO_COMMIT_TRANS;
553 sql_command_flags[SQLCOM_SLAVE_STOP]= CF_AUTO_COMMIT_TRANS;
554
555 /*
556 The following statements can deal with temporary tables,
557 so temporary tables should be pre-opened for those statements to
558 simplify privilege checking.
559
560 There are other statements that deal with temporary tables and open
561 them, but which are not listed here. The thing is that the order of
562 pre-opening temporary tables for those statements is somewhat custom.
563 */
564 sql_command_flags[SQLCOM_CREATE_TABLE]|= CF_PREOPEN_TMP_TABLES;
565 sql_command_flags[SQLCOM_DROP_TABLE]|= CF_PREOPEN_TMP_TABLES;
566 sql_command_flags[SQLCOM_CREATE_INDEX]|= CF_PREOPEN_TMP_TABLES;
567 sql_command_flags[SQLCOM_ALTER_TABLE]|= CF_PREOPEN_TMP_TABLES;
568 sql_command_flags[SQLCOM_TRUNCATE]|= CF_PREOPEN_TMP_TABLES;
569 sql_command_flags[SQLCOM_LOAD]|= CF_PREOPEN_TMP_TABLES;
570 sql_command_flags[SQLCOM_DROP_INDEX]|= CF_PREOPEN_TMP_TABLES;
571 sql_command_flags[SQLCOM_UPDATE]|= CF_PREOPEN_TMP_TABLES;
572 sql_command_flags[SQLCOM_UPDATE_MULTI]|= CF_PREOPEN_TMP_TABLES;
573 sql_command_flags[SQLCOM_INSERT_SELECT]|= CF_PREOPEN_TMP_TABLES;
574 sql_command_flags[SQLCOM_DELETE]|= CF_PREOPEN_TMP_TABLES;
575 sql_command_flags[SQLCOM_DELETE_MULTI]|= CF_PREOPEN_TMP_TABLES;
576 sql_command_flags[SQLCOM_REPLACE_SELECT]|= CF_PREOPEN_TMP_TABLES;
577 sql_command_flags[SQLCOM_SELECT]|= CF_PREOPEN_TMP_TABLES;
578 sql_command_flags[SQLCOM_SET_OPTION]|= CF_PREOPEN_TMP_TABLES;
579 sql_command_flags[SQLCOM_DO]|= CF_PREOPEN_TMP_TABLES;
580 sql_command_flags[SQLCOM_CALL]|= CF_PREOPEN_TMP_TABLES;
581 sql_command_flags[SQLCOM_CHECKSUM]|= CF_PREOPEN_TMP_TABLES;
582 sql_command_flags[SQLCOM_ANALYZE]|= CF_PREOPEN_TMP_TABLES;
583 sql_command_flags[SQLCOM_CHECK]|= CF_PREOPEN_TMP_TABLES;
584 sql_command_flags[SQLCOM_OPTIMIZE]|= CF_PREOPEN_TMP_TABLES;
585 sql_command_flags[SQLCOM_REPAIR]|= CF_PREOPEN_TMP_TABLES;
586 sql_command_flags[SQLCOM_PRELOAD_KEYS]|= CF_PREOPEN_TMP_TABLES;
587 sql_command_flags[SQLCOM_ASSIGN_TO_KEYCACHE]|= CF_PREOPEN_TMP_TABLES;
588
589 /*
590 DDL statements that should start with closing opened handlers.
591
592 We use this flag only for statements for which open HANDLERs
593 have to be closed before emporary tables are pre-opened.
594 */
595 sql_command_flags[SQLCOM_CREATE_TABLE]|= CF_HA_CLOSE;
596 sql_command_flags[SQLCOM_DROP_TABLE]|= CF_HA_CLOSE;
597 sql_command_flags[SQLCOM_ALTER_TABLE]|= CF_HA_CLOSE;
598 sql_command_flags[SQLCOM_TRUNCATE]|= CF_HA_CLOSE;
599 sql_command_flags[SQLCOM_REPAIR]|= CF_HA_CLOSE;
600 sql_command_flags[SQLCOM_OPTIMIZE]|= CF_HA_CLOSE;
601 sql_command_flags[SQLCOM_ANALYZE]|= CF_HA_CLOSE;
602 sql_command_flags[SQLCOM_CHECK]|= CF_HA_CLOSE;
603 sql_command_flags[SQLCOM_CREATE_INDEX]|= CF_HA_CLOSE;
604 sql_command_flags[SQLCOM_DROP_INDEX]|= CF_HA_CLOSE;
605 sql_command_flags[SQLCOM_PRELOAD_KEYS]|= CF_HA_CLOSE;
606 sql_command_flags[SQLCOM_ASSIGN_TO_KEYCACHE]|= CF_HA_CLOSE;
607
608 /*
609 Mark statements that always are disallowed in read-only
610 transactions. Note that according to the SQL standard,
611 even temporary table DDL should be disallowed.
612 */
613 sql_command_flags[SQLCOM_CREATE_TABLE]|= CF_DISALLOW_IN_RO_TRANS;
614 sql_command_flags[SQLCOM_ALTER_TABLE]|= CF_DISALLOW_IN_RO_TRANS;
615 sql_command_flags[SQLCOM_DROP_TABLE]|= CF_DISALLOW_IN_RO_TRANS;
616 sql_command_flags[SQLCOM_RENAME_TABLE]|= CF_DISALLOW_IN_RO_TRANS;
617 sql_command_flags[SQLCOM_CREATE_INDEX]|= CF_DISALLOW_IN_RO_TRANS;
618 sql_command_flags[SQLCOM_DROP_INDEX]|= CF_DISALLOW_IN_RO_TRANS;
619 sql_command_flags[SQLCOM_CREATE_COMPRESSION_DICTIONARY]|=
620 CF_DISALLOW_IN_RO_TRANS;
621 sql_command_flags[SQLCOM_DROP_COMPRESSION_DICTIONARY]|=
622 CF_DISALLOW_IN_RO_TRANS;
623 sql_command_flags[SQLCOM_CREATE_DB]|= CF_DISALLOW_IN_RO_TRANS;
624 sql_command_flags[SQLCOM_DROP_DB]|= CF_DISALLOW_IN_RO_TRANS;
625 sql_command_flags[SQLCOM_ALTER_DB_UPGRADE]|= CF_DISALLOW_IN_RO_TRANS;
626 sql_command_flags[SQLCOM_ALTER_DB]|= CF_DISALLOW_IN_RO_TRANS;
627 sql_command_flags[SQLCOM_CREATE_VIEW]|= CF_DISALLOW_IN_RO_TRANS;
628 sql_command_flags[SQLCOM_DROP_VIEW]|= CF_DISALLOW_IN_RO_TRANS;
629 sql_command_flags[SQLCOM_CREATE_TRIGGER]|= CF_DISALLOW_IN_RO_TRANS;
630 sql_command_flags[SQLCOM_DROP_TRIGGER]|= CF_DISALLOW_IN_RO_TRANS;
631 sql_command_flags[SQLCOM_CREATE_EVENT]|= CF_DISALLOW_IN_RO_TRANS;
632 sql_command_flags[SQLCOM_ALTER_EVENT]|= CF_DISALLOW_IN_RO_TRANS;
633 sql_command_flags[SQLCOM_DROP_EVENT]|= CF_DISALLOW_IN_RO_TRANS;
634 sql_command_flags[SQLCOM_CREATE_USER]|= CF_DISALLOW_IN_RO_TRANS;
635 sql_command_flags[SQLCOM_RENAME_USER]|= CF_DISALLOW_IN_RO_TRANS;
636 sql_command_flags[SQLCOM_ALTER_USER]|= CF_DISALLOW_IN_RO_TRANS;
637 sql_command_flags[SQLCOM_DROP_USER]|= CF_DISALLOW_IN_RO_TRANS;
638 sql_command_flags[SQLCOM_CREATE_SERVER]|= CF_DISALLOW_IN_RO_TRANS;
639 sql_command_flags[SQLCOM_ALTER_SERVER]|= CF_DISALLOW_IN_RO_TRANS;
640 sql_command_flags[SQLCOM_DROP_SERVER]|= CF_DISALLOW_IN_RO_TRANS;
641 sql_command_flags[SQLCOM_CREATE_FUNCTION]|= CF_DISALLOW_IN_RO_TRANS;
642 sql_command_flags[SQLCOM_CREATE_PROCEDURE]|= CF_DISALLOW_IN_RO_TRANS;
643 sql_command_flags[SQLCOM_CREATE_SPFUNCTION]|=CF_DISALLOW_IN_RO_TRANS;
644 sql_command_flags[SQLCOM_DROP_PROCEDURE]|= CF_DISALLOW_IN_RO_TRANS;
645 sql_command_flags[SQLCOM_DROP_FUNCTION]|= CF_DISALLOW_IN_RO_TRANS;
646 sql_command_flags[SQLCOM_ALTER_PROCEDURE]|= CF_DISALLOW_IN_RO_TRANS;
647 sql_command_flags[SQLCOM_ALTER_FUNCTION]|= CF_DISALLOW_IN_RO_TRANS;
648 sql_command_flags[SQLCOM_TRUNCATE]|= CF_DISALLOW_IN_RO_TRANS;
649 sql_command_flags[SQLCOM_ALTER_TABLESPACE]|= CF_DISALLOW_IN_RO_TRANS;
650 sql_command_flags[SQLCOM_REPAIR]|= CF_DISALLOW_IN_RO_TRANS;
651 sql_command_flags[SQLCOM_OPTIMIZE]|= CF_DISALLOW_IN_RO_TRANS;
652 sql_command_flags[SQLCOM_GRANT]|= CF_DISALLOW_IN_RO_TRANS;
653 sql_command_flags[SQLCOM_REVOKE]|= CF_DISALLOW_IN_RO_TRANS;
654 sql_command_flags[SQLCOM_REVOKE_ALL]|= CF_DISALLOW_IN_RO_TRANS;
655 sql_command_flags[SQLCOM_INSTALL_PLUGIN]|= CF_DISALLOW_IN_RO_TRANS;
656 sql_command_flags[SQLCOM_UNINSTALL_PLUGIN]|= CF_DISALLOW_IN_RO_TRANS;
657 }
658
sqlcom_can_generate_row_events(enum enum_sql_command command)659 bool sqlcom_can_generate_row_events(enum enum_sql_command command)
660 {
661 return (sql_command_flags[command] & CF_CAN_GENERATE_ROW_EVENTS);
662 }
663
is_update_query(enum enum_sql_command command)664 bool is_update_query(enum enum_sql_command command)
665 {
666 DBUG_ASSERT(command >= 0 && command <= SQLCOM_END);
667 return (sql_command_flags[command] & CF_CHANGES_DATA) != 0;
668 }
669
670
is_explainable_query(enum enum_sql_command command)671 bool is_explainable_query(enum enum_sql_command command)
672 {
673 DBUG_ASSERT(command >= 0 && command <= SQLCOM_END);
674 return (sql_command_flags[command] & CF_CAN_BE_EXPLAINED) != 0;
675 }
676
677 /**
678 Check if a sql command is allowed to write to log tables.
679 @param command The SQL command
680 @return true if writing is allowed
681 */
is_log_table_write_query(enum enum_sql_command command)682 bool is_log_table_write_query(enum enum_sql_command command)
683 {
684 DBUG_ASSERT(command >= 0 && command <= SQLCOM_END);
685 return (sql_command_flags[command] & CF_WRITE_LOGS_COMMAND) != 0;
686 }
687
execute_init_command(THD * thd,LEX_STRING * init_command,mysql_rwlock_t * var_lock)688 void execute_init_command(THD *thd, LEX_STRING *init_command,
689 mysql_rwlock_t *var_lock)
690 {
691 Vio* save_vio;
692 ulong save_client_capabilities;
693
694 mysql_rwlock_rdlock(var_lock);
695 if (!init_command->length)
696 {
697 mysql_rwlock_unlock(var_lock);
698 return;
699 }
700
701 /*
702 copy the value under a lock, and release the lock.
703 init_command has to be executed without a lock held,
704 as it may try to change itself
705 */
706 size_t len= init_command->length;
707 char *buf= thd->strmake(init_command->str, len);
708 mysql_rwlock_unlock(var_lock);
709
710 #if defined(ENABLED_PROFILING)
711 thd->profiling.start_new_query();
712 thd->profiling.set_query_source(buf, len);
713 #endif
714
715 THD_STAGE_INFO(thd, stage_execution_of_init_command);
716 save_client_capabilities= thd->client_capabilities;
717 thd->client_capabilities|= CLIENT_MULTI_QUERIES;
718 /*
719 We don't need return result of execution to client side.
720 To forbid this we should set thd->net.vio to 0.
721 */
722 save_vio= thd->net.vio;
723 thd->net.vio= 0;
724 dispatch_command(COM_QUERY, thd, buf, len);
725 thd->client_capabilities= save_client_capabilities;
726 thd->net.vio= save_vio;
727
728 #if defined(ENABLED_PROFILING)
729 thd->profiling.finish_current_query();
730 #endif
731 }
732
fgets_fn(char * buffer,size_t size,fgets_input_t input,int * error)733 static char *fgets_fn(char *buffer, size_t size, fgets_input_t input, int *error)
734 {
735 MYSQL_FILE *in= static_cast<MYSQL_FILE*> (input);
736 char *line= mysql_file_fgets(buffer, size, in);
737 if (error)
738 *error= (line == NULL) ? ferror(in->m_file) : 0;
739 return line;
740 }
741
handle_bootstrap_impl(THD * thd)742 static void handle_bootstrap_impl(THD *thd)
743 {
744 MYSQL_FILE *file= bootstrap_file;
745 char buffer[MAX_BOOTSTRAP_QUERY_SIZE];
746 char *query;
747 int length;
748 int rc;
749 int error= 0;
750
751 DBUG_ENTER("handle_bootstrap");
752
753 #ifndef EMBEDDED_LIBRARY
754 pthread_detach_this_thread();
755 thd->thread_stack= (char*) &thd;
756 #endif /* EMBEDDED_LIBRARY */
757
758 thd->security_ctx->user= (char*) my_strdup("boot", MYF(MY_WME));
759 thd->security_ctx->priv_user[0]= thd->security_ctx->priv_host[0]=0;
760 /*
761 Make the "client" handle multiple results. This is necessary
762 to enable stored procedures with SELECTs and Dynamic SQL
763 in init-file.
764 */
765 thd->client_capabilities|= CLIENT_MULTI_RESULTS;
766
767 thd->init_for_queries();
768
769 buffer[0]= '\0';
770
771 for ( ; ; )
772 {
773 rc= read_bootstrap_query(buffer, &length, file, fgets_fn, &error);
774
775 if (rc == READ_BOOTSTRAP_EOF)
776 break;
777 /*
778 Check for bootstrap file errors. SQL syntax errors will be
779 caught below.
780 */
781 if (rc != READ_BOOTSTRAP_SUCCESS)
782 {
783 /*
784 mysql_parse() may have set a successful error status for the previous
785 query. We must clear the error status to report the bootstrap error.
786 */
787 thd->get_stmt_da()->reset_diagnostics_area();
788
789 /* Get the nearest query text for reference. */
790 char *err_ptr= buffer + (length <= MAX_BOOTSTRAP_ERROR_LEN ?
791 0 : (length - MAX_BOOTSTRAP_ERROR_LEN));
792 switch (rc)
793 {
794 case READ_BOOTSTRAP_ERROR:
795 my_printf_error(ER_UNKNOWN_ERROR, "Bootstrap file error, return code (%d). "
796 "Nearest query: '%s'", MYF(0), error, err_ptr);
797 break;
798
799 case READ_BOOTSTRAP_QUERY_SIZE:
800 my_printf_error(ER_UNKNOWN_ERROR, "Boostrap file error. Query size "
801 "exceeded %d bytes near '%s'.", MYF(0),
802 MAX_BOOTSTRAP_LINE_SIZE, err_ptr);
803 break;
804
805 default:
806 DBUG_ASSERT(false);
807 break;
808 }
809
810 thd->protocol->end_statement();
811 bootstrap_error= 1;
812 break;
813 }
814
815 query= (char *) thd->memdup_w_gap(buffer, length + 1,
816 thd->db_length + 1 +
817 QUERY_CACHE_FLAGS_SIZE);
818 size_t db_len= 0;
819 memcpy(query + length + 1, (char *) &db_len, sizeof(size_t));
820 thd->set_query_and_id(query, length, thd->charset(), next_query_id());
821 DBUG_PRINT("query",("%-.4096s",thd->query()));
822 #if defined(ENABLED_PROFILING)
823 thd->profiling.start_new_query();
824 thd->profiling.set_query_source(thd->query(), length);
825 #endif
826
827 /*
828 We don't need to obtain LOCK_thread_count here because in bootstrap
829 mode we have only one thread.
830 */
831 thd->set_time();
832 Parser_state parser_state;
833 if (parser_state.init(thd, thd->query(), length))
834 {
835 thd->protocol->end_statement();
836 bootstrap_error= 1;
837 break;
838 }
839
840 mysql_parse(thd, thd->query(), length, &parser_state, true);
841
842 bootstrap_error= thd->is_error();
843 thd->protocol->end_statement();
844
845 #if defined(ENABLED_PROFILING)
846 thd->profiling.finish_current_query();
847 #endif
848
849 if (bootstrap_error)
850 break;
851
852 free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
853 }
854
855 DBUG_VOID_RETURN;
856 }
857
858
859 /**
860 Execute commands from bootstrap_file.
861
862 Used when creating the initial grant tables.
863 */
864
handle_bootstrap(void * arg)865 pthread_handler_t handle_bootstrap(void *arg)
866 {
867 THD *thd=(THD*) arg;
868
869 mysql_thread_set_psi_id(thd->thread_id);
870
871 do_handle_bootstrap(thd);
872 return 0;
873 }
874
do_handle_bootstrap(THD * thd)875 void do_handle_bootstrap(THD *thd)
876 {
877 bool thd_added= false;
878 /* The following must be called before DBUG_ENTER */
879 thd->thread_stack= (char*) &thd;
880 if (my_thread_init() || thd->store_globals())
881 {
882 #ifndef EMBEDDED_LIBRARY
883 close_connection(thd, ER_OUT_OF_RESOURCES);
884 #endif
885 thd->fatal_error();
886 goto end;
887 }
888
889 mysql_mutex_lock(&LOCK_thread_count);
890 thd_added= true;
891 add_global_thread(thd);
892 mysql_mutex_unlock(&LOCK_thread_count);
893
894 handle_bootstrap_impl(thd);
895
896 end:
897 net_end(&thd->net);
898 thd->release_resources();
899
900 if (thd_added)
901 {
902 remove_global_thread(thd);
903 }
904 /*
905 For safety we delete the thd before signalling that bootstrap is done,
906 since the server will be taken down immediately.
907 */
908 delete thd;
909
910 mysql_mutex_lock(&LOCK_thread_count);
911 in_bootstrap= FALSE;
912 mysql_cond_broadcast(&COND_thread_count);
913 mysql_mutex_unlock(&LOCK_thread_count);
914
915 #ifndef EMBEDDED_LIBRARY
916 my_thread_end();
917 pthread_exit(0);
918 #endif
919
920 return;
921 }
922
923
924 /* This works because items are allocated with sql_alloc() */
925
free_items(Item * item)926 void free_items(Item *item)
927 {
928 Item *next;
929 DBUG_ENTER("free_items");
930 for (; item ; item=next)
931 {
932 next=item->next;
933 item->delete_self();
934 }
935 DBUG_VOID_RETURN;
936 }
937
938 /**
939 This works because items are allocated with sql_alloc().
940 @note The function also handles null pointers (empty list).
941 */
cleanup_items(Item * item)942 void cleanup_items(Item *item)
943 {
944 DBUG_ENTER("cleanup_items");
945 for (; item ; item=item->next)
946 item->cleanup();
947 DBUG_VOID_RETURN;
948 }
949
950 #ifndef EMBEDDED_LIBRARY
951
952 /**
953 Read one command from connection and execute it (query or simple command).
954 This function is called in loop from thread function.
955
956 For profiling to work, it must never be called recursively.
957
958 @retval
959 0 success
960 @retval
961 1 request of thread shutdown (see dispatch_command() description)
962 */
963
do_command(THD * thd)964 bool do_command(THD *thd)
965 {
966 bool return_value;
967 char *packet= 0;
968 ulong packet_length;
969 NET *net= &thd->net;
970 enum enum_server_command command;
971
972 DBUG_ENTER("do_command");
973
974 /*
975 indicator of uninitialized lex => normal flow of errors handling
976 (see my_message_sql)
977 */
978 thd->lex->current_select= 0;
979
980 /*
981 This thread will do a blocking read from the client which
982 will be interrupted when the next command is received from
983 the client, the connection is closed or "net_wait_timeout"
984 number of seconds has passed.
985 */
986 if(!thd->skip_wait_timeout)
987 my_net_set_read_timeout(net, thd->get_wait_timeout());
988
989 /*
990 XXX: this code is here only to clear possible errors of init_connect.
991 Consider moving to init_connect() instead.
992 */
993 thd->clear_error(); // Clear error message
994 thd->get_stmt_da()->reset_diagnostics_area();
995 thd->updated_row_count= 0;
996 thd->busy_time= 0;
997 thd->cpu_time= 0;
998 thd->bytes_received= 0;
999 thd->bytes_sent= 0;
1000 thd->binlog_bytes_written= 0;
1001
1002 net_new_transaction(net);
1003
1004 /*
1005 Synchronization point for testing of KILL_CONNECTION.
1006 This sync point can wait here, to simulate slow code execution
1007 between the last test of thd->killed and blocking in read().
1008
1009 The goal of this test is to verify that a connection does not
1010 hang, if it is killed at this point of execution.
1011 (Bug#37780 - main.kill fails randomly)
1012
1013 Note that the sync point wait itself will be terminated by a
1014 kill. In this case it consumes a condition broadcast, but does
1015 not change anything else. The consumed broadcast should not
1016 matter here, because the read/recv() below doesn't use it.
1017 */
1018 DEBUG_SYNC(thd, "before_do_command_net_read");
1019
1020 /*
1021 Because of networking layer callbacks in place,
1022 this call will maintain the following instrumentation:
1023 - IDLE events
1024 - SOCKET events
1025 - STATEMENT events
1026 - STAGE events
1027 when reading a new network packet.
1028 In particular, a new instrumented statement is started.
1029 See init_net_server_extension()
1030 */
1031 thd->m_server_idle= true;
1032 packet_length= my_net_read(net);
1033 thd->m_server_idle= false;
1034
1035 if (packet_length == packet_error)
1036 {
1037 DBUG_PRINT("info",("Got error %d reading command from socket %s",
1038 net->error,
1039 vio_description(net->vio)));
1040
1041 /* Instrument this broken statement as "statement/com/error" */
1042 thd->m_statement_psi= MYSQL_REFINE_STATEMENT(thd->m_statement_psi,
1043 com_statement_info[COM_END].m_key);
1044
1045 /* Check if we can continue without closing the connection */
1046
1047 /* The error must be set. */
1048 DBUG_ASSERT(thd->is_error());
1049 thd->protocol->end_statement();
1050
1051 /* Mark the statement completed. */
1052 MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
1053 thd->m_statement_psi= NULL;
1054 thd->m_digest= NULL;
1055
1056 if (net->error != 3)
1057 {
1058 return_value= TRUE; // We have to close it.
1059 goto out;
1060 }
1061
1062 net->error= 0;
1063 return_value= FALSE;
1064 goto out;
1065 }
1066
1067 packet= (char*) net->read_pos;
1068 /*
1069 'packet_length' contains length of data, as it was stored in packet
1070 header. In case of malformed header, my_net_read returns zero.
1071 If packet_length is not zero, my_net_read ensures that the returned
1072 number of bytes was actually read from network.
1073 There is also an extra safety measure in my_net_read:
1074 it sets packet[packet_length]= 0, but only for non-zero packets.
1075 */
1076 if (packet_length == 0) /* safety */
1077 {
1078 /* Initialize with COM_SLEEP packet */
1079 packet[0]= (uchar) COM_SLEEP;
1080 packet_length= 1;
1081 }
1082 /* Do not rely on my_net_read, extra safety against programming errors. */
1083 packet[packet_length]= '\0'; /* safety */
1084
1085 command= (enum enum_server_command) (uchar) packet[0];
1086
1087 if (command >= COM_END)
1088 command= COM_END; // Wrong command
1089
1090 DBUG_PRINT("info",("Command on %s = %d (%s)",
1091 vio_description(net->vio), command,
1092 command_name[command].str));
1093
1094 /* Restore read timeout value */
1095 my_net_set_read_timeout(net, thd->variables.net_read_timeout);
1096
1097 DBUG_ASSERT(packet_length);
1098
1099 return_value= dispatch_command(command, thd, packet+1, (uint) (packet_length-1));
1100
1101 out:
1102 /* The statement instrumentation must be closed in all cases. */
1103 DBUG_ASSERT(thd->m_digest == NULL);
1104 DBUG_ASSERT(thd->m_statement_psi == NULL);
1105 DBUG_RETURN(return_value);
1106 }
1107 #endif /* EMBEDDED_LIBRARY */
1108
1109 /**
1110 @brief Determine if an attempt to update a non-temporary table while the
1111 read-only option was enabled has been made.
1112
1113 This is a helper function to mysql_execute_command.
1114
1115 @note SQLCOM_UPDATE_MULTI is an exception and delt with elsewhere.
1116
1117 @see mysql_execute_command
1118 @returns Status code
1119 @retval TRUE The statement should be denied.
1120 @retval FALSE The statement isn't updating any relevant tables.
1121 */
1122
deny_updates_if_read_only_option(THD * thd,TABLE_LIST * all_tables)1123 static my_bool deny_updates_if_read_only_option(THD *thd,
1124 TABLE_LIST *all_tables)
1125 {
1126 DBUG_ENTER("deny_updates_if_read_only_option");
1127
1128 if (!opt_readonly)
1129 DBUG_RETURN(FALSE);
1130
1131 LEX *lex= thd->lex;
1132
1133 const my_bool user_is_super=
1134 ((ulong)(thd->security_ctx->master_access & SUPER_ACL) ==
1135 (ulong)SUPER_ACL);
1136
1137 if (user_is_super && (!opt_super_readonly))
1138 DBUG_RETURN(FALSE);
1139
1140 if (!(sql_command_flags[lex->sql_command] & CF_CHANGES_DATA))
1141 DBUG_RETURN(FALSE);
1142
1143 /* Multi update is an exception and is dealt with later. */
1144 if (lex->sql_command == SQLCOM_UPDATE_MULTI)
1145 DBUG_RETURN(FALSE);
1146
1147 const my_bool create_temp_tables=
1148 (lex->sql_command == SQLCOM_CREATE_TABLE) &&
1149 (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE);
1150
1151 const my_bool create_real_tables=
1152 (lex->sql_command == SQLCOM_CREATE_TABLE) &&
1153 !(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE);
1154
1155 const my_bool drop_temp_tables=
1156 (lex->sql_command == SQLCOM_DROP_TABLE) &&
1157 lex->drop_temporary;
1158
1159 const my_bool update_real_tables=
1160 ((create_real_tables ||
1161 some_non_temp_table_to_be_updated(thd, all_tables)) &&
1162 !(create_temp_tables || drop_temp_tables));
1163
1164 const my_bool create_or_drop_databases=
1165 (lex->sql_command == SQLCOM_CREATE_DB) ||
1166 (lex->sql_command == SQLCOM_DROP_DB);
1167
1168 const bool create_or_drop_compression_dictionary=
1169 (lex->sql_command == SQLCOM_CREATE_COMPRESSION_DICTIONARY) ||
1170 (lex->sql_command == SQLCOM_DROP_COMPRESSION_DICTIONARY);
1171
1172 if (update_real_tables || create_or_drop_databases ||
1173 create_or_drop_compression_dictionary)
1174 {
1175 /*
1176 An attempt was made to modify one or more non-temporary tables.
1177 */
1178 DBUG_RETURN(TRUE);
1179 }
1180
1181
1182 /* Assuming that only temporary tables are modified. */
1183 DBUG_RETURN(FALSE);
1184 }
1185
1186
1187 /**
1188 Get the maximum execution time for a statement.
1189
1190 @return Length of time in milliseconds.
1191
1192 @remark A zero timeout means that no timeout should be
1193 applied to this particular statement.
1194 */
1195
get_max_statement_time(THD * thd)1196 static ulong inline get_max_statement_time(THD *thd)
1197 {
1198
1199 /* Assume query execution timeout feature is not used in the most cases */
1200 if (likely(!thd->variables.max_statement_time))
1201 return 0;
1202
1203 /* Check if timer support is implemented and was initialized. */
1204 if (unlikely(have_statement_timeout != SHOW_OPTION_YES))
1205 return 0;
1206
1207 /* The maximum execution time only applies to top-level statements. */
1208 if (unlikely(thd->sp_runtime_ctx || thd->in_sub_stmt))
1209 return 0;
1210
1211 /* Also does not apply to statements made by the slave thread. */
1212 if (unlikely(thd->slave_thread))
1213 return 0;
1214
1215 return thd->variables.max_statement_time;
1216 }
1217
1218
1219 /**
1220 Set the time until the currently running statement is aborted.
1221
1222 @param thd Thread (session) context.
1223
1224 @return TRUE if the timer was armed.
1225 */
1226
set_statement_timer(THD * thd)1227 static inline bool set_statement_timer(THD *thd)
1228 {
1229 ulong max_statement_time= get_max_statement_time(thd);
1230
1231 /* Assume query execution timeout feature is not used in the most cases */
1232 if (likely(max_statement_time == 0))
1233 return false;
1234
1235 if (unlikely(thd->timer != NULL))
1236 return false;
1237
1238 thd->timer= thd_timer_set(thd, thd->timer_cache, max_statement_time);
1239 thd->timer_cache= NULL;
1240
1241 if (thd->timer)
1242 status_var_increment(thd->status_var.max_statement_time_set);
1243 else
1244 status_var_increment(thd->status_var.max_statement_time_set_failed);
1245
1246 return thd->timer;
1247 }
1248
1249
1250 /**
1251 Deactivate the timer associated with the statement that was executed.
1252
1253 @param thd Thread (session) context.
1254 */
1255
reset_statement_timer(THD * thd)1256 static void reset_statement_timer(THD *thd)
1257 {
1258 DBUG_ASSERT(thd->timer);
1259 /* Cache the timer object if it can be reused. */
1260 thd->timer_cache= thd_timer_reset(thd->timer);
1261 thd->timer= NULL;
1262 }
1263
1264
1265 /**
1266 Perform one connection-level (COM_XXXX) command.
1267
1268 @param command type of command to perform
1269 @param thd connection handle
1270 @param packet data for the command, packet is always null-terminated
1271 @param packet_length length of packet + 1 (to show that data is
1272 null-terminated) except for COM_SLEEP, where it
1273 can be zero.
1274
1275 @todo
1276 set thd->lex->sql_command to SQLCOM_END here.
1277 @todo
1278 The following has to be changed to an 8 byte integer
1279
1280 @retval
1281 0 ok
1282 @retval
1283 1 request of thread shutdown, i. e. if command is
1284 COM_QUIT/COM_SHUTDOWN
1285 */
dispatch_command(enum enum_server_command command,THD * thd,char * packet,uint packet_length)1286 bool dispatch_command(enum enum_server_command command, THD *thd,
1287 char* packet, uint packet_length)
1288 {
1289 NET *net= &thd->net;
1290 bool error= 0;
1291 DBUG_ENTER("dispatch_command");
1292 DBUG_PRINT("info",("packet: '%*.s'; command: %d", packet_length, packet, command));
1293
1294 DBUG_EXECUTE_IF("crash_dispatch_command_before",
1295 { DBUG_PRINT("crash_dispatch_command_before", ("now"));
1296 DBUG_ABORT(); });
1297
1298 /* SHOW PROFILE instrumentation, begin */
1299 #if defined(ENABLED_PROFILING)
1300 thd->profiling.start_new_query();
1301 #endif
1302
1303 /* DTRACE instrumentation, begin */
1304 MYSQL_COMMAND_START(thd->thread_id, command,
1305 &thd->security_ctx->priv_user[0],
1306 (char *) thd->security_ctx->host_or_ip);
1307
1308 /* Performance Schema Interface instrumentation, begin */
1309 thd->m_statement_psi= MYSQL_REFINE_STATEMENT(thd->m_statement_psi,
1310 com_statement_info[command].m_key);
1311
1312 thd->set_command(command);
1313
1314 /*
1315 Commands which always take a long time are logged into
1316 the slow log only if opt_log_slow_admin_statements is set.
1317 */
1318 thd->enable_slow_log= TRUE;
1319 thd->clear_slow_extended();
1320 thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
1321 thd->set_time();
1322 if (thd->is_valid_time() == false)
1323 {
1324 /*
1325 If the time has gone past 2038 we need to shutdown the server. But
1326 there is possibility of getting invalid time value on some platforms.
1327 For example, gettimeofday() might return incorrect value on solaris
1328 platform. Hence validating the current time with 5 iterations before
1329 initiating the normal server shutdown process because of time getting
1330 past 2038.
1331 */
1332 const int max_tries= 5;
1333 sql_print_warning("Current time has got past year 2038. Validating current "
1334 "time with %d iterations before initiating the normal "
1335 "server shutdown process.", max_tries);
1336
1337 int tries= 0;
1338 while (++tries <= max_tries)
1339 {
1340 thd->set_time();
1341 if (thd->is_valid_time() == true)
1342 {
1343 sql_print_warning("Iteration %d: Obtained valid current time from "
1344 "system", tries);
1345 break;
1346 }
1347 sql_print_warning("Iteration %d: Current time obtained from system is "
1348 "greater than 2038", tries);
1349 }
1350 if (tries > max_tries)
1351 {
1352 /*
1353 If the time has got past 2038 we need to shut this server down.
1354 We do this by making sure every command is a shutdown and we
1355 have enough privileges to shut the server down
1356
1357 TODO: remove this when we have full 64 bit my_time_t support
1358 */
1359 sql_print_error("This MySQL server doesn't support dates later than 2038");
1360 thd->security_ctx->master_access|= SHUTDOWN_ACL;
1361 command= COM_SHUTDOWN;
1362 }
1363 }
1364 thd->set_query_id(next_query_id());
1365 inc_thread_running();
1366
1367 if (!(server_command_flags[command] & CF_SKIP_QUESTIONS))
1368 statistic_increment(thd->status_var.questions, &LOCK_status);
1369
1370 /* Declare userstat variables and start timer */
1371 double start_busy_usecs = 0.0;
1372 double start_cpu_nsecs = 0.0;
1373 if (unlikely(opt_userstat))
1374 userstat_start_timer(&start_busy_usecs, &start_cpu_nsecs);
1375
1376 /**
1377 Clear the set of flags that are expected to be cleared at the
1378 beginning of each command.
1379 */
1380 thd->server_status&= ~SERVER_STATUS_CLEAR_SET;
1381
1382 /**
1383 Enforce password expiration for all RPC commands, except the
1384 following:
1385
1386 COM_QUERY does a more fine-grained check later.
1387 COM_STMT_CLOSE and COM_STMT_SEND_LONG_DATA don't return anything.
1388 COM_PING only discloses information that the server is running,
1389 and that's available through other means.
1390 COM_QUIT should work even for expired statements.
1391 */
1392 if (unlikely(thd->security_ctx->password_expired &&
1393 command != COM_QUERY &&
1394 command != COM_STMT_CLOSE &&
1395 command != COM_STMT_SEND_LONG_DATA &&
1396 command != COM_PING &&
1397 command != COM_QUIT))
1398 {
1399 my_error(ER_MUST_CHANGE_PASSWORD, MYF(0));
1400 goto done;
1401 }
1402
1403 switch (command) {
1404 case COM_INIT_DB:
1405 {
1406 LEX_STRING tmp;
1407 status_var_increment(thd->status_var.com_stat[SQLCOM_CHANGE_DB]);
1408 thd->convert_string(&tmp, system_charset_info,
1409 packet, packet_length, thd->charset());
1410 if (!mysql_change_db(thd, &tmp, FALSE))
1411 {
1412 general_log_write(thd, command, thd->db, thd->db_length);
1413 my_ok(thd);
1414 }
1415 break;
1416 }
1417 #ifdef HAVE_REPLICATION
1418 case COM_REGISTER_SLAVE:
1419 {
1420 if (!register_slave(thd, (uchar*)packet, packet_length))
1421 my_ok(thd);
1422 break;
1423 }
1424 #endif
1425 case COM_CHANGE_USER:
1426 {
1427 int auth_rc;
1428 status_var_increment(thd->status_var.com_other);
1429
1430 thd->change_user();
1431 thd->clear_error(); // if errors from rollback
1432
1433 /* acl_authenticate() takes the data from net->read_pos */
1434 net->read_pos= (uchar*)packet;
1435
1436 USER_CONN *save_user_connect=
1437 const_cast<USER_CONN*>(thd->get_user_connect());
1438 char *save_db= thd->db;
1439 uint save_db_length= thd->db_length;
1440 Security_context save_security_ctx= *thd->security_ctx;
1441
1442 auth_rc= acl_authenticate(thd, packet_length);
1443 MYSQL_AUDIT_NOTIFY_CONNECTION_CHANGE_USER(thd);
1444 if (auth_rc)
1445 {
1446 my_free(thd->security_ctx->user);
1447 *thd->security_ctx= save_security_ctx;
1448 thd->set_user_connect(save_user_connect);
1449 thd->reset_db(save_db, save_db_length);
1450
1451 my_error(ER_ACCESS_DENIED_CHANGE_USER_ERROR, MYF(0),
1452 thd->security_ctx->user,
1453 thd->security_ctx->host_or_ip,
1454 (thd->password ? ER(ER_YES) : ER(ER_NO)));
1455 thd->killed= THD::KILL_CONNECTION;
1456 error=true;
1457 }
1458 else
1459 {
1460 #ifndef NO_EMBEDDED_ACCESS_CHECKS
1461 /* we've authenticated new user */
1462 if (save_user_connect)
1463 decrease_user_connections(save_user_connect);
1464 #endif /* NO_EMBEDDED_ACCESS_CHECKS */
1465 mysql_mutex_lock(&thd->LOCK_thd_data);
1466 my_free(save_db);
1467 mysql_mutex_unlock(&thd->LOCK_thd_data);
1468 my_free(save_security_ctx.user);
1469
1470 }
1471 break;
1472 }
1473 case COM_STMT_EXECUTE:
1474 {
1475 mysqld_stmt_execute(thd, packet, packet_length);
1476 break;
1477 }
1478 case COM_STMT_FETCH:
1479 {
1480 mysqld_stmt_fetch(thd, packet, packet_length);
1481 break;
1482 }
1483 case COM_STMT_SEND_LONG_DATA:
1484 {
1485 mysql_stmt_get_longdata(thd, packet, packet_length);
1486 break;
1487 }
1488 case COM_STMT_PREPARE:
1489 {
1490 mysqld_stmt_prepare(thd, packet, packet_length);
1491 break;
1492 }
1493 case COM_STMT_CLOSE:
1494 {
1495 mysqld_stmt_close(thd, packet, packet_length);
1496 break;
1497 }
1498 case COM_STMT_RESET:
1499 {
1500 mysqld_stmt_reset(thd, packet, packet_length);
1501 break;
1502 }
1503 case COM_QUERY:
1504 {
1505 DBUG_ASSERT(thd->m_digest == NULL);
1506 thd->m_digest= & thd->m_digest_state;
1507 thd->m_digest->reset(thd->m_token_array, max_digest_length);
1508
1509 if (alloc_query(thd, packet, packet_length))
1510 break; // fatal error is set
1511 MYSQL_QUERY_START(thd->query(), thd->thread_id,
1512 (char *) (thd->db ? thd->db : ""),
1513 &thd->security_ctx->priv_user[0],
1514 (char *) thd->security_ctx->host_or_ip);
1515 char *packet_end= thd->query() + thd->query_length();
1516
1517 if (opt_log_raw)
1518 general_log_write(thd, command, thd->query(), thd->query_length());
1519
1520 DBUG_PRINT("query",("%-.4096s",thd->query()));
1521
1522 #if defined(ENABLED_PROFILING)
1523 thd->profiling.set_query_source(thd->query(), thd->query_length());
1524 #endif
1525
1526 Parser_state parser_state;
1527 if (parser_state.init(thd, thd->query(), thd->query_length()))
1528 break;
1529
1530 mysql_parse(thd, thd->query(), thd->query_length(), &parser_state, false);
1531
1532 while (!thd->killed && (parser_state.m_lip.found_semicolon != NULL) &&
1533 ! thd->is_error())
1534 {
1535 /*
1536 Multiple queries exits, execute them individually
1537 */
1538 char *beginning_of_next_stmt= (char*) parser_state.m_lip.found_semicolon;
1539
1540 /* Finalize server status flags after executing a statement. */
1541 thd->update_server_status();
1542 thd->protocol->end_statement();
1543 query_cache_end_of_result(thd);
1544
1545 mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_STATUS,
1546 thd->get_stmt_da()->is_error() ?
1547 thd->get_stmt_da()->sql_errno() : 0,
1548 command_name[command].str);
1549
1550 ulong length= (ulong)(packet_end - beginning_of_next_stmt);
1551
1552 log_slow_statement(thd);
1553
1554 /* Remove garbage at start of query */
1555 while (length > 0 && my_isspace(thd->charset(), *beginning_of_next_stmt))
1556 {
1557 beginning_of_next_stmt++;
1558 length--;
1559 }
1560
1561 /* PSI end */
1562 MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
1563 thd->m_statement_psi= NULL;
1564 thd->m_digest= NULL;
1565
1566 /* DTRACE end */
1567 if (MYSQL_QUERY_DONE_ENABLED())
1568 {
1569 MYSQL_QUERY_DONE(thd->is_error());
1570 }
1571
1572 /* SHOW PROFILE end */
1573 #if defined(ENABLED_PROFILING)
1574 thd->profiling.finish_current_query();
1575 #endif
1576
1577 /* SHOW PROFILE begin */
1578 #if defined(ENABLED_PROFILING)
1579 thd->profiling.start_new_query("continuing");
1580 thd->profiling.set_query_source(beginning_of_next_stmt, length);
1581 #endif
1582
1583 /* DTRACE begin */
1584 MYSQL_QUERY_START(beginning_of_next_stmt, thd->thread_id,
1585 (char *) (thd->db ? thd->db : ""),
1586 &thd->security_ctx->priv_user[0],
1587 (char *) thd->security_ctx->host_or_ip);
1588
1589 /* PSI begin */
1590 thd->m_digest= & thd->m_digest_state;
1591 thd->m_digest->reset(thd->m_token_array, max_digest_length);
1592
1593 thd->m_statement_psi= MYSQL_START_STATEMENT(&thd->m_statement_state,
1594 com_statement_info[command].m_key,
1595 thd->db, thd->db_length,
1596 thd->charset());
1597 THD_STAGE_INFO(thd, stage_init);
1598
1599 thd->set_query_and_id(beginning_of_next_stmt, length,
1600 thd->charset(), next_query_id());
1601 /*
1602 Count each statement from the client.
1603 */
1604 statistic_increment(thd->status_var.questions, &LOCK_status);
1605 thd->set_time(); /* Reset the query start time. */
1606 parser_state.reset(beginning_of_next_stmt, length);
1607 /* TODO: set thd->lex->sql_command to SQLCOM_END here */
1608 mysql_parse(thd, beginning_of_next_stmt, length, &parser_state, false);
1609 }
1610
1611 DBUG_PRINT("info",("query ready"));
1612 break;
1613 }
1614 case COM_FIELD_LIST: // This isn't actually needed
1615 #ifdef DONT_ALLOW_SHOW_COMMANDS
1616 my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND),
1617 MYF(0)); /* purecov: inspected */
1618 break;
1619 #else
1620 {
1621 char *fields, *packet_end= packet + packet_length, *arg_end;
1622 /* Locked closure of all tables */
1623 TABLE_LIST table_list;
1624 LEX_STRING table_name;
1625 LEX_STRING db;
1626 /*
1627 SHOW statements should not add the used tables to the list of tables
1628 used in a transaction.
1629 */
1630 MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint();
1631
1632 status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_FIELDS]);
1633 if (thd->copy_db_to(&db.str, &db.length))
1634 break;
1635 /*
1636 We have name + wildcard in packet, separated by endzero
1637 */
1638 arg_end= strend(packet);
1639 uint arg_length= arg_end - packet;
1640
1641 /* Check given table name length. */
1642 if (arg_length >= packet_length || arg_length > NAME_LEN)
1643 {
1644 my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
1645 break;
1646 }
1647 thd->convert_string(&table_name, system_charset_info,
1648 packet, arg_length, thd->charset());
1649 enum_ident_name_check ident_check_status=
1650 check_table_name(table_name.str, table_name.length, FALSE);
1651 if (ident_check_status == IDENT_NAME_WRONG)
1652 {
1653 /* this is OK due to convert_string() null-terminating the string */
1654 my_error(ER_WRONG_TABLE_NAME, MYF(0), table_name.str);
1655 break;
1656 }
1657 else if (ident_check_status == IDENT_NAME_TOO_LONG)
1658 {
1659 my_error(ER_TOO_LONG_IDENT, MYF(0), table_name.str);
1660 break;
1661 }
1662 packet= arg_end + 1;
1663 mysql_reset_thd_for_next_command(thd);
1664 lex_start(thd);
1665 /* Must be before we init the table list. */
1666 if (lower_case_table_names)
1667 table_name.length= my_casedn_str(files_charset_info, table_name.str);
1668 table_list.init_one_table(db.str, db.length, table_name.str,
1669 table_name.length, table_name.str, TL_READ);
1670 /*
1671 Init TABLE_LIST members necessary when the undelrying
1672 table is view.
1673 */
1674 table_list.select_lex= &(thd->lex->select_lex);
1675 thd->lex->
1676 select_lex.table_list.link_in_list(&table_list,
1677 &table_list.next_local);
1678 thd->lex->add_to_query_tables(&table_list);
1679
1680 if (is_infoschema_db(table_list.db, table_list.db_length))
1681 {
1682 ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, table_list.alias);
1683 if (schema_table)
1684 table_list.schema_table= schema_table;
1685 }
1686
1687 uint query_length= (uint) (packet_end - packet); // Don't count end \0
1688 if (!(fields= (char *) thd->memdup(packet, query_length + 1)))
1689 break;
1690 thd->set_query(fields, query_length);
1691 general_log_print(thd, command, "%s %s", table_list.table_name, fields);
1692
1693 if (open_temporary_tables(thd, &table_list))
1694 break;
1695
1696 if (check_table_access(thd, SELECT_ACL, &table_list,
1697 TRUE, UINT_MAX, FALSE))
1698 break;
1699 /*
1700 Turn on an optimization relevant if the underlying table
1701 is a view: do not fill derived tables.
1702 */
1703 thd->lex->sql_command= SQLCOM_SHOW_FIELDS;
1704
1705 // See comment in opt_trace_disable_if_no_security_context_access()
1706 Opt_trace_start ots(thd, &table_list, thd->lex->sql_command, NULL,
1707 NULL, 0, NULL, NULL);
1708
1709 mysqld_list_fields(thd,&table_list,fields);
1710
1711 thd->lex->unit.cleanup();
1712 /* No need to rollback statement transaction, it's not started. */
1713 DBUG_ASSERT(thd->transaction.stmt.is_empty());
1714 close_thread_tables(thd);
1715 thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
1716
1717 if (thd->transaction_rollback_request)
1718 {
1719 /*
1720 Transaction rollback was requested since MDL deadlock was
1721 discovered while trying to open tables. Rollback transaction
1722 in all storage engines including binary log and release all
1723 locks.
1724 */
1725 trans_rollback_implicit(thd);
1726 thd->mdl_context.release_transactional_locks();
1727 }
1728
1729 thd->cleanup_after_query();
1730 break;
1731 }
1732 #endif
1733 case COM_QUIT:
1734 /* We don't calculate statistics for this command */
1735 general_log_print(thd, command, NullS);
1736 net->error=0; // Don't give 'abort' message
1737 thd->get_stmt_da()->disable_status(); // Don't send anything back
1738 error=TRUE; // End server
1739 break;
1740 #ifndef EMBEDDED_LIBRARY
1741 case COM_BINLOG_DUMP_GTID:
1742 error= com_binlog_dump_gtid(thd, packet, packet_length);
1743 break;
1744 case COM_BINLOG_DUMP:
1745 error= com_binlog_dump(thd, packet, packet_length);
1746 break;
1747 #endif
1748 case COM_REFRESH:
1749 {
1750 int not_used;
1751
1752 if (packet_length < 1)
1753 {
1754 my_error(ER_MALFORMED_PACKET, MYF(0));
1755 break;
1756 }
1757
1758 /*
1759 Initialize thd->lex since it's used in many base functions, such as
1760 open_tables(). Otherwise, it remains unitialized and may cause crash
1761 during execution of COM_REFRESH.
1762 */
1763 lex_start(thd);
1764
1765 status_var_increment(thd->status_var.com_stat[SQLCOM_FLUSH]);
1766 ulong options= (ulong) (uchar) packet[0];
1767 if (trans_commit_implicit(thd))
1768 break;
1769 thd->mdl_context.release_transactional_locks();
1770 if (check_global_access(thd,RELOAD_ACL))
1771 break;
1772 general_log_print(thd, command, NullS);
1773 #ifndef DBUG_OFF
1774 bool debug_simulate= FALSE;
1775 DBUG_EXECUTE_IF("simulate_detached_thread_refresh", debug_simulate= TRUE;);
1776 if (debug_simulate)
1777 {
1778 /*
1779 Simulate a reload without a attached thread session.
1780 Provides a environment similar to that of when the
1781 server receives a SIGHUP signal and reloads caches
1782 and flushes tables.
1783 */
1784 bool res;
1785 my_pthread_setspecific_ptr(THR_THD, NULL);
1786 res= reload_acl_and_cache(NULL, options | REFRESH_FAST,
1787 NULL, ¬_used);
1788 my_pthread_setspecific_ptr(THR_THD, thd);
1789 if (res)
1790 break;
1791 }
1792 else
1793 #endif
1794 if (reload_acl_and_cache(thd, options, (TABLE_LIST*) 0, ¬_used))
1795 break;
1796 if (trans_commit_implicit(thd))
1797 break;
1798 close_thread_tables(thd);
1799 thd->mdl_context.release_transactional_locks();
1800 my_ok(thd);
1801 break;
1802 }
1803 #ifndef EMBEDDED_LIBRARY
1804 case COM_SHUTDOWN:
1805 {
1806 status_var_increment(thd->status_var.com_other);
1807 if (check_global_access(thd,SHUTDOWN_ACL))
1808 break; /* purecov: inspected */
1809 /*
1810 If the client is < 4.1.3, it is going to send us no argument; then
1811 packet_length is 0, packet[0] is the end 0 of the packet. Note that
1812 SHUTDOWN_DEFAULT is 0. If client is >= 4.1.3, the shutdown level is in
1813 packet[0].
1814 */
1815 enum mysql_enum_shutdown_level level;
1816 if (packet_length == 0 || !thd->is_valid_time())
1817 level= SHUTDOWN_DEFAULT;
1818 else
1819 level= (enum mysql_enum_shutdown_level) (uchar) packet[0];
1820 if (level == SHUTDOWN_DEFAULT)
1821 level= SHUTDOWN_WAIT_ALL_BUFFERS; // soon default will be configurable
1822 else if (level != SHUTDOWN_WAIT_ALL_BUFFERS)
1823 {
1824 my_error(ER_NOT_SUPPORTED_YET, MYF(0), "this shutdown level");
1825 break;
1826 }
1827 DBUG_PRINT("quit",("Got shutdown command for level %u", level));
1828 general_log_print(thd, command, NullS);
1829 my_eof(thd);
1830 kill_mysql();
1831 error=TRUE;
1832 break;
1833 }
1834 #endif
1835 case COM_STATISTICS:
1836 {
1837 STATUS_VAR current_global_status_var;
1838 ulong uptime;
1839 uint length MY_ATTRIBUTE((unused));
1840 ulonglong queries_per_second1000;
1841 char buff[250];
1842 uint buff_len= sizeof(buff);
1843
1844 general_log_print(thd, command, NullS);
1845 status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS]);
1846 calc_sum_of_all_status(¤t_global_status_var);
1847 if (!(uptime= (ulong) (thd->start_time.tv_sec - server_start_time)))
1848 queries_per_second1000= 0;
1849 else
1850 queries_per_second1000= thd->query_id * LL(1000) / uptime;
1851
1852 length= my_snprintf(buff, buff_len - 1,
1853 "Uptime: %lu Threads: %d Questions: %lu "
1854 "Slow queries: %llu Opens: %llu Flush tables: %lu "
1855 "Open tables: %u Queries per second avg: %u.%03u",
1856 uptime,
1857 (int) get_thread_count(), (ulong) thd->query_id,
1858 current_global_status_var.long_query_count,
1859 current_global_status_var.opened_tables,
1860 refresh_version,
1861 table_cache_manager.cached_tables(),
1862 (uint) (queries_per_second1000 / 1000),
1863 (uint) (queries_per_second1000 % 1000));
1864 #ifdef EMBEDDED_LIBRARY
1865 /* Store the buffer in permanent memory */
1866 my_ok(thd, 0, 0, buff);
1867 #else
1868 (void) my_net_write(net, (uchar*) buff, length);
1869 (void) net_flush(net);
1870 thd->get_stmt_da()->disable_status();
1871 #endif
1872 break;
1873 }
1874 case COM_PING:
1875 status_var_increment(thd->status_var.com_other);
1876 my_ok(thd); // Tell client we are alive
1877 break;
1878 case COM_PROCESS_INFO:
1879 status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_PROCESSLIST]);
1880 if (!thd->security_ctx->priv_user[0] &&
1881 check_global_access(thd, PROCESS_ACL))
1882 break;
1883 general_log_print(thd, command, NullS);
1884 mysqld_list_processes(thd,
1885 thd->security_ctx->master_access & PROCESS_ACL ?
1886 NullS : thd->security_ctx->priv_user, 0);
1887 break;
1888 case COM_PROCESS_KILL:
1889 {
1890 if (thread_id & (~0xfffffffful))
1891 my_error(ER_DATA_OUT_OF_RANGE, MYF(0), "thread_id", "mysql_kill()");
1892 else if (packet_length < 4)
1893 my_error(ER_MALFORMED_PACKET, MYF(0));
1894 else
1895 {
1896 status_var_increment(thd->status_var.com_stat[SQLCOM_KILL]);
1897 ulong id=(ulong) uint4korr(packet);
1898 sql_kill(thd,id,false);
1899 }
1900 break;
1901 }
1902 case COM_SET_OPTION:
1903 {
1904
1905 if (packet_length < 2)
1906 {
1907 my_error(ER_MALFORMED_PACKET, MYF(0));
1908 break;
1909 }
1910 status_var_increment(thd->status_var.com_stat[SQLCOM_SET_OPTION]);
1911 uint opt_command= uint2korr(packet);
1912
1913 switch (opt_command) {
1914 case (int) MYSQL_OPTION_MULTI_STATEMENTS_ON:
1915 thd->client_capabilities|= CLIENT_MULTI_STATEMENTS;
1916 my_eof(thd);
1917 break;
1918 case (int) MYSQL_OPTION_MULTI_STATEMENTS_OFF:
1919 thd->client_capabilities&= ~CLIENT_MULTI_STATEMENTS;
1920 my_eof(thd);
1921 break;
1922 default:
1923 my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
1924 break;
1925 }
1926 break;
1927 }
1928 case COM_DEBUG:
1929 status_var_increment(thd->status_var.com_other);
1930 if (check_global_access(thd, SUPER_ACL))
1931 break; /* purecov: inspected */
1932 mysql_print_status();
1933 general_log_print(thd, command, NullS);
1934 my_eof(thd);
1935 break;
1936 case COM_SLEEP:
1937 case COM_CONNECT: // Impossible here
1938 case COM_TIME: // Impossible from client
1939 case COM_DELAYED_INSERT:
1940 case COM_END:
1941 default:
1942 my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
1943 break;
1944 }
1945
1946 done:
1947 DBUG_ASSERT(thd->derived_tables == NULL &&
1948 (thd->open_tables == NULL ||
1949 (thd->locked_tables_mode == LTM_LOCK_TABLES)));
1950
1951 /* Update user statistics only if at least one timer was initialized */
1952 if (unlikely(start_busy_usecs > 0.0 || start_cpu_nsecs > 0.0))
1953 {
1954 userstat_finish_timer(start_busy_usecs, start_cpu_nsecs, &thd->busy_time,
1955 &thd->cpu_time);
1956 /* Updates THD stats and the global user stats. */
1957 thd->update_stats(true);
1958 #ifndef EMBEDDED_LIBRARY
1959 update_global_user_stats(thd, true, time(NULL));
1960 #endif
1961 }
1962
1963 /* Finalize server status flags after executing a command. */
1964 thd->update_server_status();
1965 if (thd->killed)
1966 thd->send_kill_message();
1967 thd->protocol->end_statement();
1968 query_cache_end_of_result(thd);
1969
1970 if (!thd->is_error() && !thd->killed_errno())
1971 mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_RESULT, 0, 0);
1972
1973 mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_STATUS,
1974 thd->get_stmt_da()->is_error() ?
1975 thd->get_stmt_da()->sql_errno() : 0,
1976 command_name[command].str);
1977
1978 log_slow_statement(thd);
1979
1980 THD_STAGE_INFO(thd, stage_cleaning_up);
1981 if (thd->lex->sql_command == SQLCOM_CREATE_TABLE)
1982 {
1983 DEBUG_SYNC(thd, "dispatch_create_table_command_before_thd_root_free");
1984 }
1985
1986 if (thd->killed == THD::KILL_QUERY ||
1987 thd->killed == THD::KILL_TIMEOUT ||
1988 thd->killed == THD::KILL_BAD_DATA)
1989 {
1990 thd->killed= THD::NOT_KILLED;
1991 thd->mysys_var->abort= 0;
1992 }
1993
1994 thd->reset_query();
1995 thd->set_command(COM_SLEEP);
1996 thd->proc_info= 0;
1997 thd->lex->sql_command= SQLCOM_END;
1998
1999 /* Performance Schema Interface instrumentation, end */
2000 MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
2001 thd->m_statement_psi= NULL;
2002 thd->m_digest= NULL;
2003
2004 dec_thread_running();
2005 thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory
2006 free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
2007
2008 /* DTRACE instrumentation, end */
2009 if (MYSQL_QUERY_DONE_ENABLED() || MYSQL_COMMAND_DONE_ENABLED())
2010 {
2011 int res MY_ATTRIBUTE((unused));
2012 res= (int) thd->is_error();
2013 if (command == COM_QUERY)
2014 {
2015 MYSQL_QUERY_DONE(res);
2016 }
2017 MYSQL_COMMAND_DONE(res);
2018 }
2019
2020 /* SHOW PROFILE instrumentation, end */
2021 #if defined(ENABLED_PROFILING)
2022 thd->profiling.finish_current_query();
2023 #endif
2024
2025 DBUG_RETURN(error);
2026 }
2027
2028 /**
2029 Calculate execution time for the current query.
2030
2031 SET queries outside stored procedures are ignored so that
2032 statements changing query_exec_time are not affected by
2033 themselves.
2034
2035 @param thd thread handle
2036 @param lex current relative time in microseconds
2037
2038 @return time in microseconds from utime_after_lock
2039 */
2040
get_query_exec_time(THD * thd,ulonglong cur_utime)2041 static inline ulonglong get_query_exec_time(THD *thd, ulonglong cur_utime)
2042 {
2043 ulonglong res;
2044
2045 #ifndef DBUG_OFF
2046 if (thd->variables.query_exec_time != 0)
2047 res= thd->lex->sql_command != SQLCOM_SET_OPTION ?
2048 thd->variables.query_exec_time : 0;
2049 else
2050 #endif
2051 res= cur_utime - thd->utime_after_lock;
2052
2053 if (res > thd->variables.long_query_time)
2054 thd->server_status|= SERVER_QUERY_WAS_SLOW;
2055 else
2056 thd->server_status&= ~SERVER_QUERY_WAS_SLOW;
2057
2058 return res;
2059 }
2060
2061
copy_global_to_session(THD * thd,ulong flag,const ulong * val)2062 static inline void copy_global_to_session(THD *thd, ulong flag,
2063 const ulong *val)
2064 {
2065 my_ptrdiff_t offset = ((char *)val - (char *)&global_system_variables);
2066 if (opt_slow_query_log_use_global_control & (1ULL << flag))
2067 *(ulong *)((char *) &thd->variables + offset) = *val;
2068 }
2069
2070
copy_global_to_session(THD * thd,ulong flag,const ulonglong * val)2071 static inline void copy_global_to_session(THD *thd, ulong flag,
2072 const ulonglong *val)
2073 {
2074 my_ptrdiff_t offset = ((char *)val - (char *)&global_system_variables);
2075 if (opt_slow_query_log_use_global_control & (1ULL << flag))
2076 *(ulonglong *)((char *) &thd->variables + offset) = *val;
2077 }
2078
2079
2080
2081 /**
2082 Check whether we need to write the current statement (or its rewritten
2083 version if it exists) to the slow query log.
2084 As a side-effect, a digest of suppressed statements may be written.
2085
2086 @param thd thread handle
2087
2088 @retval
2089 true statement needs to be logged
2090 @retval
2091 false statement does not need to be logged
2092 */
2093
log_slow_applicable(THD * thd)2094 bool log_slow_applicable(THD *thd)
2095 {
2096 DBUG_ENTER("log_slow_applicable");
2097
2098 /*
2099 The following should never be true with our current code base,
2100 but better to keep this here so we don't accidently try to log a
2101 statement in a trigger or stored function
2102 */
2103 if (unlikely(thd->in_sub_stmt))
2104 DBUG_RETURN(false); // Don't set time for sub stmt
2105
2106 /* Follow the slow log filter configuration. */
2107 if (thd->variables.log_slow_filter != 0 &&
2108 (!(thd->variables.log_slow_filter & thd->query_plan_flags) ||
2109 ((thd->variables.log_slow_filter & (1UL << SLOG_F_QC_NO)) &&
2110 (thd->query_plan_flags & QPLAN_QC))))
2111 DBUG_RETURN(false);
2112
2113 ulonglong end_utime_of_query= thd->current_utime();
2114 ulonglong query_exec_time= get_query_exec_time(thd, end_utime_of_query);
2115
2116 /*
2117 Don't log the CALL statement if slow statements logging
2118 inside of stored procedures is enabled.
2119 */
2120 if (opt_log_slow_sp_statements > 0 && thd->lex)
2121 {
2122 if (thd->lex->sql_command == SQLCOM_CALL)
2123 {
2124 if (thd->sp_runtime_ctx && thd->stmt_arena)
2125 {
2126 int sql_command= ((sp_lex_instr *)thd->stmt_arena)->get_command();
2127 if (sql_command == SQLCOM_CALL || sql_command == -1)
2128 DBUG_RETURN(false);
2129 }
2130 else
2131 DBUG_RETURN(false);
2132 }
2133 else if (thd->lex->sql_command == SQLCOM_EXECUTE)
2134 {
2135 Statement *stmt;
2136 LEX_STRING *name= &thd->lex->prepared_stmt_name;
2137 if ((stmt= thd->stmt_map.find_by_name(name)) != NULL &&
2138 stmt->lex && stmt->lex->sql_command == SQLCOM_CALL)
2139 DBUG_RETURN(false);
2140 }
2141 }
2142
2143 /*
2144 Low long_query_time value most likely means user is debugging stuff and even
2145 though some thread's queries are not supposed to be logged b/c of the rate
2146 limit, if one of them takes long enough (>= 1 second) it will be sensible
2147 to make an exception and write to slow log anyway.
2148 */
2149
2150 system_variables const &g= global_system_variables;
2151 copy_global_to_session(thd, SLOG_UG_LOG_SLOW_FILTER,
2152 &g.log_slow_filter);
2153 copy_global_to_session(thd, SLOG_UG_LOG_SLOW_RATE_LIMIT,
2154 &g.log_slow_rate_limit);
2155 copy_global_to_session(thd, SLOG_UG_LOG_SLOW_VERBOSITY,
2156 &g.log_slow_verbosity);
2157 copy_global_to_session(thd, SLOG_UG_LONG_QUERY_TIME,
2158 &g.long_query_time);
2159 copy_global_to_session(thd, SLOG_UG_MIN_EXAMINED_ROW_LIMIT,
2160 &g.min_examined_row_limit);
2161
2162 if (opt_slow_query_log_rate_type == SLOG_RT_QUERY
2163 && thd->variables.log_slow_rate_limit
2164 && my_rnd(&thd->slog_rand) * ((double)thd->variables.log_slow_rate_limit) > 1.0
2165 && query_exec_time < slow_query_log_always_write_time
2166 && (thd->variables.long_query_time >= 1000000
2167 || (ulong) query_exec_time < 1000000)) {
2168 DBUG_RETURN(false);
2169 }
2170 if (opt_slow_query_log_rate_type == SLOG_RT_SESSION
2171 && thd->variables.log_slow_rate_limit
2172 && thd->thread_id % thd->variables.log_slow_rate_limit
2173 && query_exec_time < slow_query_log_always_write_time
2174 && (thd->variables.long_query_time >= 1000000
2175 || (ulong) query_exec_time < 1000000)) {
2176 DBUG_RETURN(false);
2177 }
2178
2179 /*
2180 Do not log administrative statements unless the appropriate option is
2181 set.
2182 */
2183 if (thd->enable_slow_log)
2184 {
2185 bool warn_no_index= ((thd->server_status &
2186 (SERVER_QUERY_NO_INDEX_USED |
2187 SERVER_QUERY_NO_GOOD_INDEX_USED)) &&
2188 opt_log_queries_not_using_indexes &&
2189 !(sql_command_flags[thd->lex->sql_command] &
2190 CF_STATUS_COMMAND));
2191 bool log_this_query= ((thd->server_status & SERVER_QUERY_WAS_SLOW) ||
2192 warn_no_index) &&
2193 (thd->get_examined_row_count() >=
2194 thd->variables.min_examined_row_limit);
2195 bool suppress_logging= log_throttle_qni.log(thd, warn_no_index);
2196
2197 if (!suppress_logging && log_this_query)
2198 DBUG_RETURN(true);
2199 }
2200 DBUG_RETURN(false);
2201 }
2202
2203
2204 /**
2205 Unconditionally the current statement (or its rewritten version if it
2206 exists) to the slow query log.
2207
2208 @param thd thread handle
2209 */
2210
log_slow_do(THD * thd)2211 void log_slow_do(THD *thd)
2212 {
2213 DBUG_ENTER("log_slow_do");
2214
2215 thd_proc_info(thd, "logging slow query");
2216 THD_STAGE_INFO(thd, stage_logging_slow_query);
2217 thd->status_var.long_query_count++;
2218
2219 if (thd->rewritten_query.length())
2220 slow_log_print(thd,
2221 thd->rewritten_query.c_ptr_safe(),
2222 thd->rewritten_query.length());
2223 else
2224 slow_log_print(thd, thd->query(), thd->query_length());
2225
2226 DBUG_VOID_RETURN;
2227 }
2228
2229
2230 /**
2231 Check whether we need to write the current statement to the slow query
2232 log. If so, do so. This is a wrapper for the two functions above;
2233 most callers should use this wrapper. Only use the above functions
2234 directly if you have expensive rewriting that you only need to do if
2235 the query actually needs to be logged (e.g. SP variables / NAME_CONST
2236 substitution when executing a PROCEDURE).
2237 A digest of suppressed statements may be logged instead of the current
2238 statement.
2239
2240 @param thd thread handle
2241 */
2242
log_slow_statement(THD * thd)2243 void log_slow_statement(THD *thd)
2244 {
2245 DBUG_ENTER("log_slow_statement");
2246
2247 if (log_slow_applicable(thd))
2248 log_slow_do(thd);
2249
2250 DBUG_VOID_RETURN;
2251 }
2252
2253
2254 /**
2255 Create a TABLE_LIST object for an INFORMATION_SCHEMA table.
2256
2257 This function is used in the parser to convert a SHOW or DESCRIBE
2258 table_name command to a SELECT from INFORMATION_SCHEMA.
2259 It prepares a SELECT_LEX and a TABLE_LIST object to represent the
2260 given command as a SELECT parse tree.
2261
2262 @param thd thread handle
2263 @param lex current lex
2264 @param table_ident table alias if it's used
2265 @param schema_table_idx the type of the INFORMATION_SCHEMA table to be
2266 created
2267
2268 @note
2269 Due to the way this function works with memory and LEX it cannot
2270 be used outside the parser (parse tree transformations outside
2271 the parser break PS and SP).
2272
2273 @retval
2274 0 success
2275 @retval
2276 1 out of memory or SHOW commands are not allowed
2277 in this version of the server.
2278 */
2279
prepare_schema_table(THD * thd,LEX * lex,Table_ident * table_ident,enum enum_schema_tables schema_table_idx)2280 int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
2281 enum enum_schema_tables schema_table_idx)
2282 {
2283 SELECT_LEX *schema_select_lex= NULL;
2284 DBUG_ENTER("prepare_schema_table");
2285
2286 switch (schema_table_idx) {
2287 case SCH_SCHEMATA:
2288 #if defined(DONT_ALLOW_SHOW_COMMANDS)
2289 my_message(ER_NOT_ALLOWED_COMMAND,
2290 ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */
2291 DBUG_RETURN(1);
2292 #else
2293 break;
2294 #endif
2295
2296 case SCH_TABLE_NAMES:
2297 case SCH_TABLES:
2298 case SCH_TEMPORARY_TABLES:
2299 case SCH_GLOBAL_TEMPORARY_TABLES:
2300 case SCH_VIEWS:
2301 case SCH_TRIGGERS:
2302 case SCH_EVENTS:
2303 #ifdef DONT_ALLOW_SHOW_COMMANDS
2304 my_message(ER_NOT_ALLOWED_COMMAND,
2305 ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */
2306 DBUG_RETURN(1);
2307 #else
2308 {
2309 LEX_STRING db;
2310 size_t dummy;
2311 if (lex->select_lex.db == NULL &&
2312 lex->copy_db_to(&lex->select_lex.db, &dummy))
2313 {
2314 DBUG_RETURN(1);
2315 }
2316 schema_select_lex= new SELECT_LEX();
2317 db.str= schema_select_lex->db= lex->select_lex.db;
2318 schema_select_lex->table_list.first= NULL;
2319 db.length= strlen(db.str);
2320
2321 if (check_and_convert_db_name(&db, FALSE) != IDENT_NAME_OK)
2322 DBUG_RETURN(1);
2323 break;
2324 }
2325 #endif
2326 case SCH_COLUMNS:
2327 case SCH_STATISTICS:
2328 {
2329 #ifdef DONT_ALLOW_SHOW_COMMANDS
2330 my_message(ER_NOT_ALLOWED_COMMAND,
2331 ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */
2332 DBUG_RETURN(1);
2333 #else
2334 DBUG_ASSERT(table_ident);
2335 TABLE_LIST **query_tables_last= lex->query_tables_last;
2336 schema_select_lex= new SELECT_LEX();
2337 /* 'parent_lex' is used in init_query() so it must be before it. */
2338 schema_select_lex->parent_lex= lex;
2339 schema_select_lex->init_query();
2340 if (!schema_select_lex->add_table_to_list(thd, table_ident, 0, 0, TL_READ,
2341 MDL_SHARED_READ))
2342 DBUG_RETURN(1);
2343 lex->query_tables_last= query_tables_last;
2344 break;
2345 }
2346 #endif
2347 case SCH_PROFILES:
2348 /*
2349 Mark this current profiling record to be discarded. We don't
2350 wish to have SHOW commands show up in profiling.
2351 */
2352 #if defined(ENABLED_PROFILING)
2353 thd->profiling.discard_current_query();
2354 #endif
2355 break;
2356 case SCH_USER_STATS:
2357 case SCH_CLIENT_STATS:
2358 case SCH_THREAD_STATS:
2359 if (check_global_access(thd, SUPER_ACL | PROCESS_ACL))
2360 DBUG_RETURN(1);
2361 case SCH_TABLE_STATS:
2362 case SCH_INDEX_STATS:
2363 case SCH_OPTIMIZER_TRACE:
2364 case SCH_OPEN_TABLES:
2365 case SCH_VARIABLES:
2366 case SCH_STATUS:
2367 case SCH_PROCEDURES:
2368 case SCH_CHARSETS:
2369 case SCH_ENGINES:
2370 case SCH_COLLATIONS:
2371 case SCH_COLLATION_CHARACTER_SET_APPLICABILITY:
2372 case SCH_USER_PRIVILEGES:
2373 case SCH_SCHEMA_PRIVILEGES:
2374 case SCH_TABLE_PRIVILEGES:
2375 case SCH_COLUMN_PRIVILEGES:
2376 case SCH_TABLE_CONSTRAINTS:
2377 case SCH_KEY_COLUMN_USAGE:
2378 default:
2379 break;
2380 }
2381
2382 SELECT_LEX *select_lex= lex->current_select;
2383 if (make_schema_select(thd, select_lex, schema_table_idx))
2384 {
2385 DBUG_RETURN(1);
2386 }
2387 TABLE_LIST *table_list= select_lex->table_list.first;
2388 table_list->schema_select_lex= schema_select_lex;
2389 table_list->schema_table_reformed= 1;
2390 DBUG_RETURN(0);
2391 }
2392
2393
2394 /**
2395 Read query from packet and store in thd->query.
2396 Used in COM_QUERY and COM_STMT_PREPARE.
2397
2398 Sets the following THD variables:
2399 - query
2400 - query_length
2401
2402 @retval
2403 FALSE ok
2404 @retval
2405 TRUE error; In this case thd->fatal_error is set
2406 */
2407
2408 bool alloc_query(THD *thd, const char *packet, uint packet_length)
2409 {
2410 char *query;
2411 /* Remove garbage at start and end of query */
2412 while (packet_length > 0 && my_isspace(thd->charset(), packet[0]))
2413 {
2414 packet++;
2415 packet_length--;
2416 }
2417 const char *pos= packet + packet_length; // Point at end null
2418 while (packet_length > 0 &&
2419 (pos[-1] == ';' || my_isspace(thd->charset() ,pos[-1])))
2420 {
2421 pos--;
2422 packet_length--;
2423 }
2424 /* We must allocate some extra memory for query cache
2425
2426 The query buffer layout is:
2427 buffer :==
2428 <statement> The input statement(s)
2429 '\0' Terminating null char (1 byte)
2430 <length> Length of following current database name (size_t)
2431 <db_name> Name of current database
2432 <flags> Flags struct
2433 */
2434 if (! (query= (char*) thd->memdup_w_gap(packet,
2435 packet_length,
2436 1 + sizeof(size_t) + thd->db_length +
2437 QUERY_CACHE_FLAGS_SIZE)))
2438 return TRUE;
2439 query[packet_length]= '\0';
2440 /*
2441 Space to hold the name of the current database is allocated. We
2442 also store this length, in case current database is changed during
2443 execution. We might need to reallocate the 'query' buffer
2444 */
2445 char *len_pos = (query + packet_length + 1);
2446 memcpy(len_pos, (char *) &thd->db_length, sizeof(size_t));
2447
2448 thd->set_query(query, packet_length);
2449 thd->rewritten_query.free(); // free here lest PS break
2450
2451 /* Reclaim some memory */
2452 thd->packet.shrink(thd->variables.net_buffer_length);
2453 thd->convert_buffer.shrink(thd->variables.net_buffer_length);
2454
2455 return FALSE;
2456 }
2457
2458 static void reset_one_shot_variables(THD *thd)
2459 {
2460 thd->variables.character_set_client=
2461 global_system_variables.character_set_client;
2462 thd->variables.collation_connection=
2463 global_system_variables.collation_connection;
2464 thd->variables.collation_database=
2465 global_system_variables.collation_database;
2466 thd->variables.collation_server=
2467 global_system_variables.collation_server;
2468 thd->update_charset();
2469 thd->variables.time_zone=
2470 global_system_variables.time_zone;
2471 thd->variables.lc_time_names= &my_locale_en_US;
2472 thd->one_shot_set= 0;
2473 }
2474
2475
2476 static
2477 bool sp_process_definer(THD *thd)
2478 {
2479 DBUG_ENTER("sp_process_definer");
2480
2481 LEX *lex= thd->lex;
2482
2483 /*
2484 If the definer is not specified, this means that CREATE-statement missed
2485 DEFINER-clause. DEFINER-clause can be missed in two cases:
2486
2487 - The user submitted a statement w/o the clause. This is a normal
2488 case, we should assign CURRENT_USER as definer.
2489
2490 - Our slave received an updated from the master, that does not
2491 replicate definer for stored rountines. We should also assign
2492 CURRENT_USER as definer here, but also we should mark this routine
2493 as NON-SUID. This is essential for the sake of backward
2494 compatibility.
2495
2496 The problem is the slave thread is running under "special" user (@),
2497 that actually does not exist. In the older versions we do not fail
2498 execution of a stored routine if its definer does not exist and
2499 continue the execution under the authorization of the invoker
2500 (BUG#13198). And now if we try to switch to slave-current-user (@),
2501 we will fail.
2502
2503 Actually, this leads to the inconsistent state of master and
2504 slave (different definers, different SUID behaviour), but it seems,
2505 this is the best we can do.
2506 */
2507
2508 if (!lex->definer)
2509 {
2510 Prepared_stmt_arena_holder ps_arena_holder(thd);
2511
2512 lex->definer= create_default_definer(thd);
2513
2514 /* Error has been already reported. */
2515 if (lex->definer == NULL)
2516 DBUG_RETURN(TRUE);
2517
2518 if (thd->slave_thread && lex->sphead)
2519 lex->sphead->m_chistics->suid= SP_IS_NOT_SUID;
2520 }
2521 else
2522 {
2523 /*
2524 If the specified definer differs from the current user, we
2525 should check that the current user has SUPER privilege (in order
2526 to create a stored routine under another user one must have
2527 SUPER privilege).
2528 */
2529 if ((strcmp(lex->definer->user.str, thd->security_ctx->priv_user) ||
2530 my_strcasecmp(system_charset_info, lex->definer->host.str,
2531 thd->security_ctx->priv_host)) &&
2532 check_global_access(thd, SUPER_ACL))
2533 {
2534 thd->diff_access_denied_errors++;
2535 my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
2536 DBUG_RETURN(TRUE);
2537 }
2538 }
2539
2540 /* Check that the specified definer exists. Emit a warning if not. */
2541
2542 #ifndef NO_EMBEDDED_ACCESS_CHECKS
2543 if (!is_acl_user(lex->definer->host.str, lex->definer->user.str))
2544 {
2545 push_warning_printf(thd,
2546 Sql_condition::WARN_LEVEL_NOTE,
2547 ER_NO_SUCH_USER,
2548 ER(ER_NO_SUCH_USER),
2549 lex->definer->user.str,
2550 lex->definer->host.str);
2551 }
2552 #endif /* NO_EMBEDDED_ACCESS_CHECKS */
2553
2554 DBUG_RETURN(FALSE);
2555 }
2556
2557
2558 /**
2559 Auxiliary call that opens and locks tables for LOCK TABLES statement
2560 and initializes the list of locked tables.
2561
2562 @param thd Thread context.
2563 @param tables List of tables to be locked.
2564
2565 @return FALSE in case of success, TRUE in case of error.
2566 */
2567
2568 static bool lock_tables_open_and_lock_tables(THD *thd, TABLE_LIST *tables)
2569 {
2570 Lock_tables_prelocking_strategy lock_tables_prelocking_strategy;
2571 uint counter;
2572 TABLE_LIST *table;
2573
2574 thd->in_lock_tables= 1;
2575
2576 if (open_tables(thd, &tables, &counter, 0, &lock_tables_prelocking_strategy))
2577 goto err;
2578
2579 /*
2580 We allow to change temporary tables even if they were locked for read
2581 by LOCK TABLES. To avoid a discrepancy between lock acquired at LOCK
2582 TABLES time and by the statement which is later executed under LOCK TABLES
2583 we ensure that for temporary tables we always request a write lock (such
2584 discrepancy can cause problems for the storage engine).
2585 We don't set TABLE_LIST::lock_type in this case as this might result in
2586 extra warnings from THD::decide_logging_format() even though binary logging
2587 is totally irrelevant for LOCK TABLES.
2588 */
2589 for (table= tables; table; table= table->next_global)
2590 if (!table->placeholder() && table->table->s->tmp_table)
2591 table->table->reginfo.lock_type= TL_WRITE;
2592
2593 if (lock_tables(thd, tables, counter, 0) ||
2594 thd->locked_tables_list.init_locked_tables(thd))
2595 goto err;
2596
2597 thd->in_lock_tables= 0;
2598
2599 return FALSE;
2600
2601 err:
2602 thd->in_lock_tables= 0;
2603
2604 trans_rollback_stmt(thd);
2605 /*
2606 Need to end the current transaction, so the storage engine (InnoDB)
2607 can free its locks if LOCK TABLES locked some tables before finding
2608 that it can't lock a table in its list
2609 */
2610 trans_rollback(thd);
2611 /* Close tables and release metadata locks. */
2612 close_thread_tables(thd);
2613 DBUG_ASSERT(!thd->locked_tables_mode);
2614 thd->mdl_context.release_transactional_locks();
2615 return TRUE;
2616 }
2617
2618 /**
2619 Acquire a global backup lock.
2620
2621 @param thd Thread context.
2622
2623 @return false on success, true in case of error.
2624 */
2625
2626 static bool lock_tables_for_backup(THD *thd)
2627 {
2628 bool res;
2629
2630 DBUG_ENTER("lock_tables_for_backup");
2631
2632 if (check_global_access(thd, RELOAD_ACL))
2633 DBUG_RETURN(true);
2634
2635 if (delay_key_write_options == DELAY_KEY_WRITE_ALL)
2636 {
2637 my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "delay_key_write=ALL");
2638 DBUG_RETURN(true);
2639 }
2640 /*
2641 Do nothing if the current connection already owns the LOCK TABLES FOR
2642 BACKUP lock or the global read lock (as it's a more restrictive lock).
2643 */
2644 if (thd->backup_tables_lock.is_acquired() ||
2645 thd->global_read_lock.is_acquired())
2646 DBUG_RETURN(false);
2647
2648 /*
2649 Do not allow backup locks under regular LOCK TABLES, FLUSH TABLES ... FOR
2650 EXPORT, or FLUSH TABLES <table_list> WITH READ LOCK.
2651 */
2652 if (thd->variables.option_bits & OPTION_TABLE_LOCK)
2653 {
2654 my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
2655 ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
2656 DBUG_RETURN(true);
2657 }
2658
2659 res= thd->backup_tables_lock.acquire(thd);
2660
2661 if (ha_store_binlog_info(thd))
2662 {
2663 thd->backup_tables_lock.release(thd);
2664 res= true;
2665 }
2666
2667 DBUG_RETURN(res);
2668 }
2669
2670 /**
2671 Acquire a global binlog lock.
2672
2673 @param thd Thread context.
2674
2675 @return FALSE in case of success, TRUE in case of error.
2676 */
2677
2678 bool lock_binlog_for_backup(THD *thd)
2679 {
2680 DBUG_ENTER("lock_binlog_for_backup");
2681
2682 if (check_global_access(thd, RELOAD_ACL))
2683 DBUG_RETURN(true);
2684
2685 /*
2686 Do nothing if the current connection already owns a LOCK BINLOG FOR BACKUP
2687 lock or the global read lock (as it's a more restrictive lock).
2688 */
2689 if (thd->backup_binlog_lock.is_acquired() ||
2690 thd->global_read_lock.is_acquired())
2691 DBUG_RETURN(false);
2692
2693 DBUG_RETURN(thd->backup_binlog_lock.acquire(thd));
2694 }
2695
2696 /**
2697 Execute command saved in thd and lex->sql_command.
2698
2699 @param thd Thread handle
2700
2701 @todo
2702 - Invalidate the table in the query cache if something changed
2703 after unlocking when changes become visible.
2704 @todo: this is workaround. right way will be move invalidating in
2705 the unlock procedure.
2706 - TODO: use check_change_password()
2707
2708 @retval
2709 FALSE OK
2710 @retval
2711 TRUE Error
2712 */
2713
2714 int
2715 mysql_execute_command(THD *thd)
2716 {
2717 int res= FALSE;
2718 int up_result= 0;
2719 LEX *lex= thd->lex;
2720 /* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */
2721 SELECT_LEX *select_lex= &lex->select_lex;
2722 /* first table of first SELECT_LEX */
2723 TABLE_LIST *first_table= select_lex->table_list.first;
2724 /* list of all tables in query */
2725 TABLE_LIST *all_tables;
2726 /* most outer SELECT_LEX_UNIT of query */
2727 SELECT_LEX_UNIT *unit= &lex->unit;
2728 #ifdef HAVE_REPLICATION
2729 /* have table map for update for multi-update statement (BUG#37051) */
2730 bool have_table_map_for_update= FALSE;
2731 #endif
2732 struct system_variables *per_query_variables_backup= NULL;
2733 bool reset_timer= false;
2734
2735 DBUG_ENTER("mysql_execute_command");
2736 DBUG_ASSERT(!lex->describe || is_explainable_query(lex->sql_command));
2737
2738 if (unlikely(lex->is_broken()))
2739 {
2740 // Force a Reprepare, to get a fresh LEX
2741 Reprepare_observer *reprepare_observer= thd->get_reprepare_observer();
2742 if (reprepare_observer &&
2743 reprepare_observer->report_error(thd))
2744 {
2745 DBUG_ASSERT(thd->is_error());
2746 DBUG_RETURN(1);
2747 }
2748 }
2749
2750 #ifdef WITH_PARTITION_STORAGE_ENGINE
2751 thd->work_part_info= 0;
2752 #endif
2753
2754 DBUG_ASSERT(thd->transaction.stmt.is_empty() || thd->in_sub_stmt);
2755 /*
2756 Each statement or replication event which might produce deadlock
2757 should handle transaction rollback on its own. So by the start of
2758 the next statement transaction rollback request should be fulfilled
2759 already.
2760 */
2761 DBUG_ASSERT(! thd->transaction_rollback_request || thd->in_sub_stmt);
2762 /*
2763 In many cases first table of main SELECT_LEX have special meaning =>
2764 check that it is first table in global list and relink it first in
2765 queries_tables list if it is necessary (we need such relinking only
2766 for queries with subqueries in select list, in this case tables of
2767 subqueries will go to global list first)
2768
2769 all_tables will differ from first_table only if most upper SELECT_LEX
2770 do not contain tables.
2771
2772 Because of above in place where should be at least one table in most
2773 outer SELECT_LEX we have following check:
2774 DBUG_ASSERT(first_table == all_tables);
2775 DBUG_ASSERT(first_table == all_tables && first_table != 0);
2776 */
2777 lex->first_lists_tables_same();
2778 /* should be assigned after making first tables same */
2779 all_tables= lex->query_tables;
2780 /* set context for commands which do not use setup_tables */
2781 select_lex->
2782 context.resolve_in_table_list_only(select_lex->
2783 table_list.first);
2784
2785 /*
2786 Reset warning count for each query that uses tables
2787 A better approach would be to reset this for any commands
2788 that is not a SHOW command or a select that only access local
2789 variables, but for now this is probably good enough.
2790 */
2791 if ((sql_command_flags[lex->sql_command] & CF_DIAGNOSTIC_STMT) != 0)
2792 thd->get_stmt_da()->set_warning_info_read_only(TRUE);
2793 else
2794 {
2795 thd->get_stmt_da()->set_warning_info_read_only(FALSE);
2796 if (all_tables)
2797 thd->get_stmt_da()->opt_clear_warning_info(thd->query_id);
2798 }
2799
2800 #ifdef HAVE_REPLICATION
2801 if (unlikely(thd->slave_thread))
2802 {
2803 if (!check_database_filters(thd, thd->db, lex->sql_command))
2804 DBUG_RETURN(0);
2805
2806 if (lex->sql_command == SQLCOM_DROP_TRIGGER)
2807 {
2808 /*
2809 When dropping a trigger, we need to load its table name
2810 before checking slave filter rules.
2811 */
2812 add_table_for_trigger(thd, thd->lex->spname, 1, &all_tables);
2813
2814 if (!all_tables)
2815 {
2816 /*
2817 If table name cannot be loaded,
2818 it means the trigger does not exists possibly because
2819 CREATE TRIGGER was previously skipped for this trigger
2820 according to slave filtering rules.
2821 Returning success without producing any errors in this case.
2822 */
2823 DBUG_RETURN(0);
2824 }
2825
2826 // force searching in slave.cc:tables_ok()
2827 all_tables->updating= 1;
2828 }
2829
2830 /*
2831 For fix of BUG#37051, the master stores the table map for update
2832 in the Query_log_event, and the value is assigned to
2833 thd->variables.table_map_for_update before executing the update
2834 query.
2835
2836 If thd->variables.table_map_for_update is set, then we are
2837 replicating from a new master, we can use this value to apply
2838 filter rules without opening all the tables. However If
2839 thd->variables.table_map_for_update is not set, then we are
2840 replicating from an old master, so we just skip this and
2841 continue with the old method. And of course, the bug would still
2842 exist for old masters.
2843 */
2844 if (lex->sql_command == SQLCOM_UPDATE_MULTI &&
2845 thd->table_map_for_update)
2846 {
2847 have_table_map_for_update= TRUE;
2848 table_map table_map_for_update= thd->table_map_for_update;
2849 uint nr= 0;
2850 TABLE_LIST *table;
2851 for (table=all_tables; table; table=table->next_global, nr++)
2852 {
2853 if (table_map_for_update & ((table_map)1 << nr))
2854 table->updating= TRUE;
2855 else
2856 table->updating= FALSE;
2857 }
2858
2859 if (all_tables_not_ok(thd, all_tables))
2860 {
2861 /* we warn the slave SQL thread */
2862 my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
2863 if (thd->one_shot_set)
2864 reset_one_shot_variables(thd);
2865 DBUG_RETURN(0);
2866 }
2867
2868 for (table=all_tables; table; table=table->next_global)
2869 table->updating= TRUE;
2870 }
2871
2872 /*
2873 Check if statment should be skipped because of slave filtering
2874 rules
2875
2876 Exceptions are:
2877 - UPDATE MULTI: For this statement, we want to check the filtering
2878 rules later in the code
2879 - SET: we always execute it (Not that many SET commands exists in
2880 the binary log anyway -- only 4.1 masters write SET statements,
2881 in 5.0 there are no SET statements in the binary log)
2882 - DROP TEMPORARY TABLE IF EXISTS: we always execute it (otherwise we
2883 have stale files on slave caused by exclusion of one tmp table).
2884 */
2885 if (!(lex->sql_command == SQLCOM_UPDATE_MULTI) &&
2886 !(lex->sql_command == SQLCOM_SET_OPTION) &&
2887 !(lex->sql_command == SQLCOM_DROP_TABLE &&
2888 lex->drop_temporary && lex->drop_if_exists) &&
2889 all_tables_not_ok(thd, all_tables))
2890 {
2891 /* we warn the slave SQL thread */
2892 my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
2893 if (thd->one_shot_set)
2894 {
2895 /*
2896 It's ok to check thd->one_shot_set here:
2897
2898 The charsets in a MySQL 5.0 slave can change by both a binlogged
2899 SET ONE_SHOT statement and the event-internal charset setting,
2900 and these two ways to change charsets do not seems to work
2901 together.
2902
2903 At least there seems to be problems in the rli cache for
2904 charsets if we are using ONE_SHOT. Note that this is normally no
2905 problem because either the >= 5.0 slave reads a 4.1 binlog (with
2906 ONE_SHOT) *or* or 5.0 binlog (without ONE_SHOT) but never both."
2907 */
2908 reset_one_shot_variables(thd);
2909 }
2910 DBUG_RETURN(0);
2911 }
2912 /*
2913 Execute deferred events first
2914 Bug lp1068210 or upstream 67504: Test first to see if we are executing
2915 within a sub statement. If so, DO NOT execute any deferred events, they
2916 have already been executed by the parent statement and have no bearing
2917 on the sub statement and can cause faulty behavior.
2918 */
2919 if (thd->in_sub_stmt == 0)
2920 if (slave_execute_deferred_events(thd))
2921 DBUG_RETURN(-1);
2922 }
2923 else
2924 {
2925 #endif /* HAVE_REPLICATION */
2926 /*
2927 When option readonly is set deny operations which change non-temporary
2928 tables. Except for the replication thread and the 'super' users.
2929 */
2930 if (deny_updates_if_read_only_option(thd, all_tables))
2931 {
2932 thd->diff_access_denied_errors++;
2933 my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
2934 opt_super_readonly ? "--read-only (super)" : "--read-only");
2935 DBUG_RETURN(-1);
2936 }
2937 #ifdef HAVE_REPLICATION
2938 } /* endif unlikely slave */
2939 #endif
2940
2941 status_var_increment(thd->status_var.com_stat[lex->sql_command]);
2942
2943 Opt_trace_start ots(thd, all_tables, lex->sql_command, &lex->var_list,
2944 thd->query(), thd->query_length(), NULL,
2945 thd->variables.character_set_client);
2946
2947 Opt_trace_object trace_command(&thd->opt_trace);
2948 Opt_trace_array trace_command_steps(&thd->opt_trace, "steps");
2949
2950 DBUG_ASSERT(thd->transaction.stmt.cannot_safely_rollback() == FALSE);
2951
2952 switch (gtid_pre_statement_checks(thd))
2953 {
2954 case GTID_STATEMENT_EXECUTE:
2955 break;
2956 case GTID_STATEMENT_CANCEL:
2957 DBUG_RETURN(-1);
2958 case GTID_STATEMENT_SKIP:
2959 my_ok(thd);
2960 DBUG_RETURN(0);
2961 }
2962
2963 /*
2964 End a active transaction so that this command will have it's
2965 own transaction and will also sync the binary log. If a DDL is
2966 not run in it's own transaction it may simply never appear on
2967 the slave in case the outside transaction rolls back.
2968 */
2969 if (stmt_causes_implicit_commit(thd, CF_IMPLICIT_COMMIT_BEGIN))
2970 {
2971 /*
2972 Note that this should never happen inside of stored functions
2973 or triggers as all such statements prohibited there.
2974 */
2975 DBUG_ASSERT(! thd->in_sub_stmt);
2976 /* Statement transaction still should not be started. */
2977 DBUG_ASSERT(thd->transaction.stmt.is_empty());
2978
2979 /*
2980 Implicit commit is not allowed with an active XA transaction.
2981 In this case we should not release metadata locks as the XA transaction
2982 will not be rolled back. Therefore we simply return here.
2983 */
2984 if (trans_check_state(thd))
2985 DBUG_RETURN(-1);
2986
2987 /* Commit the normal transaction if one is active. */
2988 if (trans_commit_implicit(thd))
2989 goto error;
2990 /* Release metadata locks acquired in this transaction. */
2991 thd->mdl_context.release_transactional_locks();
2992 }
2993
2994 #ifndef DBUG_OFF
2995 if (lex->sql_command != SQLCOM_SET_OPTION)
2996 DEBUG_SYNC(thd,"before_execute_sql_command");
2997 #endif
2998
2999 /*
3000 Check if we are in a read-only transaction and we're trying to
3001 execute a statement which should always be disallowed in such cases.
3002
3003 Note that this check is done after any implicit commits.
3004 */
3005 if (thd->tx_read_only &&
3006 (sql_command_flags[lex->sql_command] & CF_DISALLOW_IN_RO_TRANS))
3007 {
3008 thd->diff_access_denied_errors++;
3009 my_error(ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION, MYF(0));
3010 goto error;
3011 }
3012
3013 /*
3014 Close tables open by HANDLERs before executing DDL statement
3015 which is going to affect those tables.
3016
3017 This should happen before temporary tables are pre-opened as
3018 otherwise we will get errors about attempt to re-open tables
3019 if table to be changed is open through HANDLER.
3020
3021 Note that even although this is done before any privilege
3022 checks there is no security problem here as closing open
3023 HANDLER doesn't require any privileges anyway.
3024 */
3025 if (sql_command_flags[lex->sql_command] & CF_HA_CLOSE)
3026 mysql_ha_rm_tables(thd, all_tables);
3027
3028 /*
3029 Pre-open temporary tables to simplify privilege checking
3030 for statements which need this.
3031 */
3032 if (sql_command_flags[lex->sql_command] & CF_PREOPEN_TMP_TABLES)
3033 {
3034 if (open_temporary_tables(thd, all_tables))
3035 goto error;
3036 }
3037
3038 if (lex->set_statement && !lex->var_list.is_empty()) {
3039 per_query_variables_backup= copy_system_variables(thd,
3040 thd->m_enable_plugins);
3041 if ((res= sql_set_variables(thd, &lex->var_list, false)))
3042 {
3043 /*
3044 We encountered some sort of error, but no message was sent.
3045 Send something semi-generic here since we don't know which
3046 assignment in the list caused the error.
3047 */
3048 if (!thd->is_error())
3049 my_error(ER_WRONG_ARGUMENTS, MYF(0), "SET");
3050 goto error;
3051 }
3052 }
3053
3054 reset_timer= set_statement_timer(thd);
3055
3056 switch (lex->sql_command) {
3057
3058 case SQLCOM_SHOW_STATUS:
3059 {
3060 system_status_var old_status_var= thd->status_var;
3061 thd->initial_status_var= &old_status_var;
3062
3063 if (!(res= select_precheck(thd, lex, all_tables, first_table)))
3064 res= execute_sqlcom_select(thd, all_tables);
3065
3066 /* Don't log SHOW STATUS commands to slow query log */
3067 thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED |
3068 SERVER_QUERY_NO_GOOD_INDEX_USED);
3069 /*
3070 restore status variables, as we don't want 'show status' to cause
3071 changes
3072 */
3073 mysql_mutex_lock(&LOCK_status);
3074 add_diff_to_status(&global_status_var, &thd->status_var,
3075 &old_status_var);
3076 thd->status_var= old_status_var;
3077 mysql_mutex_unlock(&LOCK_status);
3078 break;
3079 }
3080 case SQLCOM_SHOW_EVENTS:
3081 #ifndef HAVE_EVENT_SCHEDULER
3082 my_error(ER_NOT_SUPPORTED_YET, MYF(0), "embedded server");
3083 break;
3084 #endif
3085 case SQLCOM_SHOW_STATUS_PROC:
3086 case SQLCOM_SHOW_STATUS_FUNC:
3087 case SQLCOM_SHOW_DATABASES:
3088 case SQLCOM_SHOW_TABLES:
3089 case SQLCOM_SHOW_TRIGGERS:
3090 case SQLCOM_SHOW_TABLE_STATUS:
3091 case SQLCOM_SHOW_OPEN_TABLES:
3092 case SQLCOM_SHOW_PLUGINS:
3093 case SQLCOM_SHOW_FIELDS:
3094 case SQLCOM_SHOW_KEYS:
3095 case SQLCOM_SHOW_VARIABLES:
3096 case SQLCOM_SHOW_CHARSETS:
3097 case SQLCOM_SHOW_COLLATIONS:
3098 case SQLCOM_SHOW_STORAGE_ENGINES:
3099 case SQLCOM_SHOW_PROFILE:
3100 case SQLCOM_SHOW_USER_STATS:
3101 case SQLCOM_SHOW_TABLE_STATS:
3102 case SQLCOM_SHOW_INDEX_STATS:
3103 case SQLCOM_SHOW_CLIENT_STATS:
3104 case SQLCOM_SHOW_THREAD_STATS:
3105 case SQLCOM_SELECT:
3106 {
3107 thd->status_var.last_query_cost= 0.0;
3108 thd->status_var.last_query_partial_plans= 0;
3109
3110 if ((res= select_precheck(thd, lex, all_tables, first_table)))
3111 break;
3112
3113 res= execute_sqlcom_select(thd, all_tables);
3114 break;
3115 }
3116 case SQLCOM_PREPARE:
3117 {
3118 mysql_sql_stmt_prepare(thd);
3119 break;
3120 }
3121 case SQLCOM_EXECUTE:
3122 {
3123 /*
3124 Deallocate free_list here to avoid assertion failure later in
3125 Prepared_statement::execute_loop
3126 */
3127 free_items(thd->free_list);
3128 thd->free_list= NULL;
3129 mysql_sql_stmt_execute(thd);
3130 break;
3131 }
3132 case SQLCOM_DEALLOCATE_PREPARE:
3133 {
3134 mysql_sql_stmt_close(thd);
3135 break;
3136 }
3137 case SQLCOM_DO:
3138 if (check_table_access(thd, SELECT_ACL, all_tables, FALSE, UINT_MAX, FALSE)
3139 || open_and_lock_tables(thd, all_tables, TRUE, 0))
3140 goto error;
3141
3142 res= mysql_do(thd, *lex->insert_list);
3143 break;
3144
3145 case SQLCOM_EMPTY_QUERY:
3146 my_ok(thd);
3147 break;
3148
3149 case SQLCOM_HELP:
3150 res= mysqld_help(thd,lex->help_arg);
3151 break;
3152
3153 #ifndef EMBEDDED_LIBRARY
3154 case SQLCOM_PURGE:
3155 {
3156 if (check_global_access(thd, SUPER_ACL))
3157 goto error;
3158 if (lex->type == 0)
3159 {
3160 /* PURGE MASTER LOGS TO 'file' */
3161 res = purge_master_logs(thd, lex->to_log);
3162 break;
3163 }
3164 if (lex->type == PURGE_BITMAPS_TO_LSN)
3165 {
3166 /* PURGE CHANGED_PAGE_BITMAPS BEFORE lsn */
3167 ulonglong lsn= 0;
3168 Item *it= (Item *)lex->value_list.head();
3169 if ((!it->fixed && it->fix_fields(lex->thd, &it)) || it->check_cols(1)
3170 || it->null_value)
3171 {
3172 my_error(ER_WRONG_ARGUMENTS, MYF(0),
3173 "PURGE CHANGED_PAGE_BITMAPS BEFORE");
3174 goto error;
3175 }
3176 lsn= it->val_uint();
3177 res= ha_purge_changed_page_bitmaps(lsn);
3178 if (res)
3179 {
3180 my_error(ER_LOG_PURGE_UNKNOWN_ERR, MYF(0),
3181 "PURGE CHANGED_PAGE_BITMAPS BEFORE");
3182 goto error;
3183 }
3184 my_ok(thd);
3185 break;
3186 }
3187 }
3188 // fallthrough
3189 case SQLCOM_PURGE_BEFORE:
3190 {
3191 Item *it;
3192
3193 if (check_global_access(thd, SUPER_ACL))
3194 goto error;
3195 /* PURGE MASTER LOGS BEFORE 'data' */
3196 it= (Item *)lex->value_list.head();
3197 if ((!it->fixed && it->fix_fields(lex->thd, &it)) ||
3198 it->check_cols(1))
3199 {
3200 my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE LOGS BEFORE");
3201 goto error;
3202 }
3203 it= new Item_func_unix_timestamp(it);
3204 /*
3205 it is OK only emulate fix_fieds, because we need only
3206 value of constant
3207 */
3208 it->quick_fix_field();
3209 res = purge_master_logs_before_date(thd, (ulong)it->val_int());
3210 break;
3211 }
3212 case SQLCOM_PURGE_ARCHIVE:
3213 {
3214 if (check_global_access(thd, SUPER_ACL))
3215 goto error;
3216 /* PURGE ARCHIVED LOGS TO 'file' */
3217 if (!ha_purge_archive_logs_to(NULL, NULL, lex->to_log)) {
3218 my_ok(thd);
3219 } else {
3220 my_error(ER_LOG_PURGE_UNKNOWN_ERR, MYF(0), "PURGE ARCHIVE LOGS TO");
3221 goto error;
3222 }
3223
3224 break;
3225 }
3226 case SQLCOM_PURGE_ARCHIVE_BEFORE:
3227 {
3228 Item *it;
3229
3230 if (check_global_access(thd, SUPER_ACL))
3231 goto error;
3232 /* PURGE ARCHIVE LOGS BEFORE 'data' */
3233 it= (Item *)lex->value_list.head();
3234 if ((!it->fixed && it->fix_fields(lex->thd, &it)) ||
3235 it->check_cols(1))
3236 {
3237 my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE ARCHIVE LOGS BEFORE");
3238 goto error;
3239 }
3240 it= new Item_func_unix_timestamp(it);
3241 /*
3242 it is OK only emulate fix_fieds, because we need only
3243 value of constant
3244 */
3245 it->quick_fix_field();
3246 ulong before_timestamp = (ulong)it->val_int();
3247 if (!ha_purge_archive_logs(NULL, NULL, &before_timestamp )) {
3248 my_ok(thd);
3249 } else {
3250 my_error(ER_LOG_PURGE_UNKNOWN_ERR, MYF(0), "PURGE ARCHIVE LOGS BEFORE");
3251 goto error;
3252 }
3253 break;
3254 }
3255 #endif
3256 case SQLCOM_SHOW_WARNS:
3257 {
3258 res= mysqld_show_warnings(thd, (ulong)
3259 ((1L << (uint) Sql_condition::WARN_LEVEL_NOTE) |
3260 (1L << (uint) Sql_condition::WARN_LEVEL_WARN) |
3261 (1L << (uint) Sql_condition::WARN_LEVEL_ERROR)
3262 ));
3263 break;
3264 }
3265 case SQLCOM_SHOW_ERRORS:
3266 {
3267 res= mysqld_show_warnings(thd, (ulong)
3268 (1L << (uint) Sql_condition::WARN_LEVEL_ERROR));
3269 break;
3270 }
3271 case SQLCOM_SHOW_PROFILES:
3272 {
3273 #if defined(ENABLED_PROFILING)
3274 thd->profiling.discard_current_query();
3275 res= thd->profiling.show_profiles();
3276 if (res)
3277 goto error;
3278 #else
3279 my_error(ER_FEATURE_DISABLED, MYF(0), "SHOW PROFILES", "enable-profiling");
3280 goto error;
3281 #endif
3282 break;
3283 }
3284
3285 #ifdef HAVE_REPLICATION
3286 case SQLCOM_SHOW_SLAVE_HOSTS:
3287 {
3288 if (check_global_access(thd, REPL_SLAVE_ACL))
3289 goto error;
3290 res= show_slave_hosts(thd);
3291 break;
3292 }
3293 case SQLCOM_SHOW_RELAYLOG_EVENTS:
3294 {
3295 if (check_global_access(thd, REPL_SLAVE_ACL))
3296 goto error;
3297 res = mysql_show_relaylog_events(thd);
3298 break;
3299 }
3300 case SQLCOM_SHOW_BINLOG_EVENTS:
3301 {
3302 if (check_global_access(thd, REPL_SLAVE_ACL))
3303 goto error;
3304 res = mysql_show_binlog_events(thd);
3305 break;
3306 }
3307 #endif
3308
3309 case SQLCOM_ASSIGN_TO_KEYCACHE:
3310 {
3311 DBUG_ASSERT(first_table == all_tables && first_table != 0);
3312 if (check_access(thd, INDEX_ACL, first_table->db,
3313 &first_table->grant.privilege,
3314 &first_table->grant.m_internal,
3315 0, 0))
3316 goto error;
3317 res= mysql_assign_to_keycache(thd, first_table, &lex->ident);
3318 break;
3319 }
3320 case SQLCOM_PRELOAD_KEYS:
3321 {
3322 DBUG_ASSERT(first_table == all_tables && first_table != 0);
3323 if (check_access(thd, INDEX_ACL, first_table->db,
3324 &first_table->grant.privilege,
3325 &first_table->grant.m_internal,
3326 0, 0))
3327 goto error;
3328 res = mysql_preload_keys(thd, first_table);
3329 break;
3330 }
3331 #ifdef HAVE_REPLICATION
3332 case SQLCOM_CHANGE_MASTER:
3333 {
3334 if (check_global_access(thd, SUPER_ACL))
3335 goto error;
3336 mysql_mutex_lock(&LOCK_active_mi);
3337 if (active_mi != NULL)
3338 res= change_master(thd, active_mi);
3339 else
3340 my_message(ER_SLAVE_CONFIGURATION, ER(ER_SLAVE_CONFIGURATION),
3341 MYF(0));
3342 mysql_mutex_unlock(&LOCK_active_mi);
3343 break;
3344 }
3345 case SQLCOM_SHOW_SLAVE_NOLOCK_STAT:
3346 case SQLCOM_SHOW_SLAVE_STAT:
3347 {
3348 /* Accept one of two privileges */
3349 if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL))
3350 goto error;
3351 bool do_lock=SQLCOM_SHOW_SLAVE_NOLOCK_STAT != lex->sql_command;
3352 if(do_lock)
3353 {
3354 mysql_mutex_lock(&LOCK_active_mi);
3355 }
3356 res = show_slave_status(thd, active_mi);
3357 if(do_lock)
3358 {
3359 mysql_mutex_unlock(&LOCK_active_mi);
3360 }
3361 DBUG_EXECUTE_IF("after_show_slave_status",
3362 {
3363 const char act[]=
3364 "now "
3365 "signal signal.after_show_slave_status";
3366 DBUG_ASSERT(opt_debug_sync_timeout > 0);
3367 DBUG_ASSERT(!debug_sync_set_action(current_thd,
3368 STRING_WITH_LEN(act)));
3369 };);
3370 break;
3371 }
3372 case SQLCOM_SHOW_MASTER_STAT:
3373 {
3374 /* Accept one of two privileges */
3375 if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL))
3376 goto error;
3377 res = show_master_status(thd);
3378 break;
3379 }
3380
3381 #endif /* HAVE_REPLICATION */
3382 case SQLCOM_SHOW_ENGINE_STATUS:
3383 {
3384 if (check_global_access(thd, PROCESS_ACL))
3385 goto error;
3386 res = ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_STATUS);
3387 break;
3388 }
3389 case SQLCOM_SHOW_ENGINE_MUTEX:
3390 {
3391 if (check_global_access(thd, PROCESS_ACL))
3392 goto error;
3393 res = ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_MUTEX);
3394 break;
3395 }
3396 case SQLCOM_CREATE_TABLE:
3397 {
3398 DBUG_ASSERT(first_table == all_tables && first_table != 0);
3399 bool link_to_local;
3400 TABLE_LIST *create_table= first_table;
3401 TABLE_LIST *select_tables= lex->create_last_non_select_table->next_global;
3402
3403 /*
3404 Code below (especially in mysql_create_table() and select_create
3405 methods) may modify HA_CREATE_INFO structure in LEX, so we have to
3406 use a copy of this structure to make execution prepared statement-
3407 safe. A shallow copy is enough as this code won't modify any memory
3408 referenced from this structure.
3409 */
3410 HA_CREATE_INFO create_info(lex->create_info);
3411 /*
3412 We need to copy alter_info for the same reasons of re-execution
3413 safety, only in case of Alter_info we have to do (almost) a deep
3414 copy.
3415 */
3416 Alter_info alter_info(lex->alter_info, thd->mem_root);
3417 if (thd->is_fatal_error)
3418 {
3419 /* If out of memory when creating a copy of alter_info. */
3420 res= 1;
3421 goto end_with_restore_list;
3422 }
3423
3424 if (((lex->create_info.used_fields & HA_CREATE_USED_DATADIR) != 0 ||
3425 (lex->create_info.used_fields & HA_CREATE_USED_INDEXDIR) != 0) &&
3426 check_access(thd, FILE_ACL, any_db, NULL, NULL, FALSE, FALSE))
3427 {
3428 res= 1;
3429 my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "FILE");
3430 goto end_with_restore_list;
3431 }
3432
3433 if ((res= create_table_precheck(thd, select_tables, create_table)))
3434 goto end_with_restore_list;
3435
3436 /* Might have been updated in create_table_precheck */
3437 create_info.alias= create_table->alias;
3438
3439 /* Fix names if symlinked or relocated tables */
3440 if (append_file_to_dir(thd, &create_info.data_file_name,
3441 create_table->table_name) ||
3442 append_file_to_dir(thd, &create_info.index_file_name,
3443 create_table->table_name))
3444 goto end_with_restore_list;
3445
3446 /*
3447 If no engine type was given, work out the default now
3448 rather than at parse-time.
3449 */
3450 if (!(create_info.used_fields & HA_CREATE_USED_ENGINE))
3451 create_info.db_type= create_info.options & HA_LEX_CREATE_TMP_TABLE ?
3452 ha_default_temp_handlerton(thd) : ha_default_handlerton(thd);
3453 /*
3454 If we are using SET CHARSET without DEFAULT, add an implicit
3455 DEFAULT to not confuse old users. (This may change).
3456 */
3457 if ((create_info.used_fields &
3458 (HA_CREATE_USED_DEFAULT_CHARSET | HA_CREATE_USED_CHARSET)) ==
3459 HA_CREATE_USED_CHARSET)
3460 {
3461 create_info.used_fields&= ~HA_CREATE_USED_CHARSET;
3462 create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
3463 create_info.default_table_charset= create_info.table_charset;
3464 create_info.table_charset= 0;
3465 }
3466
3467 #ifdef WITH_PARTITION_STORAGE_ENGINE
3468 {
3469 partition_info *part_info= thd->lex->part_info;
3470 if (part_info != NULL && has_external_data_or_index_dir(*part_info) &&
3471 check_access(thd, FILE_ACL, any_db, NULL, NULL, FALSE, FALSE))
3472 {
3473 res= -1;
3474 goto end_with_restore_list;
3475 }
3476 if (part_info && !(part_info= thd->lex->part_info->get_clone(true)))
3477 {
3478 res= -1;
3479 goto end_with_restore_list;
3480 }
3481 thd->work_part_info= part_info;
3482 }
3483 #endif
3484
3485 if (select_lex->item_list.elements) // With select
3486 {
3487 select_result *result;
3488
3489 /*
3490 CREATE TABLE...IGNORE/REPLACE SELECT... can be unsafe, unless
3491 ORDER BY PRIMARY KEY clause is used in SELECT statement. We therefore
3492 use row based logging if mixed or row based logging is available.
3493 TODO: Check if the order of the output of the select statement is
3494 deterministic. Waiting for BUG#42415
3495 */
3496 if(lex->ignore)
3497 lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_CREATE_IGNORE_SELECT);
3498
3499 if(lex->duplicates == DUP_REPLACE)
3500 lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_CREATE_REPLACE_SELECT);
3501
3502 /*
3503 If:
3504 a) we inside an SP and there was NAME_CONST substitution,
3505 b) binlogging is on (STMT mode),
3506 c) we log the SP as separate statements
3507 raise a warning, as it may cause problems
3508 (see 'NAME_CONST issues' in 'Binary Logging of Stored Programs')
3509 */
3510 if (thd->query_name_consts &&
3511 mysql_bin_log.is_open() &&
3512 thd->variables.binlog_format == BINLOG_FORMAT_STMT &&
3513 !mysql_bin_log.is_query_in_union(thd, thd->query_id))
3514 {
3515 List_iterator_fast<Item> it(select_lex->item_list);
3516 Item *item;
3517 uint splocal_refs= 0;
3518 /* Count SP local vars in the top-level SELECT list */
3519 while ((item= it++))
3520 {
3521 if (item->is_splocal())
3522 splocal_refs++;
3523 }
3524 /*
3525 If it differs from number of NAME_CONST substitution applied,
3526 we may have a SOME_FUNC(NAME_CONST()) in the SELECT list,
3527 that may cause a problem with binary log (see BUG#35383),
3528 raise a warning.
3529 */
3530 if (splocal_refs != thd->query_name_consts)
3531 push_warning(thd,
3532 Sql_condition::WARN_LEVEL_WARN,
3533 ER_UNKNOWN_ERROR,
3534 "Invoked routine ran a statement that may cause problems with "
3535 "binary log, see 'NAME_CONST issues' in 'Binary Logging of Stored Programs' "
3536 "section of the manual.");
3537 }
3538
3539 select_lex->options|= SELECT_NO_UNLOCK;
3540 unit->set_limit(select_lex);
3541
3542 /*
3543 Disable non-empty MERGE tables with CREATE...SELECT. Too
3544 complicated. See Bug #26379. Empty MERGE tables are read-only
3545 and don't allow CREATE...SELECT anyway.
3546 */
3547 if (create_info.used_fields & HA_CREATE_USED_UNION)
3548 {
3549 my_error(ER_WRONG_OBJECT, MYF(0), create_table->db,
3550 create_table->table_name, "BASE TABLE");
3551 res= 1;
3552 goto end_with_restore_list;
3553 }
3554
3555 res= open_normal_and_derived_tables(thd, all_tables, 0);
3556 if (res)
3557 {
3558 /* Got error or warning. Set res to 1 if error */
3559 if (!(res= thd->is_error()))
3560 my_ok(thd); // CREATE ... IF NOT EXISTS
3561 }
3562 else
3563 {
3564 /* The table already exists */
3565 if (create_table->table || create_table->view)
3566 {
3567 if (create_info.options & HA_LEX_CREATE_IF_NOT_EXISTS)
3568 {
3569 push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
3570 ER_TABLE_EXISTS_ERROR,
3571 ER(ER_TABLE_EXISTS_ERROR),
3572 create_info.alias);
3573 my_ok(thd);
3574 }
3575 else
3576 {
3577 my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_info.alias);
3578 res= 1;
3579 }
3580 goto end_with_restore_list;
3581 }
3582
3583 /*
3584 Remove target table from main select and name resolution
3585 context. This can't be done earlier as it will break view merging in
3586 statements like "CREATE TABLE IF NOT EXISTS existing_view SELECT".
3587 */
3588 lex->unlink_first_table(&link_to_local);
3589
3590 /* Updating any other table is prohibited in CTS statement */
3591 for (TABLE_LIST *table= lex->query_tables; table;
3592 table= table->next_global)
3593 if (table->lock_type >= TL_WRITE_ALLOW_WRITE)
3594 {
3595 lex->link_first_table_back(create_table, link_to_local);
3596
3597 res= 1;
3598 my_error(ER_CANT_UPDATE_TABLE_IN_CREATE_TABLE_SELECT, MYF(0),
3599 table->table_name, create_info.alias);
3600 goto end_with_restore_list;
3601 }
3602
3603 /*
3604 select_create is currently not re-execution friendly and
3605 needs to be created for every execution of a PS/SP.
3606 */
3607 if ((result= new select_create(create_table,
3608 &create_info,
3609 &alter_info,
3610 select_lex->item_list,
3611 lex->duplicates,
3612 lex->ignore,
3613 select_tables)))
3614 {
3615 /*
3616 CREATE from SELECT give its SELECT_LEX for SELECT,
3617 and item_list belong to SELECT
3618 */
3619 res= handle_select(thd, result, 0);
3620 delete result;
3621 }
3622
3623 lex->link_first_table_back(create_table, link_to_local);
3624 }
3625 }
3626 else
3627 {
3628 /* regular create */
3629 if (create_info.options & HA_LEX_CREATE_TABLE_LIKE)
3630 {
3631 /* CREATE TABLE ... LIKE ... */
3632 res= mysql_create_like_table(thd, create_table, select_tables,
3633 &create_info);
3634 }
3635 else
3636 {
3637 /* Regular CREATE TABLE */
3638 res= mysql_create_table(thd, create_table,
3639 &create_info, &alter_info);
3640 }
3641 if (!res)
3642 my_ok(thd);
3643 }
3644
3645 end_with_restore_list:
3646 break;
3647 }
3648 case SQLCOM_CREATE_INDEX:
3649 /* Fall through */
3650 case SQLCOM_DROP_INDEX:
3651 /*
3652 CREATE INDEX and DROP INDEX are implemented by calling ALTER
3653 TABLE with proper arguments.
3654
3655 In the future ALTER TABLE will notice that the request is to
3656 only add indexes and create these one by one for the existing
3657 table without having to do a full rebuild.
3658 */
3659 {
3660 /* Prepare stack copies to be re-execution safe */
3661 HA_CREATE_INFO create_info;
3662 Alter_info alter_info(lex->alter_info, thd->mem_root);
3663
3664 if (thd->is_fatal_error) /* out of memory creating a copy of alter_info */
3665 goto error;
3666
3667 DBUG_ASSERT(first_table == all_tables && first_table != 0);
3668 if (check_one_table_access(thd, INDEX_ACL, all_tables))
3669 goto error; /* purecov: inspected */
3670 /*
3671 Currently CREATE INDEX or DROP INDEX cause a full table rebuild
3672 and thus classify as slow administrative statements just like
3673 ALTER TABLE.
3674 */
3675 thd->set_slow_log_for_admin_command();
3676
3677 memset(static_cast<void*>(&create_info), 0, sizeof(create_info));
3678 create_info.db_type= 0;
3679 create_info.row_type= ROW_TYPE_NOT_USED;
3680 create_info.default_table_charset= thd->variables.collation_database;
3681
3682 res= mysql_alter_table(thd, first_table->db, first_table->table_name,
3683 &create_info, first_table, &alter_info,
3684 0, (ORDER*) 0, 0);
3685 break;
3686 }
3687 #ifdef HAVE_REPLICATION
3688 case SQLCOM_SLAVE_START:
3689 {
3690 mysql_mutex_lock(&LOCK_active_mi);
3691 if (active_mi != NULL) {
3692 DEBUG_SYNC(thd, "begin_start_slave");
3693 res= start_slave(thd, active_mi, 1 /* net report*/);
3694 }
3695 else
3696 my_message(ER_SLAVE_CONFIGURATION, ER(ER_SLAVE_CONFIGURATION),
3697 MYF(0));
3698 mysql_mutex_unlock(&LOCK_active_mi);
3699 break;
3700 }
3701 case SQLCOM_SLAVE_STOP:
3702 /*
3703 If the client thread has locked tables, a deadlock is possible.
3704 Assume that
3705 - the client thread does LOCK TABLE t READ.
3706 - then the master updates t.
3707 - then the SQL slave thread wants to update t,
3708 so it waits for the client thread because t is locked by it.
3709 - then the client thread does SLAVE STOP.
3710 SLAVE STOP waits for the SQL slave thread to terminate its
3711 update t, which waits for the client thread because t is locked by it.
3712 To prevent that, refuse SLAVE STOP if the
3713 client thread has locked tables
3714 */
3715 if (thd->locked_tables_mode ||
3716 thd->in_active_multi_stmt_transaction() ||
3717 thd->global_read_lock.is_acquired() ||
3718 thd->backup_tables_lock.is_acquired() ||
3719 thd->backup_binlog_lock.is_acquired())
3720 {
3721 my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
3722 ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
3723 goto error;
3724 }
3725 {
3726 mysql_mutex_lock(&LOCK_active_mi);
3727 if (active_mi != NULL)
3728 res= stop_slave(thd, active_mi, 1 /* net report*/);
3729 else
3730 my_message(ER_SLAVE_CONFIGURATION, ER(ER_SLAVE_CONFIGURATION),
3731 MYF(0));
3732 mysql_mutex_unlock(&LOCK_active_mi);
3733 break;
3734 }
3735 #endif /* HAVE_REPLICATION */
3736
3737 case SQLCOM_RENAME_TABLE:
3738 {
3739 DBUG_ASSERT(first_table == all_tables && first_table != 0);
3740 TABLE_LIST *table;
3741 for (table= first_table; table; table= table->next_local->next_local)
3742 {
3743 if (check_access(thd, ALTER_ACL | DROP_ACL, table->db,
3744 &table->grant.privilege,
3745 &table->grant.m_internal,
3746 0, 0) ||
3747 check_access(thd, INSERT_ACL | CREATE_ACL, table->next_local->db,
3748 &table->next_local->grant.privilege,
3749 &table->next_local->grant.m_internal,
3750 0, 0))
3751 goto error;
3752 TABLE_LIST old_list, new_list;
3753 /*
3754 we do not need initialize old_list and new_list because we will
3755 come table[0] and table->next[0] there
3756 */
3757 old_list= table[0];
3758 new_list= table->next_local[0];
3759 if (check_grant(thd, ALTER_ACL | DROP_ACL, &old_list, FALSE, 1, FALSE) ||
3760 (!test_all_bits(table->next_local->grant.privilege,
3761 INSERT_ACL | CREATE_ACL) &&
3762 check_grant(thd, INSERT_ACL | CREATE_ACL, &new_list, FALSE, 1,
3763 FALSE)))
3764 goto error;
3765 }
3766
3767 if (mysql_rename_tables(thd, first_table, 0))
3768 goto error;
3769 break;
3770 }
3771 #ifndef EMBEDDED_LIBRARY
3772 case SQLCOM_SHOW_BINLOGS:
3773 #ifdef DONT_ALLOW_SHOW_COMMANDS
3774 my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND),
3775 MYF(0)); /* purecov: inspected */
3776 goto error;
3777 #else
3778 {
3779 if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL))
3780 goto error;
3781 res = show_binlogs(thd);
3782 break;
3783 }
3784 #endif
3785 #endif /* EMBEDDED_LIBRARY */
3786 case SQLCOM_SHOW_CREATE:
3787 DBUG_ASSERT(first_table == all_tables && first_table != 0);
3788 #ifdef DONT_ALLOW_SHOW_COMMANDS
3789 my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND),
3790 MYF(0)); /* purecov: inspected */
3791 goto error;
3792 #else
3793 {
3794 /*
3795 Access check:
3796 SHOW CREATE TABLE require any privileges on the table level (ie
3797 effecting all columns in the table).
3798 SHOW CREATE VIEW require the SHOW_VIEW and SELECT ACLs on the table
3799 level.
3800 NOTE: SHOW_VIEW ACL is checked when the view is created.
3801 */
3802
3803 DBUG_PRINT("debug", ("lex->only_view: %d, table: %s.%s",
3804 lex->only_view,
3805 first_table->db, first_table->table_name));
3806 if (lex->only_view)
3807 {
3808 if (check_table_access(thd, SELECT_ACL, first_table, FALSE, 1, FALSE))
3809 {
3810 DBUG_PRINT("debug", ("check_table_access failed"));
3811 my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
3812 "SHOW", thd->security_ctx->priv_user,
3813 thd->security_ctx->host_or_ip, first_table->alias);
3814 goto error;
3815 }
3816 DBUG_PRINT("debug", ("check_table_access succeeded"));
3817
3818 /* Ignore temporary tables if this is "SHOW CREATE VIEW" */
3819 first_table->open_type= OT_BASE_ONLY;
3820
3821 }
3822 else
3823 {
3824 /*
3825 Temporary tables should be opened for SHOW CREATE TABLE, but not
3826 for SHOW CREATE VIEW.
3827 */
3828 if (open_temporary_tables(thd, all_tables))
3829 goto error;
3830
3831 /*
3832 The fact that check_some_access() returned FALSE does not mean that
3833 access is granted. We need to check if first_table->grant.privilege
3834 contains any table-specific privilege.
3835 */
3836 DBUG_PRINT("debug", ("first_table->grant.privilege: %lx",
3837 first_table->grant.privilege));
3838 if (check_some_access(thd, SHOW_CREATE_TABLE_ACLS, first_table) ||
3839 (first_table->grant.privilege & SHOW_CREATE_TABLE_ACLS) == 0)
3840 {
3841 my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
3842 "SHOW", thd->security_ctx->priv_user,
3843 thd->security_ctx->host_or_ip, first_table->alias);
3844 goto error;
3845 }
3846 }
3847
3848 /* Access is granted. Execute the command. */
3849 res= mysqld_show_create(thd, first_table);
3850 break;
3851 }
3852 #endif
3853 case SQLCOM_CHECKSUM:
3854 {
3855 DBUG_ASSERT(first_table == all_tables && first_table != 0);
3856 if (check_table_access(thd, SELECT_ACL, all_tables,
3857 FALSE, UINT_MAX, FALSE))
3858 goto error; /* purecov: inspected */
3859
3860 res = mysql_checksum_table(thd, first_table, &lex->check_opt);
3861 break;
3862 }
3863 case SQLCOM_UPDATE:
3864 {
3865 ha_rows found= 0, updated= 0;
3866 DBUG_ASSERT(first_table == all_tables && first_table != 0);
3867 if (update_precheck(thd, all_tables))
3868 break;
3869
3870 /*
3871 UPDATE IGNORE can be unsafe. We therefore use row based
3872 logging if mixed or row based logging is available.
3873 TODO: Check if the order of the output of the select statement is
3874 deterministic. Waiting for BUG#42415
3875 */
3876 if (lex->ignore)
3877 lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_UPDATE_IGNORE);
3878
3879 DBUG_ASSERT(select_lex->offset_limit == 0);
3880 unit->set_limit(select_lex);
3881 MYSQL_UPDATE_START(thd->query());
3882 res= (up_result= mysql_update(thd, all_tables,
3883 select_lex->item_list,
3884 lex->value_list,
3885 select_lex->where,
3886 select_lex->order_list.elements,
3887 select_lex->order_list.first,
3888 unit->select_limit_cnt,
3889 lex->duplicates, lex->ignore,
3890 &found, &updated));
3891 MYSQL_UPDATE_DONE(res, found, updated);
3892 /* mysql_update return 2 if we need to switch to multi-update */
3893 if (up_result != 2)
3894 break;
3895 }
3896 // fallthrough
3897 case SQLCOM_UPDATE_MULTI:
3898 {
3899 DBUG_ASSERT(first_table == all_tables && first_table != 0);
3900 /* if we switched from normal update, rights are checked */
3901 if (up_result != 2)
3902 {
3903 if ((res= multi_update_precheck(thd, all_tables)))
3904 break;
3905 }
3906 else
3907 res= 0;
3908
3909 res= mysql_multi_update_prepare(thd);
3910
3911 #ifdef HAVE_REPLICATION
3912 /* Check slave filtering rules */
3913 if (unlikely(thd->slave_thread))
3914 {
3915 if (!have_table_map_for_update && all_tables_not_ok(thd, all_tables))
3916 {
3917 if (res!= 0)
3918 {
3919 res= 0; /* don't care of prev failure */
3920 thd->clear_error(); /* filters are of highest prior */
3921 }
3922 /* we warn the slave SQL thread */
3923 my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
3924 break;
3925 }
3926 if (res)
3927 break;
3928 }
3929 else
3930 {
3931 #endif /* HAVE_REPLICATION */
3932 if (res)
3933 break;
3934 bool enforce_ro = true;
3935 if (!opt_super_readonly)
3936 enforce_ro = !(thd->security_ctx->master_access & SUPER_ACL);
3937 if (opt_readonly &&
3938 enforce_ro &&
3939 some_non_temp_table_to_be_updated(thd, all_tables))
3940 {
3941 my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
3942 opt_super_readonly ? "--read-only (super)" : "--read-only");
3943 break;
3944 }
3945 #ifdef HAVE_REPLICATION
3946 } /* unlikely */
3947 #endif
3948 {
3949 multi_update *result_obj;
3950 MYSQL_MULTI_UPDATE_START(thd->query());
3951 res= mysql_multi_update(thd, all_tables,
3952 &select_lex->item_list,
3953 &lex->value_list,
3954 select_lex->where,
3955 select_lex->options,
3956 lex->duplicates,
3957 lex->ignore,
3958 unit,
3959 select_lex,
3960 &result_obj);
3961 if (result_obj)
3962 {
3963 MYSQL_MULTI_UPDATE_DONE(res, result_obj->num_found(),
3964 result_obj->num_updated());
3965 res= FALSE; /* Ignore errors here */
3966 delete result_obj;
3967 }
3968 else
3969 {
3970 MYSQL_MULTI_UPDATE_DONE(1, 0, 0);
3971 }
3972 }
3973 break;
3974 }
3975 case SQLCOM_REPLACE:
3976 #ifndef DBUG_OFF
3977 if (mysql_bin_log.is_open())
3978 {
3979 /*
3980 Generate an incident log event before writing the real event
3981 to the binary log. We put this event is before the statement
3982 since that makes it simpler to check that the statement was
3983 not executed on the slave (since incidents usually stop the
3984 slave).
3985
3986 Observe that any row events that are generated will be
3987 generated before.
3988
3989 This is only for testing purposes and will not be present in a
3990 release build.
3991 */
3992
3993 Incident incident= INCIDENT_NONE;
3994 DBUG_PRINT("debug", ("Just before generate_incident()"));
3995 DBUG_EXECUTE_IF("incident_database_resync_on_replace",
3996 incident= INCIDENT_LOST_EVENTS;);
3997 if (incident)
3998 {
3999 Incident_log_event ev(thd, incident);
4000 if (mysql_bin_log.write_incident(&ev, true/*need_lock_log=true*/))
4001 {
4002 res= 1;
4003 break;
4004 }
4005 }
4006 DBUG_PRINT("debug", ("Just after generate_incident()"));
4007 }
4008 #endif
4009 // fallthrough
4010 case SQLCOM_INSERT:
4011 {
4012 DBUG_ASSERT(first_table == all_tables && first_table != 0);
4013
4014 /*
4015 Since INSERT DELAYED doesn't support temporary tables, we could
4016 not pre-open temporary tables for SQLCOM_INSERT / SQLCOM_REPLACE.
4017 Open them here instead.
4018 */
4019 if (first_table->lock_type != TL_WRITE_DELAYED)
4020 {
4021 if ((res= open_temporary_tables(thd, all_tables)))
4022 break;
4023 }
4024
4025 if ((res= insert_precheck(thd, all_tables)))
4026 break;
4027
4028 MYSQL_INSERT_START(thd->query());
4029 res= mysql_insert(thd, all_tables, lex->field_list, lex->many_values,
4030 lex->update_list, lex->value_list,
4031 lex->duplicates, lex->ignore);
4032 MYSQL_INSERT_DONE(res, (ulong) thd->get_row_count_func());
4033 /*
4034 If we have inserted into a VIEW, and the base table has
4035 AUTO_INCREMENT column, but this column is not accessible through
4036 a view, then we should restore LAST_INSERT_ID to the value it
4037 had before the statement.
4038 */
4039 if (first_table->view && !first_table->contain_auto_increment)
4040 thd->first_successful_insert_id_in_cur_stmt=
4041 thd->first_successful_insert_id_in_prev_stmt;
4042
4043 DBUG_EXECUTE_IF("after_mysql_insert",
4044 {
4045 const char act[]=
4046 "now "
4047 "wait_for signal.continue";
4048 DBUG_ASSERT(opt_debug_sync_timeout > 0);
4049 DBUG_ASSERT(!debug_sync_set_action(current_thd,
4050 STRING_WITH_LEN(act)));
4051 };);
4052 DEBUG_SYNC(thd, "after_mysql_insert");
4053 break;
4054 }
4055 case SQLCOM_REPLACE_SELECT:
4056 case SQLCOM_INSERT_SELECT:
4057 {
4058 select_insert *sel_result;
4059 DBUG_ASSERT(first_table == all_tables && first_table != 0);
4060 if ((res= insert_precheck(thd, all_tables)))
4061 break;
4062 /*
4063 INSERT...SELECT...ON DUPLICATE KEY UPDATE/REPLACE SELECT/
4064 INSERT...IGNORE...SELECT can be unsafe, unless ORDER BY PRIMARY KEY
4065 clause is used in SELECT statement. We therefore use row based
4066 logging if mixed or row based logging is available.
4067 TODO: Check if the order of the output of the select statement is
4068 deterministic. Waiting for BUG#42415
4069 */
4070 if (lex->sql_command == SQLCOM_INSERT_SELECT &&
4071 lex->duplicates == DUP_UPDATE)
4072 lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_INSERT_SELECT_UPDATE);
4073
4074 if (lex->sql_command == SQLCOM_INSERT_SELECT && lex->ignore)
4075 lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_INSERT_IGNORE_SELECT);
4076
4077 if (lex->sql_command == SQLCOM_REPLACE_SELECT)
4078 lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_REPLACE_SELECT);
4079
4080 /* Fix lock for first table */
4081 if (first_table->lock_type == TL_WRITE_DELAYED)
4082 first_table->lock_type= TL_WRITE;
4083
4084 /* Don't unlock tables until command is written to binary log */
4085 select_lex->options|= SELECT_NO_UNLOCK;
4086
4087 unit->set_limit(select_lex);
4088
4089 if (!(res= open_normal_and_derived_tables(thd, all_tables, 0)))
4090 {
4091 MYSQL_INSERT_SELECT_START(thd->query());
4092 /* Skip first table, which is the table we are inserting in */
4093 TABLE_LIST *second_table= first_table->next_local;
4094 select_lex->table_list.first= second_table;
4095 select_lex->context.table_list=
4096 select_lex->context.first_name_resolution_table= second_table;
4097 res= mysql_insert_select_prepare(thd);
4098 if (!res && (sel_result= new select_insert(first_table,
4099 first_table->table,
4100 &lex->field_list,
4101 &lex->field_list,
4102 &lex->update_list,
4103 &lex->value_list,
4104 lex->duplicates,
4105 lex->ignore)))
4106 {
4107 if (lex->describe)
4108 res= explain_multi_table_modification(thd, sel_result);
4109 else
4110 {
4111 res= handle_select(thd, sel_result, OPTION_SETUP_TABLES_DONE);
4112 /*
4113 Invalidate the table in the query cache if something changed
4114 after unlocking when changes become visible.
4115 TODO: this is workaround. right way will be move invalidating in
4116 the unlock procedure.
4117 */
4118 if (!res && first_table->lock_type == TL_WRITE_CONCURRENT_INSERT &&
4119 thd->lock)
4120 {
4121 /* INSERT ... SELECT should invalidate only the very first table */
4122 TABLE_LIST *save_table= first_table->next_local;
4123 first_table->next_local= 0;
4124 query_cache_invalidate3(thd, first_table, 1);
4125 first_table->next_local= save_table;
4126 }
4127 }
4128 delete sel_result;
4129 }
4130 /* revert changes for SP */
4131 MYSQL_INSERT_SELECT_DONE(res, (ulong) thd->get_row_count_func());
4132 select_lex->table_list.first= first_table;
4133 }
4134 /*
4135 If we have inserted into a VIEW, and the base table has
4136 AUTO_INCREMENT column, but this column is not accessible through
4137 a view, then we should restore LAST_INSERT_ID to the value it
4138 had before the statement.
4139 */
4140 if (first_table->view && !first_table->contain_auto_increment)
4141 thd->first_successful_insert_id_in_cur_stmt=
4142 thd->first_successful_insert_id_in_prev_stmt;
4143
4144 break;
4145 }
4146 case SQLCOM_DELETE:
4147 {
4148 DBUG_ASSERT(first_table == all_tables && first_table != 0);
4149 if ((res= delete_precheck(thd, all_tables)))
4150 break;
4151 DBUG_ASSERT(select_lex->offset_limit == 0);
4152 unit->set_limit(select_lex);
4153
4154 MYSQL_DELETE_START(thd->query());
4155 res = mysql_delete(thd, all_tables, select_lex->where,
4156 &select_lex->order_list,
4157 unit->select_limit_cnt, select_lex->options);
4158 MYSQL_DELETE_DONE(res, (ulong) thd->get_row_count_func());
4159 break;
4160 }
4161 case SQLCOM_DELETE_MULTI:
4162 {
4163 DBUG_ASSERT(first_table == all_tables && first_table != 0);
4164 TABLE_LIST *aux_tables= thd->lex->auxiliary_table_list.first;
4165 uint del_table_count;
4166 multi_delete *del_result;
4167
4168 if ((res= multi_delete_precheck(thd, all_tables)))
4169 break;
4170
4171 /* condition will be TRUE on SP re-excuting */
4172 if (select_lex->item_list.elements != 0)
4173 select_lex->item_list.empty();
4174 if (add_item_to_list(thd, new Item_null()))
4175 goto error;
4176
4177 THD_STAGE_INFO(thd, stage_init);
4178 if ((res= open_normal_and_derived_tables(thd, all_tables, 0)))
4179 break;
4180
4181 MYSQL_MULTI_DELETE_START(thd->query());
4182 if ((res= mysql_multi_delete_prepare(thd, &del_table_count)))
4183 {
4184 MYSQL_MULTI_DELETE_DONE(1, 0);
4185 goto error;
4186 }
4187
4188 if (!thd->is_fatal_error &&
4189 (del_result= new multi_delete(aux_tables, del_table_count)))
4190 {
4191 if (lex->describe)
4192 res= explain_multi_table_modification(thd, del_result);
4193 else
4194 {
4195 res= mysql_select(thd,
4196 select_lex->get_table_list(),
4197 select_lex->with_wild,
4198 select_lex->item_list,
4199 select_lex->where,
4200 (SQL_I_List<ORDER> *)NULL, (SQL_I_List<ORDER> *)NULL,
4201 (Item *)NULL,
4202 (select_lex->options | thd->variables.option_bits |
4203 SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
4204 OPTION_SETUP_TABLES_DONE) & ~OPTION_BUFFER_RESULT,
4205 del_result, unit, select_lex);
4206 res|= thd->is_error();
4207 if (res)
4208 del_result->abort_result_set();
4209 }
4210 MYSQL_MULTI_DELETE_DONE(res, del_result->num_deleted());
4211 delete del_result;
4212 }
4213 else
4214 {
4215 res= TRUE; // Error
4216 MYSQL_MULTI_DELETE_DONE(1, 0);
4217 }
4218 break;
4219 }
4220 case SQLCOM_DROP_TABLE:
4221 {
4222 DBUG_ASSERT(first_table == all_tables && first_table != 0);
4223 if (!lex->drop_temporary)
4224 {
4225 if (check_table_access(thd, DROP_ACL, all_tables, FALSE, UINT_MAX, FALSE))
4226 goto error; /* purecov: inspected */
4227 }
4228 /* DDL and binlog write order are protected by metadata locks. */
4229 res= mysql_rm_table(thd, first_table, lex->drop_if_exists,
4230 lex->drop_temporary);
4231 }
4232 break;
4233 case SQLCOM_SHOW_PROCESSLIST:
4234 if (!thd->security_ctx->priv_user[0] &&
4235 check_global_access(thd,PROCESS_ACL))
4236 break;
4237 mysqld_list_processes(thd,
4238 (thd->security_ctx->master_access & PROCESS_ACL ?
4239 NullS :
4240 thd->security_ctx->priv_user),
4241 lex->verbose);
4242 break;
4243 case SQLCOM_SHOW_PRIVILEGES:
4244 res= mysqld_show_privileges(thd);
4245 break;
4246 case SQLCOM_SHOW_ENGINE_LOGS:
4247 #ifdef DONT_ALLOW_SHOW_COMMANDS
4248 my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND),
4249 MYF(0)); /* purecov: inspected */
4250 goto error;
4251 #else
4252 {
4253 if (check_access(thd, FILE_ACL, any_db, NULL, NULL, 0, 0))
4254 goto error;
4255 res= ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_LOGS);
4256 break;
4257 }
4258 #endif
4259 case SQLCOM_CHANGE_DB:
4260 {
4261 LEX_STRING db_str= { (char *) select_lex->db, strlen(select_lex->db) };
4262
4263 if (!mysql_change_db(thd, &db_str, FALSE))
4264 my_ok(thd);
4265
4266 break;
4267 }
4268
4269 case SQLCOM_LOAD:
4270 {
4271 DBUG_ASSERT(first_table == all_tables && first_table != 0);
4272 uint privilege= (lex->duplicates == DUP_REPLACE ?
4273 INSERT_ACL | DELETE_ACL : INSERT_ACL) |
4274 (lex->local_file ? 0 : FILE_ACL);
4275
4276 if (lex->local_file)
4277 {
4278 if (!(thd->client_capabilities & CLIENT_LOCAL_FILES) ||
4279 !opt_local_infile)
4280 {
4281 my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), MYF(0));
4282 goto error;
4283 }
4284 }
4285
4286 if (check_one_table_access(thd, privilege, all_tables))
4287 goto error;
4288
4289 res= mysql_load(thd, lex->exchange, first_table, lex->field_list,
4290 lex->update_list, lex->value_list, lex->duplicates,
4291 lex->ignore, (bool) lex->local_file);
4292 break;
4293 }
4294
4295 case SQLCOM_SET_OPTION:
4296 {
4297 List<set_var_base> *lex_var_list= &lex->var_list;
4298
4299 if ((check_table_access(thd, SELECT_ACL, all_tables, FALSE, UINT_MAX, FALSE)
4300 || open_and_lock_tables(thd, all_tables, TRUE, 0)))
4301 goto error;
4302 if (!(res= sql_set_variables(thd, lex_var_list)))
4303 {
4304 /*
4305 If the previous command was a SET ONE_SHOT, we don't want to forget
4306 about the ONE_SHOT property of that SET. So we use a |= instead of = .
4307 */
4308 thd->one_shot_set|= lex->one_shot_set;
4309 my_ok(thd);
4310 }
4311 else
4312 {
4313 /*
4314 We encountered some sort of error, but no message was sent.
4315 Send something semi-generic here since we don't know which
4316 assignment in the list caused the error.
4317 */
4318 if (!thd->is_error())
4319 my_error(ER_WRONG_ARGUMENTS,MYF(0),"SET");
4320 goto error;
4321 }
4322
4323 break;
4324 }
4325
4326 case SQLCOM_UNLOCK_TABLES:
4327 /*
4328 It is critical for mysqldump --single-transaction --master-data that
4329 UNLOCK TABLES does not implicitely commit a connection which has only
4330 done FLUSH TABLES WITH READ LOCK + BEGIN. If this assumption becomes
4331 false, mysqldump will not work.
4332 */
4333 if (thd->variables.option_bits & OPTION_TABLE_LOCK)
4334 {
4335 DBUG_ASSERT(!thd->backup_tables_lock.is_acquired());
4336 /*
4337 Can we commit safely? If not, return to avoid releasing
4338 transactional metadata locks.
4339 */
4340 if (trans_check_state(thd)) {
4341 /* Cannot happen, but still reset this for safety */
4342 if (reset_timer)
4343 reset_statement_timer(thd);
4344 DBUG_RETURN(-1);
4345 }
4346 res= trans_commit_implicit(thd);
4347 thd->locked_tables_list.unlock_locked_tables(thd);
4348 thd->mdl_context.release_transactional_locks();
4349 thd->variables.option_bits&= ~(OPTION_TABLE_LOCK);
4350 }
4351
4352 if (thd->backup_tables_lock.is_acquired())
4353 {
4354 DBUG_ASSERT(!(thd->variables.option_bits & OPTION_TABLE_LOCK));
4355 DBUG_ASSERT(!thd->global_read_lock.is_acquired());
4356
4357 thd->backup_tables_lock.release(thd);
4358 }
4359
4360 if (thd->global_read_lock.is_acquired())
4361 thd->global_read_lock.unlock_global_read_lock(thd);
4362
4363 if (res)
4364 goto error;
4365 my_ok(thd);
4366 break;
4367
4368 case SQLCOM_UNLOCK_BINLOG:
4369 if (thd->backup_binlog_lock.is_acquired())
4370 thd->backup_binlog_lock.release(thd);
4371
4372 my_ok(thd);
4373 break;
4374
4375 case SQLCOM_LOCK_TABLES:
4376 /*
4377 Do not allow LOCK TABLES under an active LOCK TABLES FOR BACKUP in the
4378 same connection.
4379 */
4380 if (thd->backup_tables_lock.abort_if_acquired())
4381 goto error;
4382
4383 /*
4384 Can we commit safely? If not, return to avoid releasing
4385 transactional metadata locks.
4386 */
4387 if (trans_check_state(thd))
4388 {
4389 if (reset_timer)
4390 reset_statement_timer(thd);
4391 DBUG_RETURN(-1);
4392 }
4393 /* We must end the transaction first, regardless of anything */
4394 res= trans_commit_implicit(thd);
4395 thd->locked_tables_list.unlock_locked_tables(thd);
4396 /* Release transactional metadata locks. */
4397 thd->mdl_context.release_transactional_locks();
4398 if (res)
4399 goto error;
4400
4401 /*
4402 Here we have to pre-open temporary tables for LOCK TABLES.
4403
4404 CF_PREOPEN_TMP_TABLES is not set for this SQL statement simply
4405 because LOCK TABLES calls close_thread_tables() as a first thing
4406 (it's called from unlock_locked_tables() above). So even if
4407 CF_PREOPEN_TMP_TABLES was set and the tables would be pre-opened
4408 in a usual way, they would have been closed.
4409 */
4410
4411 if (open_temporary_tables(thd, all_tables))
4412 goto error;
4413
4414 if (lock_tables_precheck(thd, all_tables))
4415 goto error;
4416
4417 thd->variables.option_bits|= OPTION_TABLE_LOCK;
4418
4419 res= lock_tables_open_and_lock_tables(thd, all_tables);
4420
4421 if (res)
4422 {
4423 thd->variables.option_bits&= ~(OPTION_TABLE_LOCK);
4424 }
4425 else
4426 {
4427 #ifdef HAVE_QUERY_CACHE
4428 if (thd->variables.query_cache_wlock_invalidate)
4429 query_cache.invalidate_locked_for_write(first_table);
4430 #endif /*HAVE_QUERY_CACHE*/
4431 my_ok(thd);
4432 }
4433 break;
4434 case SQLCOM_LOCK_TABLES_FOR_BACKUP:
4435 if (!lock_tables_for_backup(thd))
4436 my_ok(thd);
4437
4438 break;
4439 case SQLCOM_LOCK_BINLOG_FOR_BACKUP:
4440 if (!lock_binlog_for_backup(thd))
4441 my_ok(thd);
4442
4443 break;
4444 case SQLCOM_CREATE_COMPRESSION_DICTIONARY:
4445 {
4446 if (lex->default_value->fixed == 0)
4447 lex->default_value->fix_fields(thd, 0);
4448 String dict_data;
4449 String* dict_data_ptr= lex->default_value->val_str_ascii(&dict_data);
4450 if (dict_data_ptr == 0 || dict_data_ptr->ptr() == 0)
4451 {
4452 dict_data.set("", 0, &my_charset_bin);
4453 dict_data_ptr= &dict_data;
4454 }
4455
4456 if ((res= mysql_create_zip_dict(thd, lex->ident.str, lex->ident.length,
4457 dict_data_ptr->ptr(), dict_data_ptr->length(),
4458 (lex->create_info.options & HA_LEX_CREATE_IF_NOT_EXISTS) != 0)) == 0)
4459 my_ok(thd);
4460 break;
4461 }
4462 case SQLCOM_DROP_COMPRESSION_DICTIONARY:
4463 {
4464 if ((res= mysql_drop_zip_dict(thd, lex->ident.str, lex->ident.length,
4465 lex->drop_if_exists)) == 0)
4466 my_ok(thd);
4467 break;
4468 }
4469 case SQLCOM_CREATE_DB:
4470 {
4471 /*
4472 As mysql_create_db() may modify HA_CREATE_INFO structure passed to
4473 it, we need to use a copy of LEX::create_info to make execution
4474 prepared statement- safe.
4475 */
4476 HA_CREATE_INFO create_info(lex->create_info);
4477 char *alias;
4478 if (!(alias=thd->strmake(lex->name.str, lex->name.length)) ||
4479 (check_and_convert_db_name(&lex->name, FALSE) != IDENT_NAME_OK))
4480 break;
4481 if (check_access(thd, CREATE_ACL, lex->name.str, NULL, NULL, 1, 0))
4482 break;
4483 res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias :
4484 lex->name.str), &create_info, 0);
4485 break;
4486 }
4487 case SQLCOM_DROP_DB:
4488 {
4489 if (check_and_convert_db_name(&lex->name, FALSE) != IDENT_NAME_OK)
4490 break;
4491 if (check_access(thd, DROP_ACL, lex->name.str, NULL, NULL, 1, 0))
4492 break;
4493 res= mysql_rm_db(thd, lex->name.str, lex->drop_if_exists, 0);
4494 break;
4495 }
4496 case SQLCOM_ALTER_DB_UPGRADE:
4497 {
4498 LEX_STRING *db= & lex->name;
4499 if (check_and_convert_db_name(db, FALSE) != IDENT_NAME_OK)
4500 break;
4501 if (check_access(thd, ALTER_ACL, db->str, NULL, NULL, 1, 0) ||
4502 check_access(thd, DROP_ACL, db->str, NULL, NULL, 1, 0) ||
4503 check_access(thd, CREATE_ACL, db->str, NULL, NULL, 1, 0))
4504 {
4505 res= 1;
4506 break;
4507 }
4508 res= mysql_upgrade_db(thd, db);
4509 if (!res)
4510 my_ok(thd);
4511 break;
4512 }
4513 case SQLCOM_ALTER_DB:
4514 {
4515 LEX_STRING *db= &lex->name;
4516 HA_CREATE_INFO create_info(lex->create_info);
4517 if (check_and_convert_db_name(db, FALSE) != IDENT_NAME_OK)
4518 break;
4519 if (check_access(thd, ALTER_ACL, db->str, NULL, NULL, 1, 0))
4520 break;
4521 res= mysql_alter_db(thd, db->str, &create_info);
4522 break;
4523 }
4524 case SQLCOM_SHOW_CREATE_DB:
4525 {
4526 DBUG_EXECUTE_IF("4x_server_emul",
4527 my_error(ER_UNKNOWN_ERROR, MYF(0)); goto error;);
4528 if (check_and_convert_db_name(&lex->name, TRUE) != IDENT_NAME_OK)
4529 break;
4530 res= mysqld_show_create_db(thd, lex->name.str, &lex->create_info);
4531 break;
4532 }
4533 case SQLCOM_CREATE_EVENT:
4534 case SQLCOM_ALTER_EVENT:
4535 #ifdef HAVE_EVENT_SCHEDULER
4536 do
4537 {
4538 DBUG_ASSERT(lex->event_parse_data);
4539 if (lex->table_or_sp_used())
4540 {
4541 my_error(ER_NOT_SUPPORTED_YET, MYF(0), "Usage of subqueries or stored "
4542 "function calls as part of this statement");
4543 break;
4544 }
4545
4546 res= sp_process_definer(thd);
4547 if (res)
4548 break;
4549
4550 switch (lex->sql_command) {
4551 case SQLCOM_CREATE_EVENT:
4552 {
4553 bool if_not_exists= (lex->create_info.options &
4554 HA_LEX_CREATE_IF_NOT_EXISTS);
4555 res= Events::create_event(thd, lex->event_parse_data, if_not_exists);
4556 break;
4557 }
4558 case SQLCOM_ALTER_EVENT:
4559 res= Events::update_event(thd, lex->event_parse_data,
4560 lex->spname ? &lex->spname->m_db : NULL,
4561 lex->spname ? &lex->spname->m_name : NULL);
4562 break;
4563 default:
4564 DBUG_ASSERT(0);
4565 }
4566 DBUG_PRINT("info",("DDL error code=%d", res));
4567 if (!res)
4568 my_ok(thd);
4569
4570 } while (0);
4571 /* Don't do it, if we are inside a SP */
4572 if (!thd->sp_runtime_ctx)
4573 {
4574 delete lex->sphead;
4575 lex->sphead= NULL;
4576 }
4577 /* lex->unit.cleanup() is called outside, no need to call it here */
4578 break;
4579 case SQLCOM_SHOW_CREATE_EVENT:
4580 res= Events::show_create_event(thd, lex->spname->m_db,
4581 lex->spname->m_name);
4582 break;
4583 case SQLCOM_DROP_EVENT:
4584 if (!(res= Events::drop_event(thd,
4585 lex->spname->m_db, lex->spname->m_name,
4586 lex->drop_if_exists)))
4587 my_ok(thd);
4588 break;
4589 #else
4590 my_error(ER_NOT_SUPPORTED_YET,MYF(0),"embedded server");
4591 break;
4592 #endif
4593 case SQLCOM_CREATE_FUNCTION: // UDF function
4594 {
4595 if (check_access(thd, INSERT_ACL, "mysql", NULL, NULL, 1, 0))
4596 break;
4597 #ifdef HAVE_DLOPEN
4598 if (!(res = mysql_create_function(thd, &lex->udf)))
4599 my_ok(thd);
4600 #else
4601 my_error(ER_CANT_OPEN_LIBRARY, MYF(0), lex->udf.dl, 0, "feature disabled");
4602 res= TRUE;
4603 #endif
4604 break;
4605 }
4606 #ifndef NO_EMBEDDED_ACCESS_CHECKS
4607 case SQLCOM_CREATE_USER:
4608 {
4609 if (check_access(thd, INSERT_ACL, "mysql", NULL, NULL, 1, 1) &&
4610 check_global_access(thd,CREATE_USER_ACL))
4611 break;
4612 /* Conditionally writes to binlog */
4613 if (!(res= mysql_create_user(thd, lex->users_list)))
4614 my_ok(thd);
4615 break;
4616 }
4617 case SQLCOM_DROP_USER:
4618 {
4619 if (check_access(thd, DELETE_ACL, "mysql", NULL, NULL, 1, 1) &&
4620 check_global_access(thd,CREATE_USER_ACL))
4621 break;
4622 /* Conditionally writes to binlog */
4623 if (!(res= mysql_drop_user(thd, lex->users_list)))
4624 my_ok(thd);
4625 break;
4626 }
4627 case SQLCOM_RENAME_USER:
4628 {
4629 if (check_access(thd, UPDATE_ACL, "mysql", NULL, NULL, 1, 1) &&
4630 check_global_access(thd,CREATE_USER_ACL))
4631 break;
4632 /* Conditionally writes to binlog */
4633 if (!(res= mysql_rename_user(thd, lex->users_list)))
4634 my_ok(thd);
4635 break;
4636 }
4637 case SQLCOM_REVOKE_ALL:
4638 {
4639 if (check_access(thd, UPDATE_ACL, "mysql", NULL, NULL, 1, 1) &&
4640 check_global_access(thd,CREATE_USER_ACL))
4641 break;
4642
4643 /* Replicate current user as grantor */
4644 thd->binlog_invoker();
4645
4646 /* Conditionally writes to binlog */
4647 if (!(res = mysql_revoke_all(thd, lex->users_list)))
4648 my_ok(thd);
4649 break;
4650 }
4651 case SQLCOM_REVOKE:
4652 case SQLCOM_GRANT:
4653 {
4654 if (lex->type != TYPE_ENUM_PROXY &&
4655 check_access(thd, lex->grant | lex->grant_tot_col | GRANT_ACL,
4656 first_table ? first_table->db : select_lex->db,
4657 first_table ? &first_table->grant.privilege : NULL,
4658 first_table ? &first_table->grant.m_internal : NULL,
4659 first_table ? 0 : 1, 0))
4660 goto error;
4661
4662 /* Replicate current user as grantor */
4663 thd->binlog_invoker();
4664
4665 if (thd->security_ctx->user) // If not replication
4666 {
4667 LEX_USER *user, *tmp_user;
4668 bool first_user= TRUE;
4669
4670 List_iterator <LEX_USER> user_list(lex->users_list);
4671 while ((tmp_user= user_list++))
4672 {
4673 if (!(user= get_current_user(thd, tmp_user)))
4674 goto error;
4675 if (specialflag & SPECIAL_NO_RESOLVE &&
4676 hostname_requires_resolving(user->host.str))
4677 push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
4678 ER_WARN_HOSTNAME_WONT_WORK,
4679 ER(ER_WARN_HOSTNAME_WONT_WORK));
4680 // Are we trying to change a password of another user
4681 DBUG_ASSERT(user->host.str != 0);
4682
4683 /*
4684 GRANT/REVOKE PROXY has the target user as a first entry in the list.
4685 */
4686 if (lex->type == TYPE_ENUM_PROXY && first_user)
4687 {
4688 first_user= FALSE;
4689 if (acl_check_proxy_grant_access (thd, user->host.str, user->user.str,
4690 lex->grant & GRANT_ACL))
4691 goto error;
4692 }
4693 else if (is_acl_user(user->host.str, user->user.str) &&
4694 user->password.str &&
4695 check_change_password (thd, user->host.str, user->user.str,
4696 user->password.str,
4697 user->password.length))
4698 goto error;
4699 }
4700 }
4701 if (first_table)
4702 {
4703 if (lex->type == TYPE_ENUM_PROCEDURE ||
4704 lex->type == TYPE_ENUM_FUNCTION)
4705 {
4706 uint grants= lex->all_privileges
4707 ? (PROC_ACLS & ~GRANT_ACL) | (lex->grant & GRANT_ACL)
4708 : lex->grant;
4709 if (check_grant_routine(thd, grants | GRANT_ACL, all_tables,
4710 lex->type == TYPE_ENUM_PROCEDURE, 0))
4711 goto error;
4712 /* Conditionally writes to binlog */
4713 res= mysql_routine_grant(thd, all_tables,
4714 lex->type == TYPE_ENUM_PROCEDURE,
4715 lex->users_list, grants,
4716 lex->sql_command == SQLCOM_REVOKE, TRUE);
4717 if (!res)
4718 my_ok(thd);
4719 }
4720 else
4721 {
4722 if (check_grant(thd,(lex->grant | lex->grant_tot_col | GRANT_ACL),
4723 all_tables, FALSE, UINT_MAX, FALSE))
4724 goto error;
4725 /* Conditionally writes to binlog */
4726 res= mysql_table_grant(thd, all_tables, lex->users_list,
4727 lex->columns, lex->grant,
4728 lex->sql_command == SQLCOM_REVOKE);
4729 }
4730 }
4731 else
4732 {
4733 if (lex->columns.elements || (lex->type && lex->type != TYPE_ENUM_PROXY))
4734 {
4735 my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER(ER_ILLEGAL_GRANT_FOR_TABLE),
4736 MYF(0));
4737 goto error;
4738 }
4739 else
4740 {
4741 /* Conditionally writes to binlog */
4742 res = mysql_grant(thd, select_lex->db, lex->users_list, lex->grant,
4743 lex->sql_command == SQLCOM_REVOKE,
4744 lex->type == TYPE_ENUM_PROXY);
4745 }
4746 if (!res)
4747 {
4748 if (lex->sql_command == SQLCOM_GRANT)
4749 {
4750 List_iterator <LEX_USER> str_list(lex->users_list);
4751 LEX_USER *user, *tmp_user;
4752 while ((tmp_user=str_list++))
4753 {
4754 if (!(user= get_current_user(thd, tmp_user)))
4755 goto error;
4756 reset_mqh(user, 0);
4757 }
4758 }
4759 }
4760 }
4761 break;
4762 }
4763 #endif /*!NO_EMBEDDED_ACCESS_CHECKS*/
4764 case SQLCOM_RESET:
4765 /*
4766 RESET commands are never written to the binary log, so we have to
4767 initialize this variable because RESET shares the same code as FLUSH
4768 */
4769 lex->no_write_to_binlog= 1;
4770 // fallthrough
4771 case SQLCOM_FLUSH:
4772 {
4773 int write_to_binlog;
4774
4775 if (lex->type & REFRESH_FLUSH_PAGE_BITMAPS
4776 || lex->type & REFRESH_RESET_PAGE_BITMAPS)
4777 {
4778 if (check_global_access(thd, SUPER_ACL))
4779 goto error;
4780 }
4781 else if (check_global_access(thd, RELOAD_ACL))
4782 goto error;
4783
4784 if (first_table && lex->type & REFRESH_READ_LOCK)
4785 {
4786 /*
4787 Do not allow FLUSH TABLES <table_list> WITH READ LOCK under an active
4788 LOCK TABLES FOR BACKUP lock.
4789 */
4790 if (thd->backup_tables_lock.abort_if_acquired())
4791 goto error;
4792
4793 /* Check table-level privileges. */
4794 if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables,
4795 FALSE, UINT_MAX, FALSE))
4796 goto error;
4797 if (flush_tables_with_read_lock(thd, all_tables))
4798 goto error;
4799 my_ok(thd);
4800 break;
4801 }
4802 else if (first_table && lex->type & REFRESH_FOR_EXPORT)
4803 {
4804 /*
4805 Do not allow FLUSH TABLES ... FOR EXPORT under an active LOCK TABLES
4806 FOR BACKUP lock.
4807 */
4808 if (thd->backup_tables_lock.abort_if_acquired())
4809 goto error;
4810
4811 /* Check table-level privileges. */
4812 if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables,
4813 FALSE, UINT_MAX, FALSE))
4814 goto error;
4815 if (flush_tables_for_export(thd, all_tables))
4816 goto error;
4817 my_ok(thd);
4818 break;
4819 }
4820
4821 /*
4822 reload_acl_and_cache() will tell us if we are allowed to write to the
4823 binlog or not.
4824 */
4825 if (!reload_acl_and_cache(thd, lex->type, first_table, &write_to_binlog))
4826 {
4827 /*
4828 We WANT to write and we CAN write.
4829 ! we write after unlocking the table.
4830 */
4831 /*
4832 Presumably, RESET and binlog writing doesn't require synchronization
4833 */
4834
4835 if (write_to_binlog > 0) // we should write
4836 {
4837 if (!lex->no_write_to_binlog)
4838 res= write_bin_log(thd, FALSE, thd->query(), thd->query_length());
4839 } else if (write_to_binlog < 0)
4840 {
4841 /*
4842 We should not write, but rather report error because
4843 reload_acl_and_cache binlog interactions failed
4844 */
4845 res= 1;
4846 }
4847
4848 if (!res)
4849 my_ok(thd);
4850 }
4851
4852 break;
4853 }
4854 case SQLCOM_KILL:
4855 {
4856 Item *it= (Item *)lex->value_list.head();
4857
4858 if (lex->table_or_sp_used())
4859 {
4860 my_error(ER_NOT_SUPPORTED_YET, MYF(0), "Usage of subqueries or stored "
4861 "function calls as part of this statement");
4862 break;
4863 }
4864
4865 if ((!it->fixed && it->fix_fields(lex->thd, &it)) || it->check_cols(1))
4866 {
4867 my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
4868 MYF(0));
4869 goto error;
4870 }
4871 sql_kill(thd, (ulong)it->val_int(), lex->type & ONLY_KILL_QUERY);
4872 break;
4873 }
4874 #ifndef NO_EMBEDDED_ACCESS_CHECKS
4875 case SQLCOM_SHOW_GRANTS:
4876 {
4877 LEX_USER *grant_user= get_current_user(thd, lex->grant_user);
4878 if (!grant_user)
4879 goto error;
4880 if (!strcmp(thd->security_ctx->priv_user, grant_user->user.str) ||
4881 !check_access(thd, SELECT_ACL, "mysql", NULL, NULL, 1, 0))
4882 {
4883 res = mysql_show_grants(thd, grant_user);
4884 }
4885 break;
4886 }
4887 #endif
4888 case SQLCOM_BEGIN:
4889 if (trans_begin(thd, lex->start_transaction_opt))
4890 goto error;
4891 my_ok(thd);
4892 break;
4893 case SQLCOM_COMMIT:
4894 {
4895 DBUG_ASSERT(thd->lock == NULL ||
4896 thd->locked_tables_mode == LTM_LOCK_TABLES);
4897 bool tx_chain= (lex->tx_chain == TVL_YES ||
4898 (thd->variables.completion_type == 1 &&
4899 lex->tx_chain != TVL_NO));
4900 bool tx_release= (lex->tx_release == TVL_YES ||
4901 (thd->variables.completion_type == 2 &&
4902 lex->tx_release != TVL_NO));
4903 if (trans_commit(thd))
4904 goto error;
4905 thd->mdl_context.release_transactional_locks();
4906 /* Begin transaction with the same isolation level. */
4907 if (tx_chain)
4908 {
4909 if (trans_begin(thd))
4910 goto error;
4911 }
4912 else
4913 {
4914 /* Reset the isolation level and access mode if no chaining transaction.*/
4915 thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation;
4916 thd->tx_read_only= thd->variables.tx_read_only;
4917 }
4918 /* Disconnect the current client connection. */
4919 if (tx_release)
4920 thd->killed= THD::KILL_CONNECTION;
4921 my_ok(thd);
4922 break;
4923 }
4924 case SQLCOM_ROLLBACK:
4925 {
4926 DBUG_ASSERT(thd->lock == NULL ||
4927 thd->locked_tables_mode == LTM_LOCK_TABLES);
4928 bool tx_chain= (lex->tx_chain == TVL_YES ||
4929 (thd->variables.completion_type == 1 &&
4930 lex->tx_chain != TVL_NO));
4931 bool tx_release= (lex->tx_release == TVL_YES ||
4932 (thd->variables.completion_type == 2 &&
4933 lex->tx_release != TVL_NO));
4934 if (trans_rollback(thd))
4935 goto error;
4936 thd->mdl_context.release_transactional_locks();
4937 /* Begin transaction with the same isolation level. */
4938 if (tx_chain)
4939 {
4940 if (trans_begin(thd))
4941 goto error;
4942 }
4943 else
4944 {
4945 /* Reset the isolation level and access mode if no chaining transaction.*/
4946 thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation;
4947 thd->tx_read_only= thd->variables.tx_read_only;
4948 }
4949 /* Disconnect the current client connection. */
4950 if (tx_release)
4951 thd->killed= THD::KILL_CONNECTION;
4952 my_ok(thd);
4953 break;
4954 }
4955 case SQLCOM_RELEASE_SAVEPOINT:
4956 if (trans_release_savepoint(thd, lex->ident))
4957 goto error;
4958 my_ok(thd);
4959 break;
4960 case SQLCOM_ROLLBACK_TO_SAVEPOINT:
4961 if (trans_rollback_to_savepoint(thd, lex->ident))
4962 goto error;
4963 my_ok(thd);
4964 break;
4965 case SQLCOM_SAVEPOINT:
4966 if (trans_savepoint(thd, lex->ident))
4967 goto error;
4968 my_ok(thd);
4969 break;
4970 case SQLCOM_CREATE_PROCEDURE:
4971 case SQLCOM_CREATE_SPFUNCTION:
4972 {
4973 uint namelen;
4974 char *name;
4975 int sp_result= SP_INTERNAL_ERROR;
4976
4977 DBUG_ASSERT(lex->sphead != 0);
4978 DBUG_ASSERT(lex->sphead->m_db.str); /* Must be initialized in the parser */
4979 /*
4980 Verify that the database name is allowed, optionally
4981 lowercase it.
4982 */
4983 if (check_and_convert_db_name(&lex->sphead->m_db, FALSE) != IDENT_NAME_OK)
4984 goto create_sp_error;
4985
4986 if (check_access(thd, CREATE_PROC_ACL, lex->sphead->m_db.str,
4987 NULL, NULL, 0, 0))
4988 goto create_sp_error;
4989
4990 /*
4991 Check that a database directory with this name
4992 exists. Design note: This won't work on virtual databases
4993 like information_schema.
4994 */
4995 if (check_db_dir_existence(lex->sphead->m_db.str))
4996 {
4997 my_error(ER_BAD_DB_ERROR, MYF(0), lex->sphead->m_db.str);
4998 goto create_sp_error;
4999 }
5000
5001 name= lex->sphead->name(&namelen);
5002 #ifdef HAVE_DLOPEN
5003 if (lex->sphead->m_type == SP_TYPE_FUNCTION)
5004 {
5005 udf_func *udf = find_udf(name, namelen);
5006
5007 if (udf)
5008 {
5009 my_error(ER_UDF_EXISTS, MYF(0), name);
5010 goto create_sp_error;
5011 }
5012 }
5013 #endif
5014
5015 if (sp_process_definer(thd))
5016 goto create_sp_error;
5017
5018 /*
5019 Record the CURRENT_USER in binlog. The CURRENT_USER is used on slave to
5020 grant default privileges when sp_automatic_privileges variable is set.
5021 */
5022 thd->binlog_invoker();
5023
5024 res= (sp_result= sp_create_routine(thd, lex->sphead));
5025 switch (sp_result) {
5026 case SP_OK: {
5027 #ifndef NO_EMBEDDED_ACCESS_CHECKS
5028 /* only add privileges if really neccessary */
5029
5030 Security_context security_context;
5031 bool restore_backup_context= false;
5032 Security_context *backup= NULL;
5033 /*
5034 We're going to issue an implicit GRANT statement so we close all
5035 open tables. We have to keep metadata locks as this ensures that
5036 this statement is atomic against concurent FLUSH TABLES WITH READ
5037 LOCK. Deadlocks which can arise due to fact that this implicit
5038 statement takes metadata locks should be detected by a deadlock
5039 detector in MDL subsystem and reported as errors.
5040
5041 No need to commit/rollback statement transaction, it's not started.
5042
5043 TODO: Long-term we should either ensure that implicit GRANT statement
5044 is written into binary log as a separate statement or make both
5045 creation of routine and implicit GRANT parts of one fully atomic
5046 statement.
5047 */
5048 DBUG_ASSERT(thd->transaction.stmt.is_empty());
5049 close_thread_tables(thd);
5050 /*
5051 Check if invoker exists on slave, then use invoker privilege to
5052 insert routine privileges to mysql.procs_priv. If invoker is not
5053 available then consider using definer.
5054
5055 Check if the definer exists on slave,
5056 then use definer privilege to insert routine privileges to mysql.procs_priv.
5057
5058 For current user of SQL thread has GLOBAL_ACL privilege,
5059 which doesn't any check routine privileges,
5060 so no routine privilege record will insert into mysql.procs_priv.
5061 */
5062
5063 if (thd->slave_thread)
5064 {
5065 LEX_STRING current_user;
5066 LEX_STRING current_host;
5067 if (thd->has_invoker())
5068 {
5069 current_host= thd->get_invoker_host();
5070 current_user= thd->get_invoker_user();
5071 }
5072 else
5073 {
5074 current_host= lex->definer->host;
5075 current_user= lex->definer->user;
5076 }
5077 if (is_acl_user(current_host.str, current_user.str))
5078 {
5079 security_context.change_security_context(thd,
5080 ¤t_user,
5081 ¤t_host,
5082 &thd->lex->sphead->m_db,
5083 &backup);
5084 restore_backup_context= true;
5085 }
5086 }
5087
5088 if (sp_automatic_privileges && !opt_noacl &&
5089 check_routine_access(thd, DEFAULT_CREATE_PROC_ACLS,
5090 lex->sphead->m_db.str, name,
5091 lex->sql_command == SQLCOM_CREATE_PROCEDURE, 1))
5092 {
5093 if (sp_grant_privileges(thd, lex->sphead->m_db.str, name,
5094 lex->sql_command == SQLCOM_CREATE_PROCEDURE))
5095 push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
5096 ER_PROC_AUTO_GRANT_FAIL, ER(ER_PROC_AUTO_GRANT_FAIL));
5097 thd->clear_error();
5098 }
5099
5100 /*
5101 Restore current user with GLOBAL_ACL privilege of SQL thread
5102 */
5103 if (restore_backup_context)
5104 {
5105 DBUG_ASSERT(thd->slave_thread == 1);
5106 thd->security_ctx->restore_security_context(thd, backup);
5107 }
5108
5109 #endif
5110 break;
5111 }
5112 case SP_WRITE_ROW_FAILED:
5113 my_error(ER_SP_ALREADY_EXISTS, MYF(0), SP_TYPE_STRING(lex), name);
5114 break;
5115 case SP_BAD_IDENTIFIER:
5116 my_error(ER_TOO_LONG_IDENT, MYF(0), name);
5117 break;
5118 case SP_BODY_TOO_LONG:
5119 my_error(ER_TOO_LONG_BODY, MYF(0), name);
5120 break;
5121 case SP_FLD_STORE_FAILED:
5122 my_error(ER_CANT_CREATE_SROUTINE, MYF(0), name);
5123 break;
5124 default:
5125 my_error(ER_SP_STORE_FAILED, MYF(0), SP_TYPE_STRING(lex), name);
5126 break;
5127 } /* end switch */
5128
5129 /*
5130 Capture all errors within this CASE and
5131 clean up the environment.
5132 */
5133 create_sp_error:
5134 if (sp_result != SP_OK )
5135 goto error;
5136 my_ok(thd);
5137 break; /* break super switch */
5138 } /* end case group bracket */
5139 case SQLCOM_CALL:
5140 {
5141 sp_head *sp;
5142
5143 /* Here we check for the execute privilege on stored procedure. */
5144 if (check_routine_access(thd, EXECUTE_ACL, lex->spname->m_db.str,
5145 lex->spname->m_name.str,
5146 lex->sql_command == SQLCOM_CALL, 0))
5147 goto error;
5148
5149 /*
5150 This will cache all SP and SF and open and lock all tables
5151 required for execution.
5152 */
5153 if (check_table_access(thd, SELECT_ACL, all_tables, FALSE,
5154 UINT_MAX, FALSE) ||
5155 open_and_lock_tables(thd, all_tables, TRUE, 0))
5156 goto error;
5157
5158 /*
5159 By this moment all needed SPs should be in cache so no need to look
5160 into DB.
5161 */
5162 if (!(sp= sp_find_routine(thd, SP_TYPE_PROCEDURE, lex->spname,
5163 &thd->sp_proc_cache, TRUE)))
5164 {
5165 my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PROCEDURE",
5166 lex->spname->m_qname.str);
5167 goto error;
5168 }
5169 else
5170 {
5171 ha_rows select_limit;
5172 /* bits that should be cleared in thd->server_status */
5173 uint bits_to_be_cleared= 0;
5174 /*
5175 Check that the stored procedure doesn't contain Dynamic SQL
5176 and doesn't return result sets: such stored procedures can't
5177 be called from a function or trigger.
5178 */
5179 if (thd->in_sub_stmt)
5180 {
5181 const char *where= (thd->in_sub_stmt & SUB_STMT_TRIGGER ?
5182 "trigger" : "function");
5183 if (sp->is_not_allowed_in_function(where))
5184 goto error;
5185 }
5186
5187 if (sp->m_flags & sp_head::MULTI_RESULTS)
5188 {
5189 if (! (thd->client_capabilities & CLIENT_MULTI_RESULTS))
5190 {
5191 /*
5192 The client does not support multiple result sets being sent
5193 back
5194 */
5195 my_error(ER_SP_BADSELECT, MYF(0), sp->m_qname.str);
5196 goto error;
5197 }
5198 /*
5199 If SERVER_MORE_RESULTS_EXISTS is not set,
5200 then remember that it should be cleared
5201 */
5202 bits_to_be_cleared= (~thd->server_status &
5203 SERVER_MORE_RESULTS_EXISTS);
5204 thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
5205 }
5206
5207 if (check_routine_access(thd, EXECUTE_ACL,
5208 sp->m_db.str, sp->m_name.str, TRUE, FALSE))
5209 {
5210 goto error;
5211 }
5212 select_limit= thd->variables.select_limit;
5213 thd->variables.select_limit= HA_POS_ERROR;
5214
5215 /*
5216 We never write CALL statements into binlog:
5217 - If the mode is non-prelocked, each statement will be logged
5218 separately.
5219 - If the mode is prelocked, the invoking statement will care
5220 about writing into binlog.
5221 So just execute the statement.
5222 */
5223 res= sp->execute_procedure(thd, &lex->value_list);
5224
5225 thd->variables.select_limit= select_limit;
5226
5227 thd->server_status&= ~bits_to_be_cleared;
5228
5229 if (!res)
5230 {
5231 my_ok(thd, (thd->get_row_count_func() < 0) ? 0 : thd->get_row_count_func());
5232 }
5233 else
5234 {
5235 DBUG_ASSERT(thd->is_error() || thd->killed);
5236 goto error; // Substatement should already have sent error
5237 }
5238 }
5239 break;
5240 }
5241 case SQLCOM_ALTER_PROCEDURE:
5242 case SQLCOM_ALTER_FUNCTION:
5243 {
5244 if (check_routine_access(thd, ALTER_PROC_ACL, lex->spname->m_db.str,
5245 lex->spname->m_name.str,
5246 lex->sql_command == SQLCOM_ALTER_PROCEDURE,
5247 false))
5248 goto error;
5249
5250 enum_sp_type sp_type= (lex->sql_command == SQLCOM_ALTER_PROCEDURE) ?
5251 SP_TYPE_PROCEDURE : SP_TYPE_FUNCTION;
5252 /*
5253 Note that if you implement the capability of ALTER FUNCTION to
5254 alter the body of the function, this command should be made to
5255 follow the restrictions that log-bin-trust-function-creators=0
5256 already puts on CREATE FUNCTION.
5257 */
5258 /* Conditionally writes to binlog */
5259 int sp_result= sp_update_routine(thd, sp_type, lex->spname,
5260 &lex->sp_chistics);
5261 if (thd->killed)
5262 goto error;
5263 switch (sp_result)
5264 {
5265 case SP_OK:
5266 my_ok(thd);
5267 break;
5268 case SP_KEY_NOT_FOUND:
5269 my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
5270 SP_COM_STRING(lex), lex->spname->m_qname.str);
5271 goto error;
5272 default:
5273 my_error(ER_SP_CANT_ALTER, MYF(0),
5274 SP_COM_STRING(lex), lex->spname->m_qname.str);
5275 goto error;
5276 }
5277 break;
5278 }
5279 case SQLCOM_DROP_PROCEDURE:
5280 case SQLCOM_DROP_FUNCTION:
5281 {
5282 #ifdef HAVE_DLOPEN
5283 if (lex->sql_command == SQLCOM_DROP_FUNCTION &&
5284 ! lex->spname->m_explicit_name)
5285 {
5286 /* DROP FUNCTION <non qualified name> */
5287 udf_func *udf = find_udf(lex->spname->m_name.str,
5288 lex->spname->m_name.length);
5289 if (udf)
5290 {
5291 if (check_access(thd, DELETE_ACL, "mysql", NULL, NULL, 1, 0))
5292 goto error;
5293
5294 if (!(res = mysql_drop_function(thd, &lex->spname->m_name)))
5295 {
5296 my_ok(thd);
5297 break;
5298 }
5299 my_error(ER_SP_DROP_FAILED, MYF(0),
5300 "FUNCTION (UDF)", lex->spname->m_name.str);
5301 goto error;
5302 }
5303
5304 if (lex->spname->m_db.str == NULL)
5305 {
5306 if (lex->drop_if_exists)
5307 {
5308 push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
5309 ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST),
5310 "FUNCTION (UDF)", lex->spname->m_name.str);
5311 res= FALSE;
5312 my_ok(thd);
5313 break;
5314 }
5315 my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
5316 "FUNCTION (UDF)", lex->spname->m_name.str);
5317 goto error;
5318 }
5319 /* Fall thought to test for a stored function */
5320 }
5321 #endif
5322
5323 char *db= lex->spname->m_db.str;
5324 char *name= lex->spname->m_name.str;
5325
5326 if (check_routine_access(thd, ALTER_PROC_ACL, db, name,
5327 lex->sql_command == SQLCOM_DROP_PROCEDURE,
5328 false))
5329 goto error;
5330
5331 enum_sp_type sp_type= (lex->sql_command == SQLCOM_DROP_PROCEDURE) ?
5332 SP_TYPE_PROCEDURE : SP_TYPE_FUNCTION;
5333
5334 /* Conditionally writes to binlog */
5335 int sp_result= sp_drop_routine(thd, sp_type, lex->spname);
5336
5337 #ifndef NO_EMBEDDED_ACCESS_CHECKS
5338 /*
5339 We're going to issue an implicit REVOKE statement so we close all
5340 open tables. We have to keep metadata locks as this ensures that
5341 this statement is atomic against concurent FLUSH TABLES WITH READ
5342 LOCK. Deadlocks which can arise due to fact that this implicit
5343 statement takes metadata locks should be detected by a deadlock
5344 detector in MDL subsystem and reported as errors.
5345
5346 No need to commit/rollback statement transaction, it's not started.
5347
5348 TODO: Long-term we should either ensure that implicit REVOKE statement
5349 is written into binary log as a separate statement or make both
5350 dropping of routine and implicit REVOKE parts of one fully atomic
5351 statement.
5352 */
5353 DBUG_ASSERT(thd->transaction.stmt.is_empty());
5354 close_thread_tables(thd);
5355
5356 if (sp_result != SP_KEY_NOT_FOUND &&
5357 sp_automatic_privileges && !opt_noacl &&
5358 sp_revoke_privileges(thd, db, name,
5359 lex->sql_command == SQLCOM_DROP_PROCEDURE))
5360 {
5361 push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
5362 ER_PROC_AUTO_REVOKE_FAIL,
5363 ER(ER_PROC_AUTO_REVOKE_FAIL));
5364 /* If this happens, an error should have been reported. */
5365 goto error;
5366 }
5367 #endif
5368
5369 res= sp_result;
5370 switch (sp_result) {
5371 case SP_OK:
5372 my_ok(thd);
5373 break;
5374 case SP_KEY_NOT_FOUND:
5375 if (lex->drop_if_exists)
5376 {
5377 res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
5378 push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
5379 ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST),
5380 SP_COM_STRING(lex), lex->spname->m_qname.str);
5381 if (!res)
5382 my_ok(thd);
5383 break;
5384 }
5385 my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
5386 SP_COM_STRING(lex), lex->spname->m_qname.str);
5387 goto error;
5388 default:
5389 my_error(ER_SP_DROP_FAILED, MYF(0),
5390 SP_COM_STRING(lex), lex->spname->m_qname.str);
5391 goto error;
5392 }
5393 break;
5394 }
5395 case SQLCOM_SHOW_CREATE_PROC:
5396 {
5397 if (sp_show_create_routine(thd, SP_TYPE_PROCEDURE, lex->spname))
5398 goto error;
5399 break;
5400 }
5401 case SQLCOM_SHOW_CREATE_FUNC:
5402 {
5403 if (sp_show_create_routine(thd, SP_TYPE_FUNCTION, lex->spname))
5404 goto error;
5405 break;
5406 }
5407 case SQLCOM_SHOW_PROC_CODE:
5408 case SQLCOM_SHOW_FUNC_CODE:
5409 {
5410 #ifndef DBUG_OFF
5411 sp_head *sp;
5412 enum_sp_type sp_type= (lex->sql_command == SQLCOM_SHOW_PROC_CODE) ?
5413 SP_TYPE_PROCEDURE : SP_TYPE_FUNCTION;
5414
5415 if (sp_cache_routine(thd, sp_type, lex->spname, false, &sp))
5416 goto error;
5417 if (!sp || sp->show_routine_code(thd))
5418 {
5419 /* We don't distinguish between errors for now */
5420 my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
5421 SP_COM_STRING(lex), lex->spname->m_name.str);
5422 goto error;
5423 }
5424 break;
5425 #else
5426 my_error(ER_FEATURE_DISABLED, MYF(0),
5427 "SHOW PROCEDURE|FUNCTION CODE", "--with-debug");
5428 goto error;
5429 #endif // ifndef DBUG_OFF
5430 }
5431 case SQLCOM_SHOW_CREATE_TRIGGER:
5432 {
5433 if (lex->spname->m_name.length > NAME_LEN)
5434 {
5435 my_error(ER_TOO_LONG_IDENT, MYF(0), lex->spname->m_name.str);
5436 goto error;
5437 }
5438
5439 if (show_create_trigger(thd, lex->spname))
5440 goto error; /* Error has been already logged. */
5441
5442 break;
5443 }
5444 case SQLCOM_CREATE_VIEW:
5445 {
5446 /*
5447 Note: SQLCOM_CREATE_VIEW also handles 'ALTER VIEW' commands
5448 as specified through the thd->lex->create_view_mode flag.
5449 */
5450 res= mysql_create_view(thd, first_table, thd->lex->create_view_mode);
5451 break;
5452 }
5453 case SQLCOM_DROP_VIEW:
5454 {
5455 if (check_table_access(thd, DROP_ACL, all_tables, FALSE, UINT_MAX, FALSE))
5456 goto error;
5457 /* Conditionally writes to binlog. */
5458 res= mysql_drop_view(thd, first_table, thd->lex->drop_mode);
5459 break;
5460 }
5461 case SQLCOM_CREATE_TRIGGER:
5462 {
5463 /* Conditionally writes to binlog. */
5464 res= mysql_create_or_drop_trigger(thd, all_tables, 1);
5465
5466 break;
5467 }
5468 case SQLCOM_DROP_TRIGGER:
5469 {
5470 /* Conditionally writes to binlog. */
5471 res= mysql_create_or_drop_trigger(thd, all_tables, 0);
5472 break;
5473 }
5474 case SQLCOM_XA_START:
5475 if (trans_xa_start(thd))
5476 goto error;
5477 my_ok(thd);
5478 break;
5479 case SQLCOM_XA_END:
5480 if (trans_xa_end(thd))
5481 goto error;
5482 my_ok(thd);
5483 break;
5484 case SQLCOM_XA_PREPARE:
5485 if (trans_xa_prepare(thd))
5486 goto error;
5487 my_ok(thd);
5488 break;
5489 case SQLCOM_XA_COMMIT:
5490 if (trans_xa_commit(thd))
5491 goto error;
5492 thd->mdl_context.release_transactional_locks();
5493 /*
5494 We've just done a commit, reset transaction
5495 isolation level and access mode to the session default.
5496 */
5497 thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation;
5498 thd->tx_read_only= thd->variables.tx_read_only;
5499 my_ok(thd);
5500 break;
5501 case SQLCOM_XA_ROLLBACK:
5502 if (trans_xa_rollback(thd))
5503 goto error;
5504 thd->mdl_context.release_transactional_locks();
5505 /*
5506 We've just done a rollback, reset transaction
5507 isolation level and access mode to the session default.
5508 */
5509 thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation;
5510 thd->tx_read_only= thd->variables.tx_read_only;
5511 my_ok(thd);
5512 break;
5513 case SQLCOM_XA_RECOVER:
5514 res= mysql_xa_recover(thd);
5515 break;
5516 case SQLCOM_ALTER_TABLESPACE:
5517 if (check_global_access(thd, CREATE_TABLESPACE_ACL))
5518 break;
5519 if (!(res= mysql_alter_tablespace(thd, lex->alter_tablespace_info)))
5520 my_ok(thd);
5521 break;
5522 case SQLCOM_INSTALL_PLUGIN:
5523 if (! (res= mysql_install_plugin(thd, &thd->lex->comment,
5524 &thd->lex->ident)))
5525 my_ok(thd);
5526 break;
5527 case SQLCOM_UNINSTALL_PLUGIN:
5528 if (! (res= mysql_uninstall_plugin(thd, &thd->lex->comment)))
5529 my_ok(thd);
5530 break;
5531 case SQLCOM_BINLOG_BASE64_EVENT:
5532 {
5533 #ifndef EMBEDDED_LIBRARY
5534 mysql_client_binlog_statement(thd);
5535 #else /* EMBEDDED_LIBRARY */
5536 my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "embedded");
5537 #endif /* EMBEDDED_LIBRARY */
5538 break;
5539 }
5540 case SQLCOM_CREATE_SERVER:
5541 {
5542 if (check_global_access(thd, SUPER_ACL))
5543 goto error;
5544
5545 if (create_server(thd, &thd->lex->server_options))
5546 goto error;
5547
5548 my_ok(thd, 1);
5549 break;
5550 }
5551 case SQLCOM_ALTER_SERVER:
5552 {
5553 if (check_global_access(thd, SUPER_ACL))
5554 goto error;
5555
5556 if (alter_server(thd, &thd->lex->server_options))
5557 goto error;
5558
5559 my_ok(thd, 1);
5560 break;
5561 }
5562 case SQLCOM_DROP_SERVER:
5563 {
5564 if (check_global_access(thd, SUPER_ACL))
5565 goto error;
5566
5567 LEX *lex= thd->lex;
5568 if (drop_server(thd, &lex->server_options, lex->drop_if_exists))
5569 {
5570 /*
5571 drop_server() can fail without reporting an error
5572 due to IF EXISTS clause. In this case, call my_ok().
5573 */
5574 if (thd->is_error() || thd->killed)
5575 goto error;
5576 DBUG_ASSERT(lex->drop_if_exists);
5577 my_ok(thd, 0);
5578 break;
5579 }
5580
5581 my_ok(thd, 1);
5582 break;
5583 }
5584 case SQLCOM_ANALYZE:
5585 case SQLCOM_CHECK:
5586 case SQLCOM_OPTIMIZE:
5587 case SQLCOM_REPAIR:
5588 case SQLCOM_TRUNCATE:
5589 case SQLCOM_ALTER_TABLE:
5590 case SQLCOM_HA_OPEN:
5591 case SQLCOM_HA_READ:
5592 case SQLCOM_HA_CLOSE:
5593 DBUG_ASSERT(first_table == all_tables && first_table != 0);
5594 /* fall through */
5595 case SQLCOM_SIGNAL:
5596 case SQLCOM_RESIGNAL:
5597 case SQLCOM_GET_DIAGNOSTICS:
5598 DBUG_ASSERT(lex->m_sql_cmd != NULL);
5599 res= lex->m_sql_cmd->execute(thd);
5600 break;
5601
5602 #ifndef NO_EMBEDDED_ACCESS_CHECKS
5603 case SQLCOM_ALTER_USER:
5604 if (check_access(thd, UPDATE_ACL, "mysql", NULL, NULL, 1, 1) &&
5605 check_global_access(thd, CREATE_USER_ACL))
5606 break;
5607 /* Conditionally writes to binlog */
5608 if (!(res= mysql_user_password_expire(thd, lex->users_list)))
5609 my_ok(thd);
5610 break;
5611 #endif
5612 default:
5613 #ifndef EMBEDDED_LIBRARY
5614 DBUG_ASSERT(0); /* Impossible */
5615 #endif
5616 my_ok(thd);
5617 break;
5618 }
5619 THD_STAGE_INFO(thd, stage_query_end);
5620
5621 /*
5622 Binlog-related cleanup:
5623 Reset system variables temporarily modified by SET ONE SHOT.
5624
5625 Exception: If this is a SET, do nothing. This is to allow
5626 mysqlbinlog to print many SET commands (in this case we want the
5627 charset temp setting to live until the real query). This is also
5628 needed so that SET CHARACTER_SET_CLIENT... does not cancel itself
5629 immediately.
5630 */
5631 if (thd->one_shot_set && lex->sql_command != SQLCOM_SET_OPTION)
5632 reset_one_shot_variables(thd);
5633
5634 goto finish;
5635
5636 error:
5637 res= TRUE;
5638
5639 finish:
5640
5641 DBUG_ASSERT(!thd->in_active_multi_stmt_transaction() ||
5642 thd->in_multi_stmt_transaction_mode());
5643
5644 if (reset_timer)
5645 reset_statement_timer(thd);
5646
5647 if (per_query_variables_backup) {
5648 DBUG_ASSERT(lex->set_statement);
5649 DBUG_ASSERT(!lex->var_list.is_empty());
5650
5651 List_iterator_fast<set_var_base> it(thd->lex->var_list);
5652 set_var *var;
5653
5654 free_system_variables(&thd->variables, thd->m_enable_plugins);
5655 thd->variables= *per_query_variables_backup;
5656 my_free(per_query_variables_backup);
5657 /*
5658 When variables are restored after "SET STATEMENT ... FOR ..." statement
5659 execution an update callback must be invoked for the system variables
5660 to save special logic if it is. set_var_base class does not contain
5661 refference to variable as it is just an interface class. But only
5662 system variables are allowed to be used in "SET STATEMENT ... FOR ..."
5663 statement, so cast from set_var_base* to set_var* can be used here.
5664 */
5665 while ((var=(set_var *)it++))
5666 {
5667 var->var->stmt_update(thd);
5668 }
5669
5670 thd->lex->set_statement= false;
5671 }
5672
5673 if (! thd->in_sub_stmt)
5674 {
5675 /* report error issued during command execution */
5676 if (thd->killed_errno())
5677 thd->send_kill_message();
5678 if (thd->is_error() || (thd->variables.option_bits & OPTION_MASTER_SQL_ERROR))
5679 trans_rollback_stmt(thd);
5680 else
5681 {
5682 /* If commit fails, we should be able to reset the OK status. */
5683 thd->get_stmt_da()->set_overwrite_status(true);
5684 trans_commit_stmt(thd);
5685 thd->get_stmt_da()->set_overwrite_status(false);
5686 }
5687 if (thd->killed == THD::KILL_QUERY ||
5688 thd->killed == THD::KILL_TIMEOUT ||
5689 thd->killed == THD::KILL_BAD_DATA)
5690 {
5691 thd->killed= THD::NOT_KILLED;
5692 thd->mysys_var->abort= 0;
5693 thd->reset_query_for_display();
5694 }
5695 }
5696
5697 lex->unit.cleanup();
5698 /* Free tables */
5699 THD_STAGE_INFO(thd, stage_closing_tables);
5700 close_thread_tables(thd);
5701
5702 #ifndef DBUG_OFF
5703 if (lex->sql_command != SQLCOM_SET_OPTION && ! thd->in_sub_stmt)
5704 DEBUG_SYNC(thd, "execute_command_after_close_tables");
5705 #endif
5706
5707 if (! thd->in_sub_stmt && thd->transaction_rollback_request)
5708 {
5709 /*
5710 We are not in sub-statement and transaction rollback was requested by
5711 one of storage engines (e.g. due to deadlock). Rollback transaction in
5712 all storage engines including binary log.
5713 */
5714 trans_rollback_implicit(thd);
5715 thd->mdl_context.release_transactional_locks();
5716 }
5717 else if (stmt_causes_implicit_commit(thd, CF_IMPLICIT_COMMIT_END))
5718 {
5719 /* No transaction control allowed in sub-statements. */
5720 DBUG_ASSERT(! thd->in_sub_stmt);
5721 /* If commit fails, we should be able to reset the OK status. */
5722 thd->get_stmt_da()->set_overwrite_status(true);
5723 /* Commit the normal transaction if one is active. */
5724 trans_commit_implicit(thd);
5725 thd->get_stmt_da()->set_overwrite_status(false);
5726 thd->mdl_context.release_transactional_locks();
5727 }
5728 else if (! thd->in_sub_stmt && ! thd->in_multi_stmt_transaction_mode())
5729 {
5730 /*
5731 - If inside a multi-statement transaction,
5732 defer the release of metadata locks until the current
5733 transaction is either committed or rolled back. This prevents
5734 other statements from modifying the table for the entire
5735 duration of this transaction. This provides commit ordering
5736 and guarantees serializability across multiple transactions.
5737 - If in autocommit mode, or outside a transactional context,
5738 automatically release metadata locks of the current statement.
5739 */
5740 thd->mdl_context.release_transactional_locks();
5741 }
5742 else if (! thd->in_sub_stmt)
5743 {
5744 thd->mdl_context.release_statement_locks();
5745 }
5746
5747 DBUG_RETURN(res || thd->is_error());
5748 }
5749
5750 static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
5751 {
5752 LEX *lex= thd->lex;
5753 select_result *result= lex->result;
5754 bool res;
5755 /* assign global limit variable if limit is not given */
5756 {
5757 SELECT_LEX *param= lex->unit.global_parameters;
5758 if (!param->explicit_limit)
5759 param->select_limit=
5760 new Item_int((ulonglong) thd->variables.select_limit);
5761 }
5762 if (!(res= open_normal_and_derived_tables(thd, all_tables, 0)))
5763 {
5764 if (lex->describe)
5765 {
5766 /*
5767 We always use select_send for EXPLAIN, even if it's an EXPLAIN
5768 for SELECT ... INTO OUTFILE: a user application should be able
5769 to prepend EXPLAIN to any query and receive output for it,
5770 even if the query itself redirects the output.
5771 */
5772 if (!(result= new select_send()))
5773 return 1; /* purecov: inspected */
5774 res= explain_query_expression(thd, result);
5775 delete result;
5776 }
5777 else
5778 {
5779 if (!result && !(result= new select_send()))
5780 return 1; /* purecov: inspected */
5781 select_result *save_result= result;
5782 select_result *analyse_result= NULL;
5783 if (lex->proc_analyse)
5784 {
5785 if ((result= analyse_result=
5786 new select_analyse(result, lex->proc_analyse)) == NULL)
5787 return true;
5788 }
5789 res= handle_select(thd, result, 0);
5790 delete analyse_result;
5791 if (save_result != lex->result)
5792 delete save_result;
5793 }
5794 }
5795 DEBUG_SYNC(thd, "after_table_open");
5796 return res;
5797 }
5798
5799
5800 #ifndef NO_EMBEDDED_ACCESS_CHECKS
5801 /**
5802 Check grants for commands which work only with one table.
5803
5804 @param thd Thread handler
5805 @param privilege requested privilege
5806 @param all_tables global table list of query
5807 @param no_errors FALSE/TRUE - report/don't report error to
5808 the client (using my_error() call).
5809
5810 @retval
5811 0 OK
5812 @retval
5813 1 access denied, error is sent to client
5814 */
5815
5816 bool check_single_table_access(THD *thd, ulong privilege,
5817 TABLE_LIST *all_tables, bool no_errors)
5818 {
5819 Security_context * backup_ctx= thd->security_ctx;
5820
5821 /* we need to switch to the saved context (if any) */
5822 if (all_tables->security_ctx)
5823 thd->security_ctx= all_tables->security_ctx;
5824
5825 const char *db_name;
5826 if ((all_tables->view || all_tables->field_translation) &&
5827 !all_tables->schema_table)
5828 db_name= all_tables->view_db.str;
5829 else
5830 db_name= all_tables->db;
5831
5832 if (check_access(thd, privilege, db_name,
5833 &all_tables->grant.privilege,
5834 &all_tables->grant.m_internal,
5835 0, no_errors))
5836 goto deny;
5837
5838 /* Show only 1 table for check_grant */
5839 if (!(all_tables->belong_to_view &&
5840 (thd->lex->sql_command == SQLCOM_SHOW_FIELDS)) &&
5841 check_grant(thd, privilege, all_tables, FALSE, 1, no_errors))
5842 goto deny;
5843
5844 thd->security_ctx= backup_ctx;
5845 return 0;
5846
5847 deny:
5848 thd->security_ctx= backup_ctx;
5849 return 1;
5850 }
5851
5852 /**
5853 Check grants for commands which work only with one table and all other
5854 tables belonging to subselects or implicitly opened tables.
5855
5856 @param thd Thread handler
5857 @param privilege requested privilege
5858 @param all_tables global table list of query
5859
5860 @retval
5861 0 OK
5862 @retval
5863 1 access denied, error is sent to client
5864 */
5865
5866 bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *all_tables)
5867 {
5868 if (check_single_table_access (thd,privilege,all_tables, FALSE))
5869 return 1;
5870
5871 /* Check rights on tables of subselects and implicitly opened tables */
5872 TABLE_LIST *subselects_tables, *view= all_tables->view ? all_tables : 0;
5873 if ((subselects_tables= all_tables->next_global))
5874 {
5875 /*
5876 Access rights asked for the first table of a view should be the same
5877 as for the view
5878 */
5879 if (view && subselects_tables->belong_to_view == view)
5880 {
5881 if (check_single_table_access (thd, privilege, subselects_tables, FALSE))
5882 return 1;
5883 subselects_tables= subselects_tables->next_global;
5884 }
5885 if (subselects_tables &&
5886 (check_table_access(thd, SELECT_ACL, subselects_tables, FALSE,
5887 UINT_MAX, FALSE)))
5888 return 1;
5889 }
5890 return 0;
5891 }
5892
5893
5894 /**
5895 @brief Compare requested privileges with the privileges acquired from the
5896 User- and Db-tables.
5897 @param thd Thread handler
5898 @param want_access The requested access privileges.
5899 @param db A pointer to the Db name.
5900 @param[out] save_priv A pointer to the granted privileges will be stored.
5901 @param grant_internal_info A pointer to the internal grant cache.
5902 @param dont_check_global_grants True if no global grants are checked.
5903 @param no_error True if no errors should be sent to the client.
5904
5905 'save_priv' is used to save the User-table (global) and Db-table grants for
5906 the supplied db name. Note that we don't store db level grants if the global
5907 grants is enough to satisfy the request AND the global grants contains a
5908 SELECT grant.
5909
5910 For internal databases (INFORMATION_SCHEMA, PERFORMANCE_SCHEMA),
5911 additional rules apply, see ACL_internal_schema_access.
5912
5913 @see check_grant
5914
5915 @return Status of denial of access by exclusive ACLs.
5916 @retval FALSE Access can't exclusively be denied by Db- and User-table
5917 access unless Column- and Table-grants are checked too.
5918 @retval TRUE Access denied.
5919 */
5920
5921 bool
5922 check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
5923 GRANT_INTERNAL_INFO *grant_internal_info,
5924 bool dont_check_global_grants, bool no_errors)
5925 {
5926 Security_context *sctx= thd->security_ctx;
5927 ulong db_access;
5928
5929 /*
5930 GRANT command:
5931 In case of database level grant the database name may be a pattern,
5932 in case of table|column level grant the database name can not be a pattern.
5933 We use 'dont_check_global_grants' as a flag to determine
5934 if it's database level grant command
5935 (see SQLCOM_GRANT case, mysql_execute_command() function) and
5936 set db_is_pattern according to 'dont_check_global_grants' value.
5937 */
5938 bool db_is_pattern= ((want_access & GRANT_ACL) && dont_check_global_grants);
5939 ulong dummy;
5940 DBUG_ENTER("check_access");
5941 DBUG_PRINT("enter",("db: %s want_access: %lu master_access: %lu",
5942 db ? db : "", want_access, sctx->master_access));
5943
5944 if (save_priv)
5945 *save_priv=0;
5946 else
5947 {
5948 save_priv= &dummy;
5949 dummy= 0;
5950 }
5951
5952 THD_STAGE_INFO(thd, stage_checking_permissions);
5953 if ((!db || !db[0]) && !thd->db && !dont_check_global_grants)
5954 {
5955 DBUG_PRINT("error",("No database"));
5956 if (!no_errors)
5957 my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR),
5958 MYF(0)); /* purecov: tested */
5959 DBUG_RETURN(TRUE); /* purecov: tested */
5960 }
5961
5962 if ((db != NULL) && (db != any_db))
5963 {
5964 const ACL_internal_schema_access *access;
5965 access= get_cached_schema_access(grant_internal_info, db);
5966 if (access)
5967 {
5968 switch (access->check(want_access, save_priv))
5969 {
5970 case ACL_INTERNAL_ACCESS_GRANTED:
5971 /*
5972 All the privileges requested have been granted internally.
5973 [out] *save_privileges= Internal privileges.
5974 */
5975 DBUG_RETURN(FALSE);
5976 case ACL_INTERNAL_ACCESS_DENIED:
5977 if (! no_errors)
5978 {
5979 thd->diff_access_denied_errors++;
5980 my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
5981 sctx->priv_user, sctx->priv_host, db);
5982 }
5983 DBUG_RETURN(TRUE);
5984 case ACL_INTERNAL_ACCESS_CHECK_GRANT:
5985 /*
5986 Only some of the privilege requested have been granted internally,
5987 proceed with the remaining bits of the request (want_access).
5988 */
5989 want_access&= ~(*save_priv);
5990 break;
5991 }
5992 }
5993 }
5994
5995 if ((sctx->master_access & want_access) == want_access)
5996 {
5997 /*
5998 1. If we don't have a global SELECT privilege, we have to get the
5999 database specific access rights to be able to handle queries of type
6000 UPDATE t1 SET a=1 WHERE b > 0
6001 2. Change db access if it isn't current db which is being addressed
6002 */
6003 if (!(sctx->master_access & SELECT_ACL))
6004 {
6005 if (db && (!thd->db || db_is_pattern || strcmp(db, thd->db)))
6006 db_access= acl_get(sctx->get_host()->ptr(), sctx->get_ip()->ptr(),
6007 sctx->priv_user, db, db_is_pattern);
6008 else
6009 {
6010 /* get access for current db */
6011 db_access= sctx->db_access;
6012 }
6013 /*
6014 The effective privileges are the union of the global privileges
6015 and the intersection of db- and host-privileges,
6016 plus the internal privileges.
6017 */
6018 *save_priv|= sctx->master_access | db_access;
6019 }
6020 else
6021 *save_priv|= sctx->master_access;
6022 DBUG_RETURN(FALSE);
6023 }
6024 if (((want_access & ~sctx->master_access) & ~DB_ACLS) ||
6025 (! db && dont_check_global_grants))
6026 { // We can never grant this
6027 DBUG_PRINT("error",("No possible access"));
6028 if (!no_errors)
6029 {
6030 thd->diff_access_denied_errors++;
6031 if (thd->password == 2)
6032 my_error(ER_ACCESS_DENIED_NO_PASSWORD_ERROR, MYF(0),
6033 sctx->priv_user,
6034 sctx->priv_host);
6035 else
6036 my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
6037 sctx->priv_user,
6038 sctx->priv_host,
6039 (thd->password ?
6040 ER(ER_YES) :
6041 ER(ER_NO))); /* purecov: tested */
6042 }
6043 DBUG_RETURN(TRUE); /* purecov: tested */
6044 }
6045
6046 if (db == any_db)
6047 {
6048 /*
6049 Access granted; Allow select on *any* db.
6050 [out] *save_privileges= 0
6051 */
6052 DBUG_RETURN(FALSE);
6053 }
6054
6055 if (db && (!thd->db || db_is_pattern || strcmp(db,thd->db)))
6056 db_access= acl_get(sctx->get_host()->ptr(), sctx->get_ip()->ptr(),
6057 sctx->priv_user, db, db_is_pattern);
6058 else
6059 db_access= sctx->db_access;
6060 DBUG_PRINT("info",("db_access: %lu want_access: %lu",
6061 db_access, want_access));
6062
6063 /*
6064 Save the union of User-table and the intersection between Db-table and
6065 Host-table privileges, with the already saved internal privileges.
6066 */
6067 db_access= (db_access | sctx->master_access);
6068 *save_priv|= db_access;
6069
6070 /*
6071 We need to investigate column- and table access if all requested privileges
6072 belongs to the bit set of .
6073 */
6074 bool need_table_or_column_check=
6075 (want_access & (TABLE_ACLS | PROC_ACLS | db_access)) == want_access;
6076
6077 /*
6078 Grant access if the requested access is in the intersection of
6079 host- and db-privileges (as retrieved from the acl cache),
6080 also grant access if all the requested privileges are in the union of
6081 TABLES_ACLS and PROC_ACLS; see check_grant.
6082 */
6083 if ( (db_access & want_access) == want_access ||
6084 (!dont_check_global_grants &&
6085 need_table_or_column_check))
6086 {
6087 /*
6088 Ok; but need to check table- and column privileges.
6089 [out] *save_privileges is (User-priv | (Db-priv & Host-priv) | Internal-priv)
6090 */
6091 DBUG_RETURN(FALSE);
6092 }
6093
6094 /*
6095 Access is denied;
6096 [out] *save_privileges is (User-priv | (Db-priv & Host-priv) | Internal-priv)
6097 */
6098 DBUG_PRINT("error",("Access denied"));
6099 if (!no_errors)
6100 my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
6101 sctx->priv_user, sctx->priv_host,
6102 (db ? db : (thd->db ?
6103 thd->db :
6104 "unknown")));
6105 thd->diff_access_denied_errors++;
6106 DBUG_RETURN(TRUE);
6107
6108 }
6109
6110
6111 /**
6112 Check if user has enough privileges for execution of SHOW statement,
6113 which was converted to query to one of I_S tables.
6114
6115 @param thd Thread context.
6116 @param table Table list element for I_S table to be queried..
6117
6118 @retval FALSE - Success.
6119 @retval TRUE - Failure.
6120 */
6121
6122 static bool check_show_access(THD *thd, TABLE_LIST *table)
6123 {
6124 switch (get_schema_table_idx(table->schema_table)) {
6125 case SCH_SCHEMATA:
6126 return (specialflag & SPECIAL_SKIP_SHOW_DB) &&
6127 check_global_access(thd, SHOW_DB_ACL);
6128
6129 case SCH_TABLE_NAMES:
6130 case SCH_TABLES:
6131 case SCH_VIEWS:
6132 case SCH_TRIGGERS:
6133 case SCH_EVENTS:
6134 {
6135 const char *dst_db_name= table->schema_select_lex->db;
6136
6137 DBUG_ASSERT(dst_db_name);
6138
6139 if (check_access(thd, SELECT_ACL, dst_db_name,
6140 &thd->col_access, NULL, FALSE, FALSE))
6141 return TRUE;
6142
6143 if (!thd->col_access && check_grant_db(thd, dst_db_name))
6144 {
6145 thd->diff_access_denied_errors++;
6146 my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
6147 thd->security_ctx->priv_user,
6148 thd->security_ctx->priv_host,
6149 dst_db_name);
6150 return TRUE;
6151 }
6152
6153 return FALSE;
6154 }
6155
6156 case SCH_COLUMNS:
6157 case SCH_STATISTICS:
6158 {
6159 TABLE_LIST *dst_table;
6160 dst_table= table->schema_select_lex->table_list.first;
6161
6162 DBUG_ASSERT(dst_table);
6163
6164 /*
6165 Open temporary tables to be able to detect them during privilege check.
6166 */
6167 if (open_temporary_tables(thd, dst_table))
6168 return TRUE;
6169
6170 if (check_access(thd, SELECT_ACL, dst_table->db,
6171 &dst_table->grant.privilege,
6172 &dst_table->grant.m_internal,
6173 FALSE, FALSE))
6174 return TRUE; /* Access denied */
6175
6176 /*
6177 Check_grant will grant access if there is any column privileges on
6178 all of the tables thanks to the fourth parameter (bool show_table).
6179 */
6180 if (check_grant(thd, SELECT_ACL, dst_table, TRUE, UINT_MAX, FALSE))
6181 return TRUE; /* Access denied */
6182
6183 close_thread_tables(thd);
6184 dst_table->table= NULL;
6185
6186 /* Access granted */
6187 return FALSE;
6188 }
6189 default:
6190 break;
6191 }
6192
6193 return FALSE;
6194 }
6195
6196
6197
6198 /**
6199 @brief Check if the requested privileges exists in either User-, Host- or
6200 Db-tables.
6201 @param thd Thread context
6202 @param want_access Privileges requested
6203 @param tables List of tables to be compared against
6204 @param no_errors Don't report error to the client (using my_error() call).
6205 @param any_combination_of_privileges_will_do TRUE if any privileges on any
6206 column combination is enough.
6207 @param number Only the first 'number' tables in the linked list are
6208 relevant.
6209
6210 The suppled table list contains cached privileges. This functions calls the
6211 help functions check_access and check_grant to verify the first three steps
6212 in the privileges check queue:
6213 1. Global privileges
6214 2. OR (db privileges AND host privileges)
6215 3. OR table privileges
6216 4. OR column privileges (not checked by this function!)
6217 5. OR routine privileges (not checked by this function!)
6218
6219 @see check_access
6220 @see check_grant
6221
6222 @note This functions assumes that table list used and
6223 thd->lex->query_tables_own_last value correspond to each other
6224 (the latter should be either 0 or point to next_global member
6225 of one of elements of this table list).
6226
6227 @return
6228 @retval FALSE OK
6229 @retval TRUE Access denied; But column or routine privileges might need to
6230 be checked also.
6231 */
6232
6233 bool
6234 check_table_access(THD *thd, ulong requirements,TABLE_LIST *tables,
6235 bool any_combination_of_privileges_will_do,
6236 uint number, bool no_errors)
6237 {
6238 TABLE_LIST *org_tables= tables;
6239 TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table();
6240 uint i= 0;
6241 Security_context *sctx= thd->security_ctx, *backup_ctx= thd->security_ctx;
6242 /*
6243 The check that first_not_own_table is not reached is for the case when
6244 the given table list refers to the list for prelocking (contains tables
6245 of other queries). For simple queries first_not_own_table is 0.
6246 */
6247 for (; i < number && tables != first_not_own_table && tables;
6248 tables= tables->next_global, i++)
6249 {
6250 TABLE_LIST *const table_ref= tables->correspondent_table ?
6251 tables->correspondent_table : tables;
6252
6253 ulong want_access= requirements;
6254 if (table_ref->security_ctx)
6255 sctx= table_ref->security_ctx;
6256 else
6257 sctx= backup_ctx;
6258
6259 /*
6260 Register access for view underlying table.
6261 Remove SHOW_VIEW_ACL, because it will be checked during making view
6262 */
6263 table_ref->grant.orig_want_privilege= (want_access & ~SHOW_VIEW_ACL);
6264
6265 /*
6266 We should not encounter table list elements for reformed SHOW
6267 statements unless this is first table list element in the main
6268 select.
6269 Such table list elements require additional privilege check
6270 (see check_show_access()). This check is carried out by caller,
6271 but only for the first table list element from the main select.
6272 */
6273 DBUG_ASSERT(!table_ref->schema_table_reformed ||
6274 table_ref == thd->lex->select_lex.table_list.first);
6275
6276 DBUG_PRINT("info", ("derived: %d view: %d", table_ref->derived != 0,
6277 table_ref->view != 0));
6278
6279 if (table_ref->is_anonymous_derived_table())
6280 continue;
6281
6282 thd->security_ctx= sctx;
6283
6284 if (check_access(thd, want_access, table_ref->get_db_name(),
6285 &table_ref->grant.privilege,
6286 &table_ref->grant.m_internal,
6287 0, no_errors))
6288 goto deny;
6289 }
6290 thd->security_ctx= backup_ctx;
6291 return check_grant(thd,requirements,org_tables,
6292 any_combination_of_privileges_will_do,
6293 number, no_errors);
6294 deny:
6295 thd->security_ctx= backup_ctx;
6296 return TRUE;
6297 }
6298
6299
6300 bool
6301 check_routine_access(THD *thd, ulong want_access,char *db, char *name,
6302 bool is_proc, bool no_errors)
6303 {
6304 TABLE_LIST tables[1];
6305
6306 memset(tables, 0, sizeof(TABLE_LIST));
6307 tables->db= db;
6308 tables->table_name= tables->alias= name;
6309
6310 /*
6311 The following test is just a shortcut for check_access() (to avoid
6312 calculating db_access) under the assumption that it's common to
6313 give persons global right to execute all stored SP (but not
6314 necessary to create them).
6315 Note that this effectively bypasses the ACL_internal_schema_access checks
6316 that are implemented for the INFORMATION_SCHEMA and PERFORMANCE_SCHEMA,
6317 which are located in check_access().
6318 Since the I_S and P_S do not contain routines, this bypass is ok,
6319 as long as this code path is not abused to create routines.
6320 The assert enforce that.
6321 */
6322 DBUG_ASSERT((want_access & CREATE_PROC_ACL) == 0);
6323 if ((thd->security_ctx->master_access & want_access) == want_access)
6324 tables->grant.privilege= want_access;
6325 else if (check_access(thd, want_access, db,
6326 &tables->grant.privilege,
6327 &tables->grant.m_internal,
6328 0, no_errors))
6329 return TRUE;
6330
6331 return check_grant_routine(thd, want_access, tables, is_proc, no_errors);
6332 }
6333
6334
6335 /**
6336 Check if the routine has any of the routine privileges.
6337
6338 @param thd Thread handler
6339 @param db Database name
6340 @param name Routine name
6341
6342 @retval
6343 0 ok
6344 @retval
6345 1 error
6346 */
6347
6348 bool check_some_routine_access(THD *thd, const char *db, const char *name,
6349 bool is_proc)
6350 {
6351 ulong save_priv;
6352 /*
6353 The following test is just a shortcut for check_access() (to avoid
6354 calculating db_access)
6355 Note that this effectively bypasses the ACL_internal_schema_access checks
6356 that are implemented for the INFORMATION_SCHEMA and PERFORMANCE_SCHEMA,
6357 which are located in check_access().
6358 Since the I_S and P_S do not contain routines, this bypass is ok,
6359 as it only opens SHOW_PROC_ACLS.
6360 */
6361 if (thd->security_ctx->master_access & SHOW_PROC_ACLS)
6362 return FALSE;
6363 if (!check_access(thd, SHOW_PROC_ACLS, db, &save_priv, NULL, 0, 1) ||
6364 (save_priv & SHOW_PROC_ACLS))
6365 return FALSE;
6366 return check_routine_level_acl(thd, db, name, is_proc);
6367 }
6368
6369
6370 /**
6371 Check if the given table has any of the asked privileges
6372
6373 @param thd Thread handler
6374 @param want_access Bitmap of possible privileges to check for
6375
6376 @retval
6377 0 ok
6378 @retval
6379 1 error
6380 */
6381
6382 bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table)
6383 {
6384 ulong access;
6385 DBUG_ENTER("check_some_access");
6386
6387 /* This loop will work as long as we have less than 32 privileges */
6388 for (access= 1; access < want_access ; access<<= 1)
6389 {
6390 if (access & want_access)
6391 {
6392 if (!check_access(thd, access, table->db,
6393 &table->grant.privilege,
6394 &table->grant.m_internal,
6395 0, 1) &&
6396 !check_grant(thd, access, table, FALSE, 1, TRUE))
6397 DBUG_RETURN(0);
6398 }
6399 }
6400 DBUG_PRINT("exit",("no matching access rights"));
6401 DBUG_RETURN(1);
6402 }
6403
6404 #else
6405
6406 static bool check_show_access(THD *thd, TABLE_LIST *table)
6407 {
6408 return false;
6409 }
6410
6411 #endif /*NO_EMBEDDED_ACCESS_CHECKS*/
6412
6413
6414 /**
6415 check for global access and give descriptive error message if it fails.
6416
6417 @param thd Thread handler
6418 @param want_access Use should have any of these global rights
6419
6420 @warning
6421 One gets access right if one has ANY of the rights in want_access.
6422 This is useful as one in most cases only need one global right,
6423 but in some case we want to check if the user has SUPER or
6424 REPL_CLIENT_ACL rights.
6425
6426 @retval
6427 0 ok
6428 @retval
6429 1 Access denied. In this case an error is sent to the client
6430 */
6431
6432 bool check_global_access(THD *thd, ulong want_access)
6433 {
6434 DBUG_ENTER("check_global_access");
6435 #ifndef NO_EMBEDDED_ACCESS_CHECKS
6436 char command[128];
6437 if ((thd->security_ctx->master_access & want_access))
6438 DBUG_RETURN(0);
6439 get_privilege_desc(command, sizeof(command), want_access);
6440 thd->diff_access_denied_errors++;
6441 my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command);
6442 DBUG_RETURN(1);
6443 #else
6444 DBUG_RETURN(0);
6445 #endif
6446 }
6447
6448
6449 /**
6450 Checks foreign key's parent table access.
6451
6452 @param thd [in] Thread handler
6453 @param child_table_db [in] Database of child table
6454 @param create_info [in] Create information (like MAX_ROWS, ENGINE or
6455 temporary table flag)
6456 @param alter_info [in] Initial list of columns and indexes for the
6457 table to be created
6458
6459 @retval
6460 false ok.
6461 @retval
6462 true error or access denied. Error is sent to client in this case.
6463 */
6464 bool check_fk_parent_table_access(THD *thd,
6465 const char *child_table_db,
6466 HA_CREATE_INFO *create_info,
6467 Alter_info *alter_info)
6468 {
6469 Key *key;
6470 List_iterator<Key> key_iterator(alter_info->key_list);
6471 handlerton *db_type= create_info->db_type ? create_info->db_type :
6472 ha_default_handlerton(thd);
6473
6474 // Return if engine does not support Foreign key Constraint.
6475 if (!ha_check_storage_engine_flag(db_type, HTON_SUPPORTS_FOREIGN_KEYS))
6476 return false;
6477
6478 while ((key= key_iterator++))
6479 {
6480 if (key->type == Key::FOREIGN_KEY)
6481 {
6482 TABLE_LIST parent_table;
6483 bool is_qualified_table_name;
6484 Foreign_key *fk_key= (Foreign_key *)key;
6485 LEX_STRING db_name;
6486 LEX_STRING table_name= { fk_key->ref_table.str,
6487 fk_key->ref_table.length };
6488 const ulong privileges= (SELECT_ACL | INSERT_ACL | UPDATE_ACL |
6489 DELETE_ACL | REFERENCES_ACL);
6490
6491 // Check if tablename is valid or not.
6492 DBUG_ASSERT(table_name.str != NULL);
6493 if (check_table_name(table_name.str, table_name.length, false))
6494 {
6495 my_error(ER_WRONG_TABLE_NAME, MYF(0), table_name.str);
6496 return true;
6497 }
6498
6499 if (fk_key->ref_db.str)
6500 {
6501 is_qualified_table_name= true;
6502 db_name.str= (char *) thd->memdup(fk_key->ref_db.str,
6503 fk_key->ref_db.length+1);
6504 db_name.length= fk_key->ref_db.length;
6505
6506 // Check if database name is valid or not.
6507 if (fk_key->ref_db.str && check_and_convert_db_name(&db_name, false))
6508 return true;
6509 }
6510 else
6511 {
6512 /*
6513 If database name for parent table is not specified explicitly
6514 SEs assume that it is the same as database name of child table.
6515 We do the same here.
6516 */
6517 is_qualified_table_name= false;
6518 db_name.str= const_cast<char*>(child_table_db);
6519 db_name.length= strlen(child_table_db);
6520 }
6521
6522 // if lower_case_table_names is set then convert tablename to lower case.
6523 if (lower_case_table_names)
6524 {
6525 table_name.str= (char *) thd->memdup(fk_key->ref_table.str,
6526 fk_key->ref_table.length+1);
6527 table_name.length= my_casedn_str(files_charset_info, table_name.str);
6528 }
6529
6530 parent_table.init_one_table(db_name.str, db_name.length,
6531 table_name.str, table_name.length,
6532 table_name.str, TL_IGNORE);
6533
6534 /*
6535 Check if user has any of the "privileges" at table level on
6536 "parent_table".
6537 Having privilege on any of the parent_table column is not
6538 enough so checking whether user has any of the "privileges"
6539 at table level only here.
6540 */
6541 if (check_some_access(thd, privileges, &parent_table) ||
6542 parent_table.grant.want_privilege)
6543 {
6544 if (is_qualified_table_name)
6545 {
6546 const size_t qualified_table_name_len= NAME_LEN + 1 + NAME_LEN + 1;
6547 char *qualified_table_name= (char *) thd->alloc(qualified_table_name_len);
6548
6549 my_snprintf(qualified_table_name, qualified_table_name_len, "%s.%s",
6550 db_name.str, table_name.str);
6551 table_name.str= qualified_table_name;
6552 }
6553
6554 my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
6555 "REFERENCES",
6556 thd->security_ctx->priv_user,
6557 thd->security_ctx->host_or_ip,
6558 table_name.str);
6559
6560 return true;
6561 }
6562 }
6563 }
6564
6565 return false;
6566 }
6567
6568
6569 /**
6570 For LOCK TABLES on a view checks if user in which context view is executed
6571 or user that has initiated this operation has SELECT and LOCK TABLES
6572 privileges on one of its underlying tables.
6573
6574 @param [in] thd Thread context.
6575 @param [in] tbl Table list element for underlying table
6576 on which we check privilege.
6577 @param [out] fake_lock_tables_acl Set to true if table in question is one
6578 of special I_S or P_S tables on which
6579 nobody can get LOCK TABLES privilege.
6580 So to preserve compatibility with dump
6581 tools we need to fake this privilege.
6582 Set to false otherwise.
6583
6584 @retval false Success.
6585 @retval true Access denied. Error has been reported.
6586 */
6587 bool check_lock_view_underlying_table_access(THD *thd, TABLE_LIST *tbl,
6588 bool *fake_lock_tables_acl)
6589 {
6590 ulong want_access= SELECT_ACL | LOCK_TABLES_ACL;
6591 *fake_lock_tables_acl= false;
6592
6593 /*
6594 I_S and P_S tables require special handling of LOCK TABLES privilege
6595 in this case.
6596 On the one hand we don't grant this privileges on I_S and read-only/
6597 truncatable-only P_S tables to anyone. So normally you can't lock
6598 them directly using LOCK TABLES.
6599 On the other hand we allow creation of views which reference these
6600 tables. And mysqldump/pump tools routinely lock views using LOCK
6601 TABLES just to dump their definition in default mode. So refusing
6602 locking of such views will break mysqldump/pump. It will also break
6603 user scenarios in when views on top of I_S/P_S tables are locked along
6604 with other tables by LOCK TABLES, so they are accessible under LOCK
6605 TABLES mode. So we simply skip LOCK TABLES privilege check for I_S and
6606 read-only/ truncatable-only P_S tables. However, we report the fact to
6607 the caller, so it won't acquire write THR_LOCK lock in this case,
6608 which can be considered privilege escalation.
6609 */
6610 const ACL_internal_schema_access *schema_access=
6611 get_cached_schema_access(&tbl->grant.m_internal, tbl->db);
6612 if (schema_access)
6613 {
6614 ulong dummy= 0;
6615 switch (schema_access->check(LOCK_TABLES_ACL, &dummy))
6616 {
6617 case ACL_INTERNAL_ACCESS_DENIED:
6618 *fake_lock_tables_acl= true;
6619 // Fall through.
6620 case ACL_INTERNAL_ACCESS_GRANTED:
6621 want_access&= ~LOCK_TABLES_ACL;
6622 break;
6623 case ACL_INTERNAL_ACCESS_CHECK_GRANT:
6624 const ACL_internal_table_access *table_access= get_cached_table_access(
6625 &tbl->grant.m_internal, tbl->db, tbl->table_name);
6626 if (table_access)
6627 {
6628 switch (table_access->check(LOCK_TABLES_ACL, &dummy))
6629 {
6630 case ACL_INTERNAL_ACCESS_DENIED:
6631 *fake_lock_tables_acl= true;
6632 // Fall through.
6633 case ACL_INTERNAL_ACCESS_GRANTED:
6634 want_access&= ~LOCK_TABLES_ACL;
6635 break;
6636 case ACL_INTERNAL_ACCESS_CHECK_GRANT:
6637 break;
6638 }
6639 }
6640 break;
6641 }
6642 }
6643
6644 if (!check_single_table_access(thd, want_access, tbl, true))
6645 return false;
6646
6647 /*
6648 As it was mentioned earlier mysqldump/pump tools routinely lock
6649 views just to dump their definition. This is supposed to work even
6650 for views with (temporarily) invalid definer. To avoid breaking
6651 this scenario we allow locking of view not only when user which
6652 security context will be used for its execution has LOCK TABLES
6653 and SELECT privileges on its underlying tbales, but also when
6654 the user which originally requested LOCK TABLES has the similar
6655 privileges on its underlying tables (which is likely to be the
6656 case for users invoking mysqldump/pump).
6657 */
6658 Security_context *save_security_ctx= tbl->security_ctx;
6659 tbl->security_ctx= NULL;
6660 bool top_user_has_privs=
6661 !check_single_table_access(thd, want_access, tbl, true);
6662 tbl->security_ctx= save_security_ctx;
6663
6664 if (top_user_has_privs)
6665 return false;
6666
6667 my_error(ER_VIEW_INVALID, MYF(0), tbl->belong_to_view->get_db_name(),
6668 tbl->belong_to_view->get_table_name());
6669 return true;
6670 }
6671
6672
6673 /****************************************************************************
6674 Check stack size; Send error if there isn't enough stack to continue
6675 ****************************************************************************/
6676
6677
6678 #if STACK_DIRECTION < 0
6679 #define used_stack(A,B) (long) (A - B)
6680 #else
6681 #define used_stack(A,B) (long) (B - A)
6682 #endif
6683
6684 #ifndef DBUG_OFF
6685 long max_stack_used;
6686 #endif
6687
6688 /**
6689 @note
6690 Note: The 'buf' parameter is necessary, even if it is unused here.
6691 - fix_fields functions has a "dummy" buffer large enough for the
6692 corresponding exec. (Thus we only have to check in fix_fields.)
6693 - Passing to check_stack_overrun() prevents the compiler from removing it.
6694 */
6695 bool check_stack_overrun(THD *thd, long margin,
6696 uchar *buf MY_ATTRIBUTE((unused)))
6697 {
6698 long stack_used;
6699 DBUG_ASSERT(thd == current_thd);
6700 if ((stack_used=used_stack(thd->thread_stack,(char*) &stack_used)) >=
6701 (long) (my_thread_stack_size - margin))
6702 {
6703 /*
6704 Do not use stack for the message buffer to ensure correct
6705 behaviour in cases we have close to no stack left.
6706 */
6707 char* ebuff= new (std::nothrow) char[MYSQL_ERRMSG_SIZE];
6708 if (ebuff) {
6709 my_snprintf(ebuff, MYSQL_ERRMSG_SIZE, ER(ER_STACK_OVERRUN_NEED_MORE),
6710 stack_used, my_thread_stack_size, margin);
6711 my_message(ER_STACK_OVERRUN_NEED_MORE, ebuff, MYF(ME_FATALERROR));
6712 delete [] ebuff;
6713 }
6714 return 1;
6715 }
6716 #ifndef DBUG_OFF
6717 max_stack_used= max(max_stack_used, stack_used);
6718 #endif
6719 return 0;
6720 }
6721
6722
6723 #define MY_YACC_INIT 1000 // Start with big alloc
6724 #define MY_YACC_MAX 32000 // Because of 'short'
6725
6726 bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, ulong *yystacksize)
6727 {
6728 Yacc_state *state= & current_thd->m_parser_state->m_yacc;
6729 ulong old_info=0;
6730 DBUG_ASSERT(state);
6731 if ((uint) *yystacksize >= MY_YACC_MAX)
6732 return 1;
6733 if (!state->yacc_yyvs)
6734 old_info= *yystacksize;
6735 *yystacksize= set_zone((*yystacksize)*2,MY_YACC_INIT,MY_YACC_MAX);
6736 if (!(state->yacc_yyvs= (uchar*)
6737 my_realloc(state->yacc_yyvs,
6738 *yystacksize*sizeof(**yyvs),
6739 MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))) ||
6740 !(state->yacc_yyss= (uchar*)
6741 my_realloc(state->yacc_yyss,
6742 *yystacksize*sizeof(**yyss),
6743 MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))))
6744 return 1;
6745 if (old_info)
6746 {
6747 /*
6748 Only copy the old stack on the first call to my_yyoverflow(),
6749 when replacing a static stack (YYINITDEPTH) by a dynamic stack.
6750 For subsequent calls, my_realloc already did preserve the old stack.
6751 */
6752 memcpy(state->yacc_yyss, *yyss, old_info*sizeof(**yyss));
6753 memcpy(state->yacc_yyvs, *yyvs, old_info*sizeof(**yyvs));
6754 }
6755 *yyss= (short*) state->yacc_yyss;
6756 *yyvs= (YYSTYPE*) state->yacc_yyvs;
6757 return 0;
6758 }
6759
6760
6761 /**
6762 Reset the part of THD responsible for the state of command
6763 processing.
6764
6765 This needs to be called before execution of every statement
6766 (prepared or conventional). It is not called by substatements of
6767 routines.
6768
6769 @todo Remove mysql_reset_thd_for_next_command and only use the
6770 member function.
6771
6772 @todo Call it after we use THD for queries, not before.
6773 */
6774 void mysql_reset_thd_for_next_command(THD *thd)
6775 {
6776 thd->reset_for_next_command();
6777 }
6778
6779 void THD::reset_for_next_command()
6780 {
6781 // TODO: Why on earth is this here?! We should probably fix this
6782 // function and move it to the proper file. /Matz
6783 THD *thd= this;
6784 DBUG_ENTER("mysql_reset_thd_for_next_command");
6785 DBUG_ASSERT(!thd->sp_runtime_ctx); /* not for substatements of routines */
6786 DBUG_ASSERT(! thd->in_sub_stmt);
6787 DBUG_ASSERT(!thd->query_cache_tls.first_query_block);
6788 thd->free_list= 0;
6789 thd->select_number= 1;
6790 /*
6791 Those two lines below are theoretically unneeded as
6792 THD::cleanup_after_query() should take care of this already.
6793 */
6794 thd->auto_inc_intervals_in_cur_stmt_for_binlog.empty();
6795 thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
6796
6797 thd->query_start_used= thd->query_start_usec_used= 0;
6798 thd->is_fatal_error= thd->time_zone_used= 0;
6799 /*
6800 Clear the status flag that are expected to be cleared at the
6801 beginning of each SQL statement.
6802 */
6803 thd->server_status&= ~SERVER_STATUS_CLEAR_SET;
6804 /*
6805 If in autocommit mode and not in a transaction, reset flag
6806 that identifies if a transaction has done some operations
6807 that cannot be safely rolled back.
6808
6809 If the flag is set an warning message is printed out in
6810 ha_rollback_trans() saying that some tables couldn't be
6811 rolled back.
6812 */
6813 if (!thd->in_multi_stmt_transaction_mode())
6814 {
6815 thd->transaction.all.reset_unsafe_rollback_flags();
6816 }
6817 DBUG_ASSERT(thd->security_ctx== &thd->main_security_ctx);
6818 thd->thread_specific_used= FALSE;
6819
6820 if (opt_bin_log)
6821 {
6822 reset_dynamic(&thd->user_var_events);
6823 thd->user_var_events_alloc= thd->mem_root;
6824 }
6825 thd->clear_error();
6826 thd->get_stmt_da()->reset_diagnostics_area();
6827 thd->get_stmt_da()->reset_for_next_command();
6828 thd->rand_used= 0;
6829
6830 thd->clear_slow_extended();
6831
6832 thd->reset_current_stmt_binlog_format_row();
6833 thd->binlog_unsafe_warning_flags= 0;
6834
6835 thd->commit_error= THD::CE_NONE;
6836 thd->durability_property= HA_REGULAR_DURABILITY;
6837 thd->set_trans_pos(NULL, 0);
6838
6839 DBUG_PRINT("debug",
6840 ("is_current_stmt_binlog_format_row(): %d",
6841 thd->is_current_stmt_binlog_format_row()));
6842
6843 DBUG_VOID_RETURN;
6844 }
6845
6846
6847 /**
6848 Resets the lex->current_select object.
6849 @note It is assumed that lex->current_select != NULL
6850
6851 This function is a wrapper around select_lex->init_select() with an added
6852 check for the special situation when using INTO OUTFILE and LOAD DATA.
6853 */
6854
6855 void
6856 mysql_init_select(LEX *lex)
6857 {
6858 SELECT_LEX *select_lex= lex->current_select;
6859 select_lex->init_select();
6860 lex->wild= 0;
6861 if (select_lex == &lex->select_lex)
6862 {
6863 DBUG_ASSERT(lex->result == 0);
6864 lex->exchange= 0;
6865 }
6866 }
6867
6868
6869 /**
6870 Used to allocate a new SELECT_LEX object on the current thd mem_root and
6871 link it into the relevant lists.
6872
6873 This function is always followed by mysql_init_select.
6874
6875 @see mysql_init_select
6876
6877 @retval TRUE An error occurred
6878 @retval FALSE The new SELECT_LEX was successfully allocated.
6879 */
6880
6881 bool
6882 mysql_new_select(LEX *lex, bool move_down)
6883 {
6884 SELECT_LEX *select_lex;
6885 THD *thd= lex->thd;
6886 Name_resolution_context *outer_context= lex->current_context();
6887 DBUG_ENTER("mysql_new_select");
6888
6889 if (!(select_lex= new (thd->mem_root) SELECT_LEX()))
6890 DBUG_RETURN(1);
6891 select_lex->select_number= ++thd->select_number;
6892 select_lex->parent_lex= lex; /* Used in init_query. */
6893 select_lex->init_query();
6894 select_lex->init_select();
6895 lex->nest_level++;
6896 if (lex->nest_level > (int) MAX_SELECT_NESTING)
6897 {
6898 my_error(ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT, MYF(0));
6899 DBUG_RETURN(1);
6900 }
6901 select_lex->nest_level= lex->nest_level;
6902 if (move_down)
6903 {
6904 SELECT_LEX_UNIT *unit;
6905 lex->subqueries= TRUE;
6906 /* first select_lex of subselect or derived table */
6907 if (!(unit= new (thd->mem_root) SELECT_LEX_UNIT()))
6908 DBUG_RETURN(1);
6909
6910 unit->init_query();
6911 unit->init_select();
6912 unit->thd= thd;
6913 unit->include_down(lex->current_select);
6914 unit->link_next= 0;
6915 unit->link_prev= 0;
6916 select_lex->include_down(unit);
6917 /*
6918 By default we assume that it is usual subselect and we have outer name
6919 resolution context, if no we will assign it to 0 later
6920 */
6921 if (select_lex->outer_select()->parsing_place == IN_ON)
6922 /*
6923 This subquery is part of an ON clause, so we need to link the
6924 name resolution context for this subquery with the ON context.
6925
6926 @todo outer_context is not the same as
6927 &select_lex->outer_select()->context in one case:
6928 (SELECT 1 as a) UNION (SELECT 2) ORDER BY (SELECT a);
6929 When we create the select_lex for the subquery in ORDER BY,
6930 1) outer_context is the context of the second SELECT of the
6931 UNION
6932 2) &select_lex->outer_select() is the fake select_lex, which context
6933 is the one of the first SELECT of the UNION (see
6934 st_select_lex_unit::add_fake_select_lex()).
6935 2) is the correct context, per the documentation. 1) is not, and using
6936 it leads to a resolving error for the query above.
6937 We should fix 1) and then use it unconditionally here.
6938 */
6939 select_lex->context.outer_context= outer_context;
6940 else
6941 select_lex->context.outer_context= &select_lex->outer_select()->context;
6942 }
6943 else
6944 {
6945 if (lex->current_select->order_list.first && !lex->current_select->braces)
6946 {
6947 my_error(ER_WRONG_USAGE, MYF(0), "UNION", "ORDER BY");
6948 DBUG_RETURN(1);
6949 }
6950 select_lex->include_neighbour(lex->current_select);
6951 SELECT_LEX_UNIT *unit= select_lex->master_unit();
6952 if (!unit->fake_select_lex && unit->add_fake_select_lex(lex->thd))
6953 DBUG_RETURN(1);
6954 select_lex->context.outer_context=
6955 unit->first_select()->context.outer_context;
6956 }
6957
6958 select_lex->master_unit()->global_parameters= select_lex;
6959 select_lex->include_global((st_select_lex_node**)&lex->all_selects_list);
6960 lex->current_select= select_lex;
6961 /*
6962 in subquery is SELECT query and we allow resolution of names in SELECT
6963 list
6964 */
6965 select_lex->context.resolve_in_select_list= TRUE;
6966 DBUG_RETURN(0);
6967 }
6968
6969 /**
6970 Create a select to return the same output as 'SELECT @@var_name'.
6971
6972 Used for SHOW COUNT(*) [ WARNINGS | ERROR].
6973
6974 This will crash with a core dump if the variable doesn't exists.
6975
6976 @param var_name Variable name
6977 */
6978
6979 void create_select_for_variable(const char *var_name)
6980 {
6981 THD *thd;
6982 LEX *lex;
6983 LEX_STRING tmp, null_lex_string;
6984 Item *var;
6985 char buff[MAX_SYS_VAR_LENGTH*2+4+8], *end;
6986 DBUG_ENTER("create_select_for_variable");
6987
6988 thd= current_thd;
6989 lex= thd->lex;
6990 mysql_init_select(lex);
6991 lex->sql_command= SQLCOM_SELECT;
6992 tmp.str= (char*) var_name;
6993 tmp.length=strlen(var_name);
6994 memset(&null_lex_string, 0, sizeof(null_lex_string));
6995 /*
6996 We set the name of Item to @@session.var_name because that then is used
6997 as the column name in the output.
6998 */
6999 if ((var= get_system_var(thd, OPT_SESSION, tmp, null_lex_string)))
7000 {
7001 end= strxmov(buff, "@@session.", var_name, NullS);
7002 var->item_name.copy(buff, end - buff);
7003 add_item_to_list(thd, var);
7004 }
7005 DBUG_VOID_RETURN;
7006 }
7007
7008
7009 void mysql_init_multi_delete(LEX *lex)
7010 {
7011 lex->sql_command= SQLCOM_DELETE_MULTI;
7012 mysql_init_select(lex);
7013 lex->select_lex.select_limit= 0;
7014 lex->unit.select_limit_cnt= HA_POS_ERROR;
7015 lex->select_lex.table_list.save_and_clear(&lex->auxiliary_table_list);
7016 lex->query_tables= 0;
7017 lex->query_tables_last= &lex->query_tables;
7018 }
7019
7020
7021 /*
7022 When you modify mysql_parse(), you may need to mofify
7023 mysql_test_parse_for_slave() in this same file.
7024 */
7025
7026 /**
7027 Parse a query.
7028
7029 @param thd Current thread
7030 @param rawbuf Begining of the query text
7031 @param length Length of the query text
7032 @param[out] found_semicolon For multi queries, position of the character of
7033 the next query in the query text.
7034 */
7035
7036 void mysql_parse(THD *thd, char *rawbuf, uint length,
7037 Parser_state *parser_state, bool update_userstat)
7038 {
7039 int error MY_ATTRIBUTE((unused));
7040 DBUG_ENTER("mysql_parse");
7041
7042 DBUG_EXECUTE_IF("parser_debug", turn_parser_debug_on(););
7043
7044 /*
7045 Warning.
7046 The purpose of query_cache_send_result_to_client() is to lookup the
7047 query in the query cache first, to avoid parsing and executing it.
7048 So, the natural implementation would be to:
7049 - first, call query_cache_send_result_to_client,
7050 - second, if caching failed, initialise the lexical and syntactic parser.
7051 The problem is that the query cache depends on a clean initialization
7052 of (among others) lex->safe_to_cache_query and thd->server_status,
7053 which are reset respectively in
7054 - lex_start()
7055 - mysql_reset_thd_for_next_command()
7056 So, initializing the lexical analyser *before* using the query cache
7057 is required for the cache to work properly.
7058 FIXME: cleanup the dependencies in the code to simplify this.
7059 */
7060 lex_start(thd);
7061 mysql_reset_thd_for_next_command(thd);
7062
7063 /* Declare userstat variables and start timer */
7064 double start_busy_usecs = 0.0;
7065 double start_cpu_nsecs = 0.0;
7066 if (unlikely(opt_userstat && update_userstat))
7067 userstat_start_timer(&start_busy_usecs, &start_cpu_nsecs);
7068
7069 if (query_cache_send_result_to_client(thd, rawbuf, length) <= 0)
7070 {
7071 LEX *lex= thd->lex;
7072
7073 bool err= parse_sql(thd, parser_state, NULL);
7074
7075 const char *found_semicolon= parser_state->m_lip.found_semicolon;
7076 size_t qlen= found_semicolon
7077 ? (found_semicolon - thd->query())
7078 : thd->query_length();
7079
7080 if (!err)
7081 {
7082 /*
7083 Rewrite the query for logging and for the Performance Schema statement
7084 tables. Raw logging happened earlier.
7085
7086 Query-cache only handles SELECT, which we don't rewrite, so it's no
7087 concern of ours.
7088
7089 Sub-routines of mysql_rewrite_query() should try to only rewrite when
7090 necessary (e.g. not do password obfuscation when query contains no
7091 password).
7092
7093 If rewriting does not happen here, thd->rewritten_query is still empty
7094 from being reset in alloc_query().
7095 */
7096 mysql_rewrite_query(thd);
7097
7098 if (thd->rewritten_query.length())
7099 {
7100 lex->safe_to_cache_query= false; // see comments below
7101
7102 thd->set_query_for_display(thd->rewritten_query.c_ptr_safe(),
7103 thd->rewritten_query.length());
7104 } else if (thd->slave_thread) {
7105 /*
7106 In the slave, we add the information to pfs.events_statements_history,
7107 but not to pfs.threads, as that is what the test suite expects.
7108 */
7109 MYSQL_SET_STATEMENT_TEXT(thd->m_statement_psi,
7110 thd->query(),
7111 thd->query_length());
7112 } else {
7113 thd->set_query_for_display(thd->query(), thd->query_length());
7114 }
7115
7116 if (!(opt_log_raw || thd->slave_thread))
7117 {
7118 if (thd->rewritten_query.length())
7119 general_log_write(thd, COM_QUERY, thd->rewritten_query.c_ptr_safe(),
7120 thd->rewritten_query.length());
7121 else
7122 general_log_write(thd, COM_QUERY, thd->query(), qlen);
7123 }
7124 }
7125
7126 if (!err)
7127 {
7128 thd->m_statement_psi= MYSQL_REFINE_STATEMENT(thd->m_statement_psi,
7129 sql_statement_info[thd->lex->sql_command].m_key);
7130
7131 #ifndef NO_EMBEDDED_ACCESS_CHECKS
7132 if (mqh_used && thd->get_user_connect() &&
7133 check_mqh(thd, lex->sql_command))
7134 {
7135 thd->net.error = 0;
7136 }
7137 else
7138 #endif
7139 {
7140 if (! thd->is_error())
7141 {
7142 /*
7143 Binlog logs a string starting from thd->query and having length
7144 thd->query_length; so we set thd->query_length correctly (to not
7145 log several statements in one event, when we executed only first).
7146 We set it to not see the ';' (otherwise it would get into binlog
7147 and Query_log_event::print() would give ';;' output).
7148 This also helps display only the current query in SHOW
7149 PROCESSLIST.
7150 Note that we don't need LOCK_thread_count to modify query_length.
7151 */
7152 if (found_semicolon && (ulong) (found_semicolon - thd->query()))
7153 thd->set_query_inner(thd->query(),
7154 (uint32) (found_semicolon -
7155 thd->query() - 1),
7156 thd->charset());
7157 /* Actually execute the query */
7158 if (found_semicolon)
7159 {
7160 lex->safe_to_cache_query= 0;
7161 thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
7162 }
7163 lex->set_trg_event_type_for_tables();
7164 MYSQL_QUERY_EXEC_START(thd->query(),
7165 thd->thread_id,
7166 (char *) (thd->db ? thd->db : ""),
7167 &thd->security_ctx->priv_user[0],
7168 (char *) thd->security_ctx->host_or_ip,
7169 0);
7170 if (unlikely(thd->security_ctx->password_expired &&
7171 !lex->is_change_password &&
7172 lex->sql_command != SQLCOM_SET_OPTION))
7173 {
7174 my_error(ER_MUST_CHANGE_PASSWORD, MYF(0));
7175 error= 1;
7176 }
7177 else
7178 error= mysql_execute_command(thd);
7179 if (error == 0 &&
7180 thd->variables.gtid_next.type == GTID_GROUP &&
7181 thd->owned_gtid.sidno != 0 &&
7182 (thd->lex->sql_command == SQLCOM_COMMIT ||
7183 stmt_causes_implicit_commit(thd, CF_IMPLICIT_COMMIT_END) ||
7184 thd->lex->sql_command == SQLCOM_CREATE_TABLE ||
7185 thd->lex->sql_command == SQLCOM_DROP_TABLE))
7186 {
7187 /*
7188 This ensures that an empty transaction is logged if
7189 needed. It is executed at the end of an implicitly or
7190 explicitly committing statement, or after CREATE
7191 TEMPORARY TABLE or DROP TEMPORARY TABLE.
7192
7193 CREATE/DROP TEMPORARY do not count as implicitly
7194 committing according to stmt_causes_implicit_commit(),
7195 but are written to the binary log as DDL (not between
7196 BEGIN/COMMIT). Thus we need special cases for these
7197 statements in the condition above. Hence the clauses for
7198 for SQLCOM_CREATE_TABLE and SQLCOM_DROP_TABLE above.
7199
7200 Thus, for base tables, SQLCOM_[CREATE|DROP]_TABLE match
7201 both the stmt_causes_implicit_commit clause and the
7202 thd->lex->sql_command == SQLCOM_* clause; for temporary
7203 tables they match only thd->lex->sql_command ==
7204 SQLCOM_*.
7205 */
7206 error= gtid_empty_group_log_and_cleanup(thd);
7207 }
7208 MYSQL_QUERY_EXEC_DONE(error);
7209 }
7210 }
7211 }
7212 else
7213 {
7214 /*
7215 Log the failed raw query in the Performance Schema. This statement did not
7216 parse, so there is no way to tell if it may contain a password of not.
7217
7218 The tradeoff is:
7219 a) If we do log the query, a user typing by accident a broken query
7220 containing a password will have the password exposed. This is very
7221 unlikely, and this behavior can be documented. Remediation is to use
7222 a new password when retyping the corrected query.
7223
7224 b) If we do not log the query, finding broken queries in the client
7225 application will be much more difficult. This is much more likely.
7226
7227 Considering that broken queries can typically be generated by attempts at
7228 SQL injection, finding the source of the SQL injection is critical, so the
7229 design choice is to log the query text of broken queries (a).
7230 */
7231 thd->set_query_for_display(thd->query(), thd->query_length());
7232
7233 /* Instrument this broken statement as "statement/sql/error" */
7234 thd->m_statement_psi= MYSQL_REFINE_STATEMENT(thd->m_statement_psi,
7235 sql_statement_info[SQLCOM_END].m_key);
7236
7237 DBUG_ASSERT(thd->is_error());
7238 DBUG_PRINT("info",("Command aborted. Fatal_error: %d",
7239 thd->is_fatal_error));
7240
7241 query_cache_abort(&thd->query_cache_tls);
7242 }
7243
7244 THD_STAGE_INFO(thd, stage_freeing_items);
7245 sp_cache_enforce_limit(thd->sp_proc_cache, stored_program_cache_size);
7246 sp_cache_enforce_limit(thd->sp_func_cache, stored_program_cache_size);
7247 thd->end_statement();
7248 thd->cleanup_after_query();
7249 DBUG_ASSERT(thd->change_list.is_empty());
7250 }
7251 else
7252 {
7253 /*
7254 Query cache hit. We need to write the general log here if
7255 we haven't already logged the statement earlier due to --log-raw.
7256 Right now, we only cache SELECT results; if the cache ever
7257 becomes more generic, we should also cache the rewritten
7258 query-string together with the original query-string (which
7259 we'd still use for the matching) when we first execute the
7260 query, and then use the obfuscated query-string for logging
7261 here when the query is given again.
7262 */
7263 thd->m_statement_psi= MYSQL_REFINE_STATEMENT(thd->m_statement_psi,
7264 sql_statement_info[SQLCOM_SELECT].m_key);
7265 if (!opt_log_raw)
7266 general_log_write(thd, COM_QUERY, thd->query(), thd->query_length());
7267 parser_state->m_lip.found_semicolon= NULL;
7268 }
7269
7270 /* Update user statistics only if at least one timer was initialized */
7271 if (unlikely(update_userstat &&
7272 (start_busy_usecs > 0.0 || start_cpu_nsecs > 0.0)))
7273 {
7274 userstat_finish_timer(start_busy_usecs, start_cpu_nsecs, &thd->busy_time,
7275 &thd->cpu_time);
7276 /* Updates THD stats and the global user stats. */
7277 thd->update_stats(true);
7278 #ifndef EMBEDDED_LIBRARY
7279 update_global_user_stats(thd, true, time(NULL));
7280 #endif
7281 }
7282
7283 DEBUG_SYNC(thd, "query_rewritten");
7284
7285 DBUG_VOID_RETURN;
7286 }
7287
7288
7289 #ifdef HAVE_REPLICATION
7290 /**
7291 Usable by the replication SQL thread only: just parse a query to know if it
7292 can be ignored because of replicate-*-table rules.
7293
7294 @retval
7295 0 cannot be ignored
7296 @retval
7297 1 can be ignored
7298 */
7299
7300 bool mysql_test_parse_for_slave(THD *thd, char *rawbuf, uint length)
7301 {
7302 LEX *lex= thd->lex;
7303 bool ignorable= false;
7304 sql_digest_state *parent_digest= thd->m_digest;
7305 PSI_statement_locker *parent_locker= thd->m_statement_psi;
7306 DBUG_ENTER("mysql_test_parse_for_slave");
7307
7308 DBUG_ASSERT(thd->slave_thread);
7309
7310 Parser_state parser_state;
7311 if (parser_state.init(thd, rawbuf, length) == 0)
7312 {
7313 lex_start(thd);
7314 mysql_reset_thd_for_next_command(thd);
7315
7316 thd->m_digest= NULL;
7317 thd->m_statement_psi= NULL;
7318 if (parse_sql(thd, & parser_state, NULL) == 0)
7319 {
7320 if (all_tables_not_ok(thd, lex->select_lex.table_list.first))
7321 ignorable= true;
7322 else if (!check_database_filters(thd, thd->db, lex->sql_command))
7323 ignorable= true;
7324 }
7325 thd->m_digest= parent_digest;
7326 thd->m_statement_psi= parent_locker;
7327 thd->end_statement();
7328 }
7329 thd->cleanup_after_query();
7330 DBUG_RETURN(ignorable);
7331 }
7332 #endif
7333
7334
7335
7336 /**
7337 Store field definition for create.
7338
7339 @return
7340 Return 0 if ok
7341 */
7342
7343 bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type,
7344 char *length, char *decimals,
7345 uint type_modifier,
7346 Item *default_value, Item *on_update_value,
7347 LEX_STRING *comment,
7348 char *change,
7349 List<String> *interval_list, const CHARSET_INFO *cs,
7350 uint uint_geom_type, const LEX_CSTRING *zip_dict)
7351 {
7352 Create_field *new_field;
7353 LEX *lex= thd->lex;
7354 uint8 datetime_precision= decimals ? atoi(decimals) : 0;
7355 DBUG_ENTER("add_field_to_list");
7356
7357 if (check_string_char_length(field_name, "", NAME_CHAR_LEN,
7358 system_charset_info, 1))
7359 {
7360 my_error(ER_TOO_LONG_IDENT, MYF(0), field_name->str); /* purecov: inspected */
7361 DBUG_RETURN(1); /* purecov: inspected */
7362 }
7363 if (type_modifier & PRI_KEY_FLAG)
7364 {
7365 Key *key;
7366 lex->col_list.push_back(new Key_part_spec(*field_name, 0));
7367 key= new Key(Key::PRIMARY, null_lex_str,
7368 &default_key_create_info,
7369 0, lex->col_list);
7370 lex->alter_info.key_list.push_back(key);
7371 lex->col_list.empty();
7372 }
7373 if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG | CLUSTERING_FLAG))
7374 {
7375 Key::Keytype keytype;
7376 if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG))
7377 keytype= Key::UNIQUE;
7378 else
7379 keytype= Key::MULTIPLE;
7380 if (type_modifier & CLUSTERING_FLAG)
7381 keytype= (enum Key::Keytype)(keytype | Key::CLUSTERING);
7382 DBUG_ASSERT(keytype != Key::MULTIPLE);
7383
7384 lex->col_list.push_back(new Key_part_spec(*field_name, 0));
7385 Key *key= new Key(keytype, null_lex_str, &default_key_create_info, 0,
7386 lex->col_list);
7387 lex->alter_info.key_list.push_back(key);
7388 lex->col_list.empty();
7389 }
7390
7391 if (default_value)
7392 {
7393 /*
7394 Default value should be literal => basic constants =>
7395 no need fix_fields()
7396
7397 We allow only CURRENT_TIMESTAMP as function default for the TIMESTAMP or
7398 DATETIME types.
7399 */
7400 if (default_value->type() == Item::FUNC_ITEM &&
7401 (static_cast<Item_func*>(default_value)->functype() !=
7402 Item_func::NOW_FUNC ||
7403 (!real_type_with_now_as_default(type)) ||
7404 default_value->decimals != datetime_precision))
7405 {
7406 my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
7407 DBUG_RETURN(1);
7408 }
7409 else if (default_value->type() == Item::NULL_ITEM)
7410 {
7411 default_value= 0;
7412 if ((type_modifier & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) ==
7413 NOT_NULL_FLAG)
7414 {
7415 my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
7416 DBUG_RETURN(1);
7417 }
7418 }
7419 else if (type_modifier & AUTO_INCREMENT_FLAG)
7420 {
7421 my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
7422 DBUG_RETURN(1);
7423 }
7424 }
7425
7426 if (on_update_value &&
7427 (!real_type_with_now_on_update(type) ||
7428 on_update_value->decimals != datetime_precision))
7429 {
7430 my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name->str);
7431 DBUG_RETURN(1);
7432 }
7433
7434 if (!(new_field= new Create_field()) ||
7435 new_field->init(thd, field_name->str, type, length, decimals, type_modifier,
7436 default_value, on_update_value, comment, change,
7437 interval_list, cs, uint_geom_type, zip_dict))
7438 DBUG_RETURN(1);
7439
7440 lex->alter_info.create_list.push_back(new_field);
7441 lex->last_field=new_field;
7442 DBUG_RETURN(0);
7443 }
7444
7445
7446 /** Store position for column in ALTER TABLE .. ADD column. */
7447
7448 void store_position_for_column(const char *name)
7449 {
7450 current_thd->lex->last_field->after=(char*) (name);
7451 }
7452
7453
7454 /**
7455 save order by and tables in own lists.
7456 */
7457
7458 bool add_to_list(THD *thd, SQL_I_List<ORDER> &list, Item *item,bool asc)
7459 {
7460 ORDER *order;
7461 DBUG_ENTER("add_to_list");
7462 if (!(order = (ORDER *) thd->alloc(sizeof(ORDER))))
7463 DBUG_RETURN(1);
7464 order->item_ptr= item;
7465 order->item= &order->item_ptr;
7466 order->direction= (asc ? ORDER::ORDER_ASC : ORDER::ORDER_DESC);
7467 order->used_alias= false;
7468 order->used=0;
7469 order->counter_used= 0;
7470 list.link_in_list(order, &order->next);
7471 DBUG_RETURN(0);
7472 }
7473
7474
7475 /**
7476 Add a table to list of used tables.
7477
7478 @param table Table to add
7479 @param alias alias for table (or null if no alias)
7480 @param table_options A set of the following bits:
7481 - TL_OPTION_UPDATING : Table will be updated
7482 - TL_OPTION_FORCE_INDEX : Force usage of index
7483 - TL_OPTION_ALIAS : an alias in multi table DELETE
7484 @param lock_type How table should be locked
7485 @param mdl_type Type of metadata lock to acquire on the table.
7486 @param use_index List of indexed used in USE INDEX
7487 @param ignore_index List of indexed used in IGNORE INDEX
7488
7489 @retval
7490 0 Error
7491 @retval
7492 \# Pointer to TABLE_LIST element added to the total table list
7493 */
7494
7495 TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
7496 Table_ident *table,
7497 LEX_STRING *alias,
7498 ulong table_options,
7499 thr_lock_type lock_type,
7500 enum_mdl_type mdl_type,
7501 List<Index_hint> *index_hints_arg,
7502 List<String> *partition_names,
7503 LEX_STRING *option)
7504 {
7505 TABLE_LIST *ptr;
7506 TABLE_LIST *previous_table_ref; /* The table preceding the current one. */
7507 char *alias_str;
7508 LEX *lex= thd->lex;
7509 DBUG_ENTER("add_table_to_list");
7510 LINT_INIT(previous_table_ref);
7511
7512 if (!table)
7513 DBUG_RETURN(0); // End of memory
7514 alias_str= alias ? alias->str : table->table.str;
7515 if (!MY_TEST(table_options & TL_OPTION_ALIAS))
7516 {
7517 enum_ident_name_check ident_check_status=
7518 check_table_name(table->table.str, table->table.length, FALSE);
7519 if (ident_check_status == IDENT_NAME_WRONG)
7520 {
7521 my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
7522 DBUG_RETURN(0);
7523 }
7524 else if (ident_check_status == IDENT_NAME_TOO_LONG)
7525 {
7526 my_error(ER_TOO_LONG_IDENT, MYF(0), table->table.str);
7527 DBUG_RETURN(0);
7528 }
7529 }
7530 if (table->is_derived_table() == FALSE && table->db.str &&
7531 (check_and_convert_db_name(&table->db, FALSE) != IDENT_NAME_OK))
7532 DBUG_RETURN(0);
7533
7534 if (!alias) /* Alias is case sensitive */
7535 {
7536 if (table->sel)
7537 {
7538 my_message(ER_DERIVED_MUST_HAVE_ALIAS,
7539 ER(ER_DERIVED_MUST_HAVE_ALIAS), MYF(0));
7540 DBUG_RETURN(0);
7541 }
7542 if (!(alias_str= (char*) thd->memdup(alias_str,table->table.length+1)))
7543 DBUG_RETURN(0);
7544 }
7545 if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
7546 DBUG_RETURN(0); /* purecov: inspected */
7547 if (table->db.str)
7548 {
7549 ptr->is_fqtn= TRUE;
7550 ptr->db= table->db.str;
7551 ptr->db_length= table->db.length;
7552 }
7553 else if (lex->copy_db_to(&ptr->db, &ptr->db_length))
7554 DBUG_RETURN(0);
7555 else
7556 ptr->is_fqtn= FALSE;
7557
7558 ptr->alias= alias_str;
7559 ptr->is_alias= alias ? TRUE : FALSE;
7560 if (lower_case_table_names && table->table.length)
7561 table->table.length= my_casedn_str(files_charset_info, table->table.str);
7562 ptr->table_name=table->table.str;
7563 ptr->table_name_length=table->table.length;
7564 ptr->lock_type= lock_type;
7565 ptr->updating= MY_TEST(table_options & TL_OPTION_UPDATING);
7566 /* TODO: remove TL_OPTION_FORCE_INDEX as it looks like it's not used */
7567 ptr->force_index= MY_TEST(table_options & TL_OPTION_FORCE_INDEX);
7568 ptr->ignore_leaves= MY_TEST(table_options & TL_OPTION_IGNORE_LEAVES);
7569 ptr->derived= table->sel;
7570 if (!ptr->derived && is_infoschema_db(ptr->db, ptr->db_length))
7571 {
7572 ST_SCHEMA_TABLE *schema_table;
7573 if (ptr->updating &&
7574 /* Special cases which are processed by commands itself */
7575 lex->sql_command != SQLCOM_CHECK &&
7576 lex->sql_command != SQLCOM_CHECKSUM)
7577 {
7578 my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
7579 thd->security_ctx->priv_user,
7580 thd->security_ctx->priv_host,
7581 INFORMATION_SCHEMA_NAME.str);
7582 DBUG_RETURN(0);
7583 }
7584 schema_table= find_schema_table(thd, ptr->table_name);
7585 if (!schema_table ||
7586 (schema_table->hidden &&
7587 ((sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0 ||
7588 /*
7589 this check is used for show columns|keys from I_S hidden table
7590 */
7591 lex->sql_command == SQLCOM_SHOW_FIELDS ||
7592 lex->sql_command == SQLCOM_SHOW_KEYS)))
7593 {
7594 my_error(ER_UNKNOWN_TABLE, MYF(0),
7595 ptr->table_name, INFORMATION_SCHEMA_NAME.str);
7596 DBUG_RETURN(0);
7597 }
7598 ptr->schema_table_name= ptr->table_name;
7599 ptr->schema_table= schema_table;
7600 }
7601 ptr->select_lex= lex->current_select;
7602 ptr->cacheable_table= 1;
7603 ptr->index_hints= index_hints_arg;
7604 ptr->option= option ? option->str : 0;
7605 /* check that used name is unique */
7606 if (lock_type != TL_IGNORE)
7607 {
7608 TABLE_LIST *first_table= table_list.first;
7609 if (lex->sql_command == SQLCOM_CREATE_VIEW)
7610 first_table= first_table ? first_table->next_local : NULL;
7611 for (TABLE_LIST *tables= first_table ;
7612 tables ;
7613 tables=tables->next_local)
7614 {
7615 if (!my_strcasecmp(table_alias_charset, alias_str, tables->alias) &&
7616 !strcmp(ptr->db, tables->db))
7617 {
7618 my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str); /* purecov: tested */
7619 DBUG_RETURN(0); /* purecov: tested */
7620 }
7621 }
7622 }
7623 /* Store the table reference preceding the current one. */
7624 if (table_list.elements > 0)
7625 {
7626 /*
7627 table_list.next points to the last inserted TABLE_LIST->next_local'
7628 element
7629 We don't use the offsetof() macro here to avoid warnings from gcc
7630 */
7631 previous_table_ref= (TABLE_LIST*) ((char*) table_list.next -
7632 ((char*) &(ptr->next_local) -
7633 (char*) ptr));
7634 /*
7635 Set next_name_resolution_table of the previous table reference to point
7636 to the current table reference. In effect the list
7637 TABLE_LIST::next_name_resolution_table coincides with
7638 TABLE_LIST::next_local. Later this may be changed in
7639 store_top_level_join_columns() for NATURAL/USING joins.
7640 */
7641 previous_table_ref->next_name_resolution_table= ptr;
7642 }
7643
7644 /*
7645 Link the current table reference in a local list (list for current select).
7646 Notice that as a side effect here we set the next_local field of the
7647 previous table reference to 'ptr'. Here we also add one element to the
7648 list 'table_list'.
7649 */
7650 table_list.link_in_list(ptr, &ptr->next_local);
7651 ptr->next_name_resolution_table= NULL;
7652 #ifdef WITH_PARTITION_STORAGE_ENGINE
7653 ptr->partition_names= partition_names;
7654 #endif /* WITH_PARTITION_STORAGE_ENGINE */
7655 /* Link table in global list (all used tables) */
7656 lex->add_to_query_tables(ptr);
7657
7658 // Pure table aliases do not need to be locked:
7659 if (!MY_TEST(table_options & TL_OPTION_ALIAS))
7660 {
7661 ptr->mdl_request.init(MDL_key::TABLE, ptr->db, ptr->table_name, mdl_type,
7662 MDL_TRANSACTION);
7663 }
7664 if (table->is_derived_table())
7665 {
7666 ptr->effective_algorithm= DERIVED_ALGORITHM_TMPTABLE;
7667 ptr->derived_key_list.empty();
7668 }
7669 DBUG_RETURN(ptr);
7670 }
7671
7672
7673 /**
7674 Initialize a new table list for a nested join.
7675
7676 The function initializes a structure of the TABLE_LIST type
7677 for a nested join. It sets up its nested join list as empty.
7678 The created structure is added to the front of the current
7679 join list in the st_select_lex object. Then the function
7680 changes the current nest level for joins to refer to the newly
7681 created empty list after having saved the info on the old level
7682 in the initialized structure.
7683
7684 @param thd current thread
7685
7686 @retval
7687 0 if success
7688 @retval
7689 1 otherwise
7690 */
7691
7692 bool st_select_lex::init_nested_join(THD *thd)
7693 {
7694 DBUG_ENTER("init_nested_join");
7695
7696 TABLE_LIST *const ptr=
7697 TABLE_LIST::new_nested_join(thd->mem_root, "(nested_join)",
7698 embedding, join_list, this);
7699 if (ptr == NULL)
7700 DBUG_RETURN(true);
7701
7702 join_list->push_front(ptr);
7703 embedding= ptr;
7704 join_list= &ptr->nested_join->join_list;
7705
7706 DBUG_RETURN(false);
7707 }
7708
7709
7710 /**
7711 End a nested join table list.
7712
7713 The function returns to the previous join nest level.
7714 If the current level contains only one member, the function
7715 moves it one level up, eliminating the nest.
7716
7717 @param thd current thread
7718
7719 @return
7720 - Pointer to TABLE_LIST element added to the total table list, if success
7721 - 0, otherwise
7722 */
7723
7724 TABLE_LIST *st_select_lex::end_nested_join(THD *thd)
7725 {
7726 TABLE_LIST *ptr;
7727 NESTED_JOIN *nested_join;
7728 DBUG_ENTER("end_nested_join");
7729
7730 DBUG_ASSERT(embedding);
7731 ptr= embedding;
7732 join_list= ptr->join_list;
7733 embedding= ptr->embedding;
7734 nested_join= ptr->nested_join;
7735 if (nested_join->join_list.elements == 1)
7736 {
7737 TABLE_LIST *embedded= nested_join->join_list.head();
7738 join_list->pop();
7739 embedded->join_list= join_list;
7740 embedded->embedding= embedding;
7741 join_list->push_front(embedded);
7742 ptr= embedded;
7743 }
7744 else if (nested_join->join_list.elements == 0)
7745 {
7746 join_list->pop();
7747 ptr= 0; // return value
7748 }
7749 DBUG_RETURN(ptr);
7750 }
7751
7752
7753 /**
7754 Nest last join operation.
7755
7756 The function nest last join operation as if it was enclosed in braces.
7757
7758 @param thd current thread
7759
7760 @retval
7761 0 Error
7762 @retval
7763 \# Pointer to TABLE_LIST element created for the new nested join
7764 */
7765
7766 TABLE_LIST *st_select_lex::nest_last_join(THD *thd)
7767 {
7768 DBUG_ENTER("nest_last_join");
7769
7770 TABLE_LIST *const ptr=
7771 TABLE_LIST::new_nested_join(thd->mem_root, "(nest_last_join)",
7772 embedding, join_list, this);
7773 if (ptr == NULL)
7774 DBUG_RETURN(NULL);
7775
7776 List<TABLE_LIST> *const embedded_list= &ptr->nested_join->join_list;
7777
7778 for (uint i=0; i < 2; i++)
7779 {
7780 TABLE_LIST *table= join_list->pop();
7781 table->join_list= embedded_list;
7782 table->embedding= ptr;
7783 embedded_list->push_back(table);
7784 if (table->natural_join)
7785 {
7786 ptr->is_natural_join= TRUE;
7787 /*
7788 If this is a JOIN ... USING, move the list of joined fields to the
7789 table reference that describes the join.
7790 */
7791 if (prev_join_using)
7792 ptr->join_using_fields= prev_join_using;
7793 }
7794 }
7795 join_list->push_front(ptr);
7796
7797 DBUG_RETURN(ptr);
7798 }
7799
7800
7801 /**
7802 Add a table to the current join list.
7803
7804 The function puts a table in front of the current join list
7805 of st_select_lex object.
7806 Thus, joined tables are put into this list in the reverse order
7807 (the most outer join operation follows first).
7808
7809 @param table the table to add
7810
7811 @return
7812 None
7813 */
7814
7815 void st_select_lex::add_joined_table(TABLE_LIST *table)
7816 {
7817 DBUG_ENTER("add_joined_table");
7818 join_list->push_front(table);
7819 table->join_list= join_list;
7820 table->embedding= embedding;
7821 DBUG_VOID_RETURN;
7822 }
7823
7824
7825 /**
7826 Convert a right join into equivalent left join.
7827
7828 The function takes the current join list t[0],t[1] ... and
7829 effectively converts it into the list t[1],t[0] ...
7830 Although the outer_join flag for the new nested table contains
7831 JOIN_TYPE_RIGHT, it will be handled as the inner table of a left join
7832 operation.
7833
7834 EXAMPLES
7835 @verbatim
7836 SELECT * FROM t1 RIGHT JOIN t2 ON on_expr =>
7837 SELECT * FROM t2 LEFT JOIN t1 ON on_expr
7838
7839 SELECT * FROM t1,t2 RIGHT JOIN t3 ON on_expr =>
7840 SELECT * FROM t1,t3 LEFT JOIN t2 ON on_expr
7841
7842 SELECT * FROM t1,t2 RIGHT JOIN (t3,t4) ON on_expr =>
7843 SELECT * FROM t1,(t3,t4) LEFT JOIN t2 ON on_expr
7844
7845 SELECT * FROM t1 LEFT JOIN t2 ON on_expr1 RIGHT JOIN t3 ON on_expr2 =>
7846 SELECT * FROM t3 LEFT JOIN (t1 LEFT JOIN t2 ON on_expr2) ON on_expr1
7847 @endverbatim
7848
7849 @param thd current thread
7850
7851 @return
7852 - Pointer to the table representing the inner table, if success
7853 - 0, otherwise
7854 */
7855
7856 TABLE_LIST *st_select_lex::convert_right_join()
7857 {
7858 TABLE_LIST *tab2= join_list->pop();
7859 TABLE_LIST *tab1= join_list->pop();
7860 DBUG_ENTER("convert_right_join");
7861
7862 join_list->push_front(tab2);
7863 join_list->push_front(tab1);
7864 tab1->outer_join|= JOIN_TYPE_RIGHT;
7865
7866 DBUG_RETURN(tab1);
7867 }
7868
7869 /**
7870 Set lock for all tables in current select level.
7871
7872 @param lock_type Lock to set for tables
7873
7874 @note
7875 If lock is a write lock, then tables->updating is set 1
7876 This is to get tables_ok to know that the table is updated by the
7877 query
7878 */
7879
7880 void st_select_lex::set_lock_for_tables(thr_lock_type lock_type)
7881 {
7882 bool for_update= lock_type >= TL_READ_NO_INSERT;
7883 DBUG_ENTER("set_lock_for_tables");
7884 DBUG_PRINT("enter", ("lock_type: %d for_update: %d", lock_type,
7885 for_update));
7886 for (TABLE_LIST *tables= table_list.first;
7887 tables;
7888 tables= tables->next_local)
7889 {
7890 tables->lock_type= lock_type;
7891 tables->updating= for_update;
7892 tables->mdl_request.set_type((lock_type >= TL_WRITE_ALLOW_WRITE) ?
7893 MDL_SHARED_WRITE : MDL_SHARED_READ);
7894 }
7895 DBUG_VOID_RETURN;
7896 }
7897
7898
7899 /**
7900 Create a fake SELECT_LEX for a unit.
7901
7902 The method create a fake SELECT_LEX object for a unit.
7903 This object is created for any union construct containing a union
7904 operation and also for any single select union construct of the form
7905 @verbatim
7906 (SELECT ... ORDER BY order_list [LIMIT n]) ORDER BY ...
7907 @endvarbatim
7908 or of the form
7909 @varbatim
7910 (SELECT ... ORDER BY LIMIT n) ORDER BY ...
7911 @endvarbatim
7912
7913 @param thd_arg thread handle
7914
7915 @note
7916 The object is used to retrieve rows from the temporary table
7917 where the result on the union is obtained.
7918
7919 @retval
7920 1 on failure to create the object
7921 @retval
7922 0 on success
7923 */
7924
7925 bool st_select_lex_unit::add_fake_select_lex(THD *thd_arg)
7926 {
7927 SELECT_LEX *first_sl= first_select();
7928 DBUG_ENTER("add_fake_select_lex");
7929 DBUG_ASSERT(!fake_select_lex);
7930
7931 if (!(fake_select_lex= new (thd_arg->mem_root) SELECT_LEX()))
7932 DBUG_RETURN(1);
7933 fake_select_lex->include_standalone(this,
7934 (SELECT_LEX_NODE**)&fake_select_lex);
7935 fake_select_lex->select_number= INT_MAX;
7936 fake_select_lex->parent_lex= thd_arg->lex; /* Used in init_query. */
7937 fake_select_lex->make_empty_select();
7938 fake_select_lex->linkage= GLOBAL_OPTIONS_TYPE;
7939 fake_select_lex->select_limit= 0;
7940
7941 fake_select_lex->context.outer_context=first_sl->context.outer_context;
7942 /* allow item list resolving in fake select for ORDER BY */
7943 fake_select_lex->context.resolve_in_select_list= TRUE;
7944 fake_select_lex->context.select_lex= fake_select_lex;
7945
7946 if (!is_union())
7947 {
7948 /*
7949 This works only for
7950 (SELECT ... ORDER BY list [LIMIT n]) ORDER BY order_list [LIMIT m],
7951 (SELECT ... LIMIT n) ORDER BY order_list [LIMIT m]
7952 just before the parser starts processing order_list
7953 */
7954 global_parameters= fake_select_lex;
7955 fake_select_lex->no_table_names_allowed= 1;
7956 thd_arg->lex->current_select= fake_select_lex;
7957 }
7958 thd_arg->lex->pop_context();
7959 DBUG_RETURN(0);
7960 }
7961
7962
7963 /**
7964 Push a new name resolution context for a JOIN ... ON clause to the
7965 context stack of a query block.
7966
7967 Create a new name resolution context for a JOIN ... ON clause,
7968 set the first and last leaves of the list of table references
7969 to be used for name resolution, and push the newly created
7970 context to the stack of contexts of the query.
7971
7972 @param thd pointer to current thread
7973 @param left_op left operand of the JOIN
7974 @param right_op rigth operand of the JOIN
7975
7976 @todo Research if we should set the "outer_context" member of the new ON
7977 context.
7978
7979 @retval
7980 FALSE if all is OK
7981 @retval
7982 TRUE if a memory allocation error occured
7983 */
7984
7985 bool
7986 push_new_name_resolution_context(THD *thd,
7987 TABLE_LIST *left_op, TABLE_LIST *right_op)
7988 {
7989 Name_resolution_context *on_context;
7990 if (!(on_context= new (thd->mem_root) Name_resolution_context))
7991 return TRUE;
7992 on_context->init();
7993 on_context->first_name_resolution_table=
7994 left_op->first_leaf_for_name_resolution();
7995 on_context->last_name_resolution_table=
7996 right_op->last_leaf_for_name_resolution();
7997 on_context->select_lex= thd->lex->current_select;
7998 // Save join nest's context in right_op, to find it later in view merging.
7999 DBUG_ASSERT(right_op->context_of_embedding == NULL);
8000 right_op->context_of_embedding= on_context;
8001 return thd->lex->push_context(on_context);
8002 }
8003
8004
8005 /**
8006 Add an ON condition to the second operand of a JOIN ... ON.
8007
8008 Add an ON condition to the right operand of a JOIN ... ON clause.
8009
8010 @param b the second operand of a JOIN ... ON
8011 @param expr the condition to be added to the ON clause
8012 */
8013
8014 void add_join_on(TABLE_LIST *b, Item *expr)
8015 {
8016 if (expr)
8017 {
8018 if (!b->join_cond())
8019 b->set_join_cond(expr);
8020 else
8021 {
8022 /*
8023 If called from the parser, this happens if you have both a
8024 right and left join. If called later, it happens if we add more
8025 than one condition to the ON clause.
8026 */
8027 b->set_join_cond(new Item_cond_and(b->join_cond(), expr));
8028 }
8029 b->join_cond()->top_level_item();
8030 }
8031 }
8032
8033
8034 /**
8035 Mark that there is a NATURAL JOIN or JOIN ... USING between two
8036 tables.
8037
8038 This function marks that table b should be joined with a either via
8039 a NATURAL JOIN or via JOIN ... USING. Both join types are special
8040 cases of each other, so we treat them together. The function
8041 setup_conds() creates a list of equal condition between all fields
8042 of the same name for NATURAL JOIN or the fields in 'using_fields'
8043 for JOIN ... USING. The list of equality conditions is stored
8044 either in b->join_cond(), or in JOIN::conds, depending on whether there
8045 was an outer join.
8046
8047 EXAMPLE
8048 @verbatim
8049 SELECT * FROM t1 NATURAL LEFT JOIN t2
8050 <=>
8051 SELECT * FROM t1 LEFT JOIN t2 ON (t1.i=t2.i and t1.j=t2.j ... )
8052
8053 SELECT * FROM t1 NATURAL JOIN t2 WHERE <some_cond>
8054 <=>
8055 SELECT * FROM t1, t2 WHERE (t1.i=t2.i and t1.j=t2.j and <some_cond>)
8056
8057 SELECT * FROM t1 JOIN t2 USING(j) WHERE <some_cond>
8058 <=>
8059 SELECT * FROM t1, t2 WHERE (t1.j=t2.j and <some_cond>)
8060 @endverbatim
8061
8062 @param a Left join argument
8063 @param b Right join argument
8064 @param using_fields Field names from USING clause
8065 */
8066
8067 void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List<String> *using_fields,
8068 SELECT_LEX *lex)
8069 {
8070 b->natural_join= a;
8071 lex->prev_join_using= using_fields;
8072 }
8073
8074
8075 /**
8076 kill on thread.
8077
8078 @param thd Thread class
8079 @param id Thread id
8080 @param only_kill_query Should it kill the query or the connection
8081
8082 @note
8083 This is written such that we have a short lock on LOCK_thread_count
8084 */
8085
8086 uint kill_one_thread(THD *thd, ulong id, bool only_kill_query)
8087 {
8088 THD *tmp= NULL;
8089 uint error=ER_NO_SUCH_THREAD;
8090 DBUG_ENTER("kill_one_thread");
8091 DBUG_PRINT("enter", ("id=%lu only_kill=%d", id, only_kill_query));
8092
8093 mysql_mutex_lock(&LOCK_thread_count);
8094 Thread_iterator it= global_thread_list_begin();
8095 Thread_iterator end= global_thread_list_end();
8096 for (; it != end; ++it)
8097 {
8098 if ((*it)->get_command() == COM_DAEMON)
8099 continue;
8100 if ((*it)->thread_id == id)
8101 {
8102 tmp= *it;
8103 mysql_mutex_lock(&tmp->LOCK_thd_data); // Lock from delete
8104 break;
8105 }
8106 }
8107 mysql_mutex_unlock(&LOCK_thread_count);
8108 if (tmp)
8109 {
8110
8111 /*
8112 If we're SUPER, we can KILL anything, including system-threads.
8113 No further checks.
8114
8115 KILLer: thd->security_ctx->user could in theory be NULL while
8116 we're still in "unauthenticated" state. This is a theoretical
8117 case (the code suggests this could happen, so we play it safe).
8118
8119 KILLee: tmp->security_ctx->user will be NULL for system threads.
8120 We need to check so Jane Random User doesn't crash the server
8121 when trying to kill a) system threads or b) unauthenticated users'
8122 threads (Bug#43748).
8123
8124 If user of both killer and killee are non-NULL, proceed with
8125 slayage if both are string-equal.
8126 */
8127
8128 const bool is_utility_connection =
8129 acl_is_utility_user(tmp->security_ctx->priv_user,
8130 tmp->security_ctx->get_host()->ptr(),
8131 tmp->security_ctx->get_ip()->ptr());
8132
8133
8134 if (((thd->security_ctx->master_access & SUPER_ACL) && !is_utility_connection) ||
8135 thd->security_ctx->user_matches(tmp->security_ctx))
8136 {
8137 /* process the kill only if thread is not already undergoing any kill
8138 connection.
8139 */
8140 if (tmp->killed != THD::KILL_CONNECTION)
8141 {
8142 tmp->awake(only_kill_query ? THD::KILL_QUERY : THD::KILL_CONNECTION);
8143 }
8144 error= 0;
8145 }
8146 else
8147 error=ER_KILL_DENIED_ERROR;
8148 mysql_mutex_unlock(&tmp->LOCK_thd_data);
8149 }
8150 DBUG_PRINT("exit", ("%d", error));
8151 DBUG_RETURN(error);
8152 }
8153
8154
8155 /*
8156 kills a thread and sends response
8157
8158 SYNOPSIS
8159 sql_kill()
8160 thd Thread class
8161 id Thread id
8162 only_kill_query Should it kill the query or the connection
8163 */
8164
8165 static
8166 void sql_kill(THD *thd, ulong id, bool only_kill_query)
8167 {
8168 uint error;
8169 if (!(error= kill_one_thread(thd, id, only_kill_query)))
8170 {
8171 if (! thd->killed)
8172 my_ok(thd);
8173 }
8174 else
8175 my_error(error, MYF(0), id);
8176 }
8177
8178
8179 /** If pointer is not a null pointer, append filename to it. */
8180
8181 bool append_file_to_dir(THD *thd, const char **filename_ptr,
8182 const char *table_name)
8183 {
8184 char buff[FN_REFLEN],*ptr, *end;
8185 if (!*filename_ptr)
8186 return 0; // nothing to do
8187
8188 /* Check that the filename is not too long and it's a hard path */
8189 if (strlen(*filename_ptr)+strlen(table_name) >= FN_REFLEN-1 ||
8190 !test_if_hard_path(*filename_ptr))
8191 {
8192 my_error(ER_WRONG_TABLE_NAME, MYF(0), *filename_ptr);
8193 return 1;
8194 }
8195 /* Fix is using unix filename format on dos */
8196 strmov(buff,*filename_ptr);
8197 end=convert_dirname(buff, *filename_ptr, NullS);
8198 if (!(ptr= (char*) thd->alloc((size_t) (end-buff) + strlen(table_name)+1)))
8199 return 1; // End of memory
8200 *filename_ptr=ptr;
8201 strxmov(ptr,buff,table_name,NullS);
8202 return 0;
8203 }
8204
8205
8206 /**
8207 Check if the select is a simple select (not an union).
8208
8209 @retval
8210 0 ok
8211 @retval
8212 1 error ; In this case the error messege is sent to the client
8213 */
8214
8215 bool check_simple_select()
8216 {
8217 THD *thd= current_thd;
8218 LEX *lex= thd->lex;
8219 if (lex->current_select != &lex->select_lex)
8220 {
8221 char command[80];
8222 Lex_input_stream *lip= & thd->m_parser_state->m_lip;
8223 strmake(command, lip->yylval->symbol.str,
8224 min<size_t>(lip->yylval->symbol.length, sizeof(command)-1));
8225 my_error(ER_CANT_USE_OPTION_HERE, MYF(0), command);
8226 return 1;
8227 }
8228 return 0;
8229 }
8230
8231
8232 Comp_creator *comp_eq_creator(bool invert)
8233 {
8234 return invert?(Comp_creator *)&ne_creator:(Comp_creator *)&eq_creator;
8235 }
8236
8237
8238 Comp_creator *comp_ge_creator(bool invert)
8239 {
8240 return invert?(Comp_creator *)<_creator:(Comp_creator *)&ge_creator;
8241 }
8242
8243
8244 Comp_creator *comp_gt_creator(bool invert)
8245 {
8246 return invert?(Comp_creator *)&le_creator:(Comp_creator *)>_creator;
8247 }
8248
8249
8250 Comp_creator *comp_le_creator(bool invert)
8251 {
8252 return invert?(Comp_creator *)>_creator:(Comp_creator *)&le_creator;
8253 }
8254
8255
8256 Comp_creator *comp_lt_creator(bool invert)
8257 {
8258 return invert?(Comp_creator *)&ge_creator:(Comp_creator *)<_creator;
8259 }
8260
8261
8262 Comp_creator *comp_ne_creator(bool invert)
8263 {
8264 return invert?(Comp_creator *)&eq_creator:(Comp_creator *)&ne_creator;
8265 }
8266
8267
8268 /**
8269 Construct ALL/ANY/SOME subquery Item.
8270
8271 @param left_expr pointer to left expression
8272 @param cmp compare function creator
8273 @param all true if we create ALL subquery
8274 @param select_lex pointer on parsed subquery structure
8275
8276 @return
8277 constructed Item (or 0 if out of memory)
8278 */
8279 Item * all_any_subquery_creator(Item *left_expr,
8280 chooser_compare_func_creator cmp,
8281 bool all,
8282 SELECT_LEX *select_lex)
8283 {
8284 if ((cmp == &comp_eq_creator) && !all) // = ANY <=> IN
8285 return new Item_in_subselect(left_expr, select_lex);
8286
8287 if ((cmp == &comp_ne_creator) && all) // <> ALL <=> NOT IN
8288 return new Item_func_not(new Item_in_subselect(left_expr, select_lex));
8289
8290 Item_allany_subselect *it=
8291 new Item_allany_subselect(left_expr, cmp, select_lex, all);
8292 if (all)
8293 return it->upper_item= new Item_func_not_all(it); /* ALL */
8294
8295 return it->upper_item= new Item_func_nop_all(it); /* ANY/SOME */
8296 }
8297
8298
8299 /**
8300 Perform first stage of privilege checking for SELECT statement.
8301
8302 @param thd Thread context.
8303 @param lex LEX for SELECT statement.
8304 @param tables List of tables used by statement.
8305 @param first_table First table in the main SELECT of the SELECT
8306 statement.
8307
8308 @retval FALSE - Success (column-level privilege checks might be required).
8309 @retval TRUE - Failure, privileges are insufficient.
8310 */
8311
8312 bool select_precheck(THD *thd, LEX *lex, TABLE_LIST *tables,
8313 TABLE_LIST *first_table)
8314 {
8315 bool res;
8316 /*
8317 lex->exchange != NULL implies SELECT .. INTO OUTFILE and this
8318 requires FILE_ACL access.
8319 */
8320 ulong privileges_requested= lex->exchange ? SELECT_ACL | FILE_ACL :
8321 SELECT_ACL;
8322
8323 if (tables)
8324 {
8325 res= check_table_access(thd,
8326 privileges_requested,
8327 tables, FALSE, UINT_MAX, FALSE) ||
8328 (first_table && first_table->schema_table_reformed &&
8329 check_show_access(thd, first_table));
8330 }
8331 else
8332 res= check_access(thd, privileges_requested, any_db, NULL, NULL, 0, 0);
8333
8334 return res;
8335 }
8336
8337
8338 /**
8339 Multi update query pre-check.
8340
8341 @param thd Thread handler
8342 @param tables Global/local table list (have to be the same)
8343
8344 @retval
8345 FALSE OK
8346 @retval
8347 TRUE Error
8348 */
8349
8350 bool multi_update_precheck(THD *thd, TABLE_LIST *tables)
8351 {
8352 const char *msg= 0;
8353 TABLE_LIST *table;
8354 LEX *lex= thd->lex;
8355 SELECT_LEX *select_lex= &lex->select_lex;
8356 DBUG_ENTER("multi_update_precheck");
8357
8358 if (select_lex->item_list.elements != lex->value_list.elements)
8359 {
8360 my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0));
8361 DBUG_RETURN(TRUE);
8362 }
8363 /*
8364 Ensure that we have UPDATE or SELECT privilege for each table
8365 The exact privilege is checked in mysql_multi_update()
8366 */
8367 for (table= tables; table; table= table->next_local)
8368 {
8369 if (table->derived)
8370 table->grant.privilege= SELECT_ACL;
8371 else if ((check_access(thd, UPDATE_ACL, table->db,
8372 &table->grant.privilege,
8373 &table->grant.m_internal,
8374 0, 1) ||
8375 check_grant(thd, UPDATE_ACL, table, FALSE, 1, TRUE)) &&
8376 (check_access(thd, SELECT_ACL, table->db,
8377 &table->grant.privilege,
8378 &table->grant.m_internal,
8379 0, 0) ||
8380 check_grant(thd, SELECT_ACL, table, FALSE, 1, FALSE)))
8381 DBUG_RETURN(TRUE);
8382
8383 table->table_in_first_from_clause= 1;
8384 }
8385 /*
8386 Is there tables of subqueries?
8387 */
8388 if (&lex->select_lex != lex->all_selects_list)
8389 {
8390 DBUG_PRINT("info",("Checking sub query list"));
8391 for (table= tables; table; table= table->next_global)
8392 {
8393 if (!table->table_in_first_from_clause)
8394 {
8395 if (check_access(thd, SELECT_ACL, table->db,
8396 &table->grant.privilege,
8397 &table->grant.m_internal,
8398 0, 0) ||
8399 check_grant(thd, SELECT_ACL, table, FALSE, 1, FALSE))
8400 DBUG_RETURN(TRUE);
8401 }
8402 }
8403 }
8404
8405 if (select_lex->order_list.elements)
8406 msg= "ORDER BY";
8407 else if (select_lex->select_limit)
8408 msg= "LIMIT";
8409 if (msg)
8410 {
8411 my_error(ER_WRONG_USAGE, MYF(0), "UPDATE", msg);
8412 DBUG_RETURN(TRUE);
8413 }
8414 DBUG_RETURN(FALSE);
8415 }
8416
8417 /**
8418 Multi delete query pre-check.
8419
8420 @param thd Thread handler
8421 @param tables Global/local table list
8422
8423 @retval
8424 FALSE OK
8425 @retval
8426 TRUE error
8427 */
8428
8429 bool multi_delete_precheck(THD *thd, TABLE_LIST *tables)
8430 {
8431 SELECT_LEX *select_lex= &thd->lex->select_lex;
8432 TABLE_LIST *aux_tables= thd->lex->auxiliary_table_list.first;
8433 TABLE_LIST **save_query_tables_own_last= thd->lex->query_tables_own_last;
8434 DBUG_ENTER("multi_delete_precheck");
8435
8436 /*
8437 Temporary tables are pre-opened in 'tables' list only. Here we need to
8438 initialize TABLE instances in 'aux_tables' list.
8439 */
8440 for (TABLE_LIST *tl= aux_tables; tl; tl= tl->next_global)
8441 {
8442 if (tl->table)
8443 continue;
8444
8445 if (tl->correspondent_table)
8446 tl->table= tl->correspondent_table->table;
8447 }
8448
8449 /* sql_yacc guarantees that tables and aux_tables are not zero */
8450 DBUG_ASSERT(aux_tables != 0);
8451 if (check_table_access(thd, SELECT_ACL, tables, FALSE, UINT_MAX, FALSE))
8452 DBUG_RETURN(TRUE);
8453
8454 /*
8455 Since aux_tables list is not part of LEX::query_tables list we
8456 have to juggle with LEX::query_tables_own_last value to be able
8457 call check_table_access() safely.
8458 */
8459 thd->lex->query_tables_own_last= 0;
8460 if (check_table_access(thd, DELETE_ACL, aux_tables, FALSE, UINT_MAX, FALSE))
8461 {
8462 thd->lex->query_tables_own_last= save_query_tables_own_last;
8463 DBUG_RETURN(TRUE);
8464 }
8465 thd->lex->query_tables_own_last= save_query_tables_own_last;
8466
8467 if ((thd->variables.option_bits & OPTION_SAFE_UPDATES) && !select_lex->where)
8468 {
8469 my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
8470 ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
8471 DBUG_RETURN(TRUE);
8472 }
8473 DBUG_RETURN(FALSE);
8474 }
8475
8476
8477 /*
8478 Given a table in the source list, find a correspondent table in the
8479 table references list.
8480
8481 @param lex Pointer to LEX representing multi-delete.
8482 @param src Source table to match.
8483 @param ref Table references list.
8484
8485 @remark The source table list (tables listed before the FROM clause
8486 or tables listed in the FROM clause before the USING clause) may
8487 contain table names or aliases that must match unambiguously one,
8488 and only one, table in the target table list (table references list,
8489 after FROM/USING clause).
8490
8491 @return Matching table, NULL otherwise.
8492 */
8493
8494 static TABLE_LIST *multi_delete_table_match(LEX *lex, TABLE_LIST *tbl,
8495 TABLE_LIST *tables)
8496 {
8497 TABLE_LIST *match= NULL;
8498 DBUG_ENTER("multi_delete_table_match");
8499
8500 for (TABLE_LIST *elem= tables; elem; elem= elem->next_local)
8501 {
8502 int cmp;
8503
8504 if (tbl->is_fqtn && elem->is_alias)
8505 continue; /* no match */
8506 if (tbl->is_fqtn && elem->is_fqtn)
8507 cmp= my_strcasecmp(table_alias_charset, tbl->table_name, elem->table_name) ||
8508 strcmp(tbl->db, elem->db);
8509 else if (elem->is_alias)
8510 cmp= my_strcasecmp(table_alias_charset, tbl->alias, elem->alias);
8511 else
8512 cmp= my_strcasecmp(table_alias_charset, tbl->table_name, elem->table_name) ||
8513 strcmp(tbl->db, elem->db);
8514
8515 if (cmp)
8516 continue;
8517
8518 if (match)
8519 {
8520 my_error(ER_NONUNIQ_TABLE, MYF(0), elem->alias);
8521 DBUG_RETURN(NULL);
8522 }
8523
8524 match= elem;
8525 }
8526
8527 if (!match)
8528 my_error(ER_UNKNOWN_TABLE, MYF(0), tbl->table_name, "MULTI DELETE");
8529
8530 DBUG_RETURN(match);
8531 }
8532
8533
8534 /**
8535 Link tables in auxilary table list of multi-delete with corresponding
8536 elements in main table list, and set proper locks for them.
8537
8538 @param lex pointer to LEX representing multi-delete
8539
8540 @retval
8541 FALSE success
8542 @retval
8543 TRUE error
8544 */
8545
8546 bool multi_delete_set_locks_and_link_aux_tables(LEX *lex)
8547 {
8548 TABLE_LIST *tables= lex->select_lex.table_list.first;
8549 TABLE_LIST *target_tbl;
8550 DBUG_ENTER("multi_delete_set_locks_and_link_aux_tables");
8551
8552 for (target_tbl= lex->auxiliary_table_list.first;
8553 target_tbl; target_tbl= target_tbl->next_local)
8554 {
8555 /* All tables in aux_tables must be found in FROM PART */
8556 TABLE_LIST *walk= multi_delete_table_match(lex, target_tbl, tables);
8557 if (!walk)
8558 DBUG_RETURN(TRUE);
8559 if (!walk->derived)
8560 {
8561 target_tbl->table_name= walk->table_name;
8562 target_tbl->table_name_length= walk->table_name_length;
8563 }
8564 walk->updating= target_tbl->updating;
8565 walk->lock_type= target_tbl->lock_type;
8566 /* We can assume that tables to be deleted from are locked for write. */
8567 DBUG_ASSERT(walk->lock_type >= TL_WRITE_ALLOW_WRITE);
8568 walk->mdl_request.set_type(MDL_SHARED_WRITE);
8569 target_tbl->correspondent_table= walk; // Remember corresponding table
8570 }
8571 DBUG_RETURN(FALSE);
8572 }
8573
8574
8575 /**
8576 simple UPDATE query pre-check.
8577
8578 @param thd Thread handler
8579 @param tables Global table list
8580
8581 @retval
8582 FALSE OK
8583 @retval
8584 TRUE Error
8585 */
8586
8587 bool update_precheck(THD *thd, TABLE_LIST *tables)
8588 {
8589 DBUG_ENTER("update_precheck");
8590 if (thd->lex->select_lex.item_list.elements != thd->lex->value_list.elements)
8591 {
8592 my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0));
8593 DBUG_RETURN(TRUE);
8594 }
8595 DBUG_RETURN(check_one_table_access(thd, UPDATE_ACL, tables));
8596 }
8597
8598
8599 /**
8600 simple DELETE query pre-check.
8601
8602 @param thd Thread handler
8603 @param tables Global table list
8604
8605 @retval
8606 FALSE OK
8607 @retval
8608 TRUE error
8609 */
8610
8611 bool delete_precheck(THD *thd, TABLE_LIST *tables)
8612 {
8613 DBUG_ENTER("delete_precheck");
8614 if (check_one_table_access(thd, DELETE_ACL, tables))
8615 DBUG_RETURN(TRUE);
8616 /* Set privilege for the WHERE clause */
8617 tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege);
8618 DBUG_RETURN(FALSE);
8619 }
8620
8621
8622 /**
8623 simple INSERT query pre-check.
8624
8625 @param thd Thread handler
8626 @param tables Global table list
8627
8628 @retval
8629 FALSE OK
8630 @retval
8631 TRUE error
8632 */
8633
8634 bool insert_precheck(THD *thd, TABLE_LIST *tables)
8635 {
8636 LEX *lex= thd->lex;
8637 DBUG_ENTER("insert_precheck");
8638
8639 /*
8640 Check that we have modify privileges for the first table and
8641 select privileges for the rest
8642 */
8643 ulong privilege= (INSERT_ACL |
8644 (lex->duplicates == DUP_REPLACE ? DELETE_ACL : 0) |
8645 (lex->value_list.elements ? UPDATE_ACL : 0));
8646
8647 if (check_one_table_access(thd, privilege, tables))
8648 DBUG_RETURN(TRUE);
8649
8650 if (lex->update_list.elements != lex->value_list.elements)
8651 {
8652 my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0));
8653 DBUG_RETURN(TRUE);
8654 }
8655 DBUG_RETURN(FALSE);
8656 }
8657
8658
8659 /**
8660 Set proper open mode and table type for element representing target table
8661 of CREATE TABLE statement, also adjust statement table list if necessary.
8662 */
8663
8664 void create_table_set_open_action_and_adjust_tables(LEX *lex)
8665 {
8666 TABLE_LIST *create_table= lex->query_tables;
8667
8668 if (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)
8669 create_table->open_type= OT_TEMPORARY_ONLY;
8670 else
8671 create_table->open_type= OT_BASE_ONLY;
8672
8673 if (!lex->select_lex.item_list.elements)
8674 {
8675 /*
8676 Avoid opening and locking target table for ordinary CREATE TABLE
8677 or CREATE TABLE LIKE for write (unlike in CREATE ... SELECT we
8678 won't do any insertions in it anyway). Not doing this causes
8679 problems when running CREATE TABLE IF NOT EXISTS for already
8680 existing log table.
8681 */
8682 create_table->lock_type= TL_READ;
8683 }
8684 }
8685
8686
8687 /**
8688 CREATE TABLE query pre-check.
8689
8690 @param thd Thread handler
8691 @param tables Global table list
8692 @param create_table Table which will be created
8693
8694 @retval
8695 FALSE OK
8696 @retval
8697 TRUE Error
8698 */
8699
8700 bool create_table_precheck(THD *thd, TABLE_LIST *tables,
8701 TABLE_LIST *create_table)
8702 {
8703 LEX *lex= thd->lex;
8704 SELECT_LEX *select_lex= &lex->select_lex;
8705 ulong want_priv;
8706 bool error= TRUE; // Error message is given
8707 DBUG_ENTER("create_table_precheck");
8708
8709 /*
8710 Require CREATE [TEMPORARY] privilege on new table; for
8711 CREATE TABLE ... SELECT, also require INSERT.
8712 */
8713
8714 want_priv= (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) ?
8715 CREATE_TMP_ACL :
8716 (CREATE_ACL | (select_lex->item_list.elements ? INSERT_ACL : 0));
8717
8718 if (check_access(thd, want_priv, create_table->db,
8719 &create_table->grant.privilege,
8720 &create_table->grant.m_internal,
8721 0, 0))
8722 goto err;
8723
8724 /* If it is a merge table, check privileges for merge children. */
8725 if (lex->create_info.merge_list.first)
8726 {
8727 /*
8728 The user must have (SELECT_ACL | UPDATE_ACL | DELETE_ACL) on the
8729 underlying base tables, even if there are temporary tables with the same
8730 names.
8731
8732 From user's point of view, it might look as if the user must have these
8733 privileges on temporary tables to create a merge table over them. This is
8734 one of two cases when a set of privileges is required for operations on
8735 temporary tables (see also CREATE TABLE).
8736
8737 The reason for this behavior stems from the following facts:
8738
8739 - For merge tables, the underlying table privileges are checked only
8740 at CREATE TABLE / ALTER TABLE time.
8741
8742 In other words, once a merge table is created, the privileges of
8743 the underlying tables can be revoked, but the user will still have
8744 access to the merge table (provided that the user has privileges on
8745 the merge table itself).
8746
8747 - Temporary tables shadow base tables.
8748
8749 I.e. there might be temporary and base tables with the same name, and
8750 the temporary table takes the precedence in all operations.
8751
8752 - For temporary MERGE tables we do not track if their child tables are
8753 base or temporary. As result we can't guarantee that privilege check
8754 which was done in presence of temporary child will stay relevant later
8755 as this temporary table might be removed.
8756
8757 If SELECT_ACL | UPDATE_ACL | DELETE_ACL privileges were not checked for
8758 the underlying *base* tables, it would create a security breach as in
8759 Bug#12771903.
8760 */
8761
8762 if (check_table_access(thd, SELECT_ACL | UPDATE_ACL | DELETE_ACL,
8763 lex->create_info.merge_list.first,
8764 FALSE, UINT_MAX, FALSE))
8765 goto err;
8766 }
8767
8768 if (want_priv != CREATE_TMP_ACL &&
8769 check_grant(thd, want_priv, create_table, FALSE, 1, FALSE))
8770 goto err;
8771
8772 if (select_lex->item_list.elements)
8773 {
8774 /* Check permissions for used tables in CREATE TABLE ... SELECT */
8775 if (tables && check_table_access(thd, SELECT_ACL, tables, FALSE,
8776 UINT_MAX, FALSE))
8777 goto err;
8778 }
8779 else if (lex->create_info.options & HA_LEX_CREATE_TABLE_LIKE)
8780 {
8781 if (check_table_access(thd, SELECT_ACL, tables, FALSE, UINT_MAX, FALSE))
8782 goto err;
8783 }
8784
8785 if (check_fk_parent_table_access(thd, create_table->db,
8786 &lex->create_info, &lex->alter_info))
8787 goto err;
8788
8789 error= FALSE;
8790 err:
8791 DBUG_RETURN(error);
8792 }
8793
8794
8795 /**
8796 Check privileges for LOCK TABLES statement.
8797
8798 @param thd Thread context.
8799 @param tables List of tables to be locked.
8800
8801 @retval FALSE - Success.
8802 @retval TRUE - Failure.
8803 */
8804
8805 static bool lock_tables_precheck(THD *thd, TABLE_LIST *tables)
8806 {
8807 TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table();
8808
8809 for (TABLE_LIST *table= tables; table != first_not_own_table && table;
8810 table= table->next_global)
8811 {
8812 if (is_temporary_table(table))
8813 continue;
8814
8815 if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, table,
8816 FALSE, 1, FALSE))
8817 return TRUE;
8818 }
8819
8820 return FALSE;
8821 }
8822
8823
8824 /**
8825 negate given expression.
8826
8827 @param thd thread handler
8828 @param expr expression for negation
8829
8830 @return
8831 negated expression
8832 */
8833
8834 Item *negate_expression(THD *thd, Item *expr)
8835 {
8836 Item *negated;
8837 if (expr->type() == Item::FUNC_ITEM &&
8838 ((Item_func *) expr)->functype() == Item_func::NOT_FUNC)
8839 {
8840 /* it is NOT(NOT( ... )) */
8841 Item *arg= ((Item_func *) expr)->arguments()[0];
8842 enum_parsing_place place= thd->lex->current_select->parsing_place;
8843 if (arg->is_bool_func() || place == IN_WHERE || place == IN_HAVING)
8844 return arg;
8845 /*
8846 if it is not boolean function then we have to emulate value of
8847 not(not(a)), it will be a != 0
8848 */
8849 return new Item_func_ne(arg, new Item_int_0());
8850 }
8851
8852 if ((negated= expr->neg_transformer(thd)) != 0)
8853 return negated;
8854 return new Item_func_not(expr);
8855 }
8856
8857 /**
8858 Set the specified definer to the default value, which is the
8859 current user in the thread.
8860
8861 @param[in] thd thread handler
8862 @param[out] definer definer
8863 */
8864
8865 void get_default_definer(THD *thd, LEX_USER *definer)
8866 {
8867 const Security_context *sctx= thd->security_ctx;
8868
8869 definer->user.str= (char *) sctx->priv_user;
8870 definer->user.length= strlen(definer->user.str);
8871
8872 definer->host.str= (char *) sctx->priv_host;
8873 definer->host.length= strlen(definer->host.str);
8874
8875 definer->password= null_lex_str;
8876 definer->plugin= empty_lex_str;
8877 definer->auth= empty_lex_str;
8878 definer->uses_identified_with_clause= false;
8879 definer->uses_identified_by_clause= false;
8880 definer->uses_authentication_string_clause= false;
8881 definer->uses_identified_by_password_clause= false;
8882 }
8883
8884
8885 /**
8886 Create default definer for the specified THD.
8887
8888 @param[in] thd thread handler
8889
8890 @return
8891 - On success, return a valid pointer to the created and initialized
8892 LEX_USER, which contains definer information.
8893 - On error, return 0.
8894 */
8895
8896 LEX_USER *create_default_definer(THD *thd)
8897 {
8898 LEX_USER *definer;
8899
8900 if (! (definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER))))
8901 return 0;
8902
8903 thd->get_definer(definer);
8904
8905 return definer;
8906 }
8907
8908
8909 /**
8910 Create definer with the given user and host names.
8911
8912 @param[in] thd thread handler
8913 @param[in] user_name user name
8914 @param[in] host_name host name
8915
8916 @return
8917 - On success, return a valid pointer to the created and initialized
8918 LEX_USER, which contains definer information.
8919 - On error, return 0.
8920 */
8921
8922 LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name)
8923 {
8924 LEX_USER *definer;
8925
8926 /* Create and initialize. */
8927
8928 if (! (definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER))))
8929 return 0;
8930
8931 definer->user= *user_name;
8932 definer->host= *host_name;
8933 definer->password.str= NULL;
8934 definer->password.length= 0;
8935 definer->uses_authentication_string_clause= false;
8936 definer->uses_identified_by_clause= false;
8937 definer->uses_identified_by_password_clause= false;
8938 definer->uses_identified_with_clause= false;
8939 return definer;
8940 }
8941
8942
8943 /**
8944 Retuns information about user or current user.
8945
8946 @param[in] thd thread handler
8947 @param[in] user user
8948
8949 @return
8950 - On success, return a valid pointer to initialized
8951 LEX_USER, which contains user information.
8952 - On error, return 0.
8953 */
8954
8955 LEX_USER *get_current_user(THD *thd, LEX_USER *user)
8956 {
8957 if (!user->user.str) // current_user
8958 {
8959 LEX_USER *default_definer= create_default_definer(thd);
8960 if (default_definer)
8961 {
8962 /*
8963 Inherit parser semantics from the statement in which the user parameter
8964 was used.
8965 This is needed because a st_lex_user is both used as a component in an
8966 AST and as a specifier for a particular user in the ACL subsystem.
8967 */
8968 default_definer->uses_authentication_string_clause=
8969 user->uses_authentication_string_clause;
8970 default_definer->uses_identified_by_clause=
8971 user->uses_identified_by_clause;
8972 default_definer->uses_identified_by_password_clause=
8973 user->uses_identified_by_password_clause;
8974 default_definer->uses_identified_with_clause=
8975 user->uses_identified_with_clause;
8976 default_definer->plugin.str= user->plugin.str;
8977 default_definer->plugin.length= user->plugin.length;
8978 default_definer->auth.str= user->auth.str;
8979 default_definer->auth.length= user->auth.length;
8980 return default_definer;
8981 }
8982 }
8983
8984 return user;
8985 }
8986
8987
8988 /**
8989 Check that byte length of a string does not exceed some limit.
8990
8991 @param str string to be checked
8992 @param err_msg error message to be displayed if the string is too long
8993 @param max_length max length
8994
8995 @retval
8996 FALSE the passed string is not longer than max_length
8997 @retval
8998 TRUE the passed string is longer than max_length
8999
9000 NOTE
9001 The function is not used in existing code but can be useful later?
9002 */
9003
9004 bool check_string_byte_length(LEX_STRING *str, const char *err_msg,
9005 uint max_byte_length)
9006 {
9007 if (str->length <= max_byte_length)
9008 return FALSE;
9009
9010 my_error(ER_WRONG_STRING_LENGTH, MYF(0), str->str, err_msg, max_byte_length);
9011
9012 return TRUE;
9013 }
9014
9015
9016 /*
9017 Check that char length of a string does not exceed some limit.
9018
9019 SYNOPSIS
9020 check_string_char_length()
9021 str string to be checked
9022 err_msg error message to be displayed if the string is too long
9023 max_char_length max length in symbols
9024 cs string charset
9025
9026 RETURN
9027 FALSE the passed string is not longer than max_char_length
9028 TRUE the passed string is longer than max_char_length
9029 */
9030
9031
9032 bool check_string_char_length(LEX_STRING *str, const char *err_msg,
9033 uint max_char_length, const CHARSET_INFO *cs,
9034 bool no_error)
9035 {
9036 int well_formed_error;
9037 uint res= cs->cset->well_formed_len(cs, str->str, str->str + str->length,
9038 max_char_length, &well_formed_error);
9039
9040 if (!well_formed_error && str->length == res)
9041 return FALSE;
9042
9043 if (!no_error)
9044 {
9045 ErrConvString err(str->str, str->length, cs);
9046 my_error(ER_WRONG_STRING_LENGTH, MYF(0), err.ptr(), err_msg, max_char_length);
9047 }
9048 return TRUE;
9049 }
9050
9051
9052 /*
9053 Check if path does not contain mysql data home directory
9054 SYNOPSIS
9055 test_if_data_home_dir()
9056 dir directory
9057 conv_home_dir converted data home directory
9058 home_dir_len converted data home directory length
9059
9060 RETURN VALUES
9061 0 ok
9062 1 error
9063 */
9064 C_MODE_START
9065
9066 int test_if_data_home_dir(const char *dir)
9067 {
9068 char path[FN_REFLEN];
9069 int dir_len;
9070 DBUG_ENTER("test_if_data_home_dir");
9071
9072 if (!dir)
9073 DBUG_RETURN(0);
9074
9075 (void) fn_format(path, dir, "", "",
9076 (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
9077 dir_len= strlen(path);
9078 if (mysql_unpacked_real_data_home_len<= dir_len)
9079 {
9080 if (dir_len > mysql_unpacked_real_data_home_len &&
9081 path[mysql_unpacked_real_data_home_len] != FN_LIBCHAR)
9082 DBUG_RETURN(0);
9083
9084 if (lower_case_file_system)
9085 {
9086 if (!my_strnncoll(default_charset_info, (const uchar*) path,
9087 mysql_unpacked_real_data_home_len,
9088 (const uchar*) mysql_unpacked_real_data_home,
9089 mysql_unpacked_real_data_home_len))
9090 DBUG_RETURN(1);
9091 }
9092 else if (!memcmp(path, mysql_unpacked_real_data_home,
9093 mysql_unpacked_real_data_home_len))
9094 DBUG_RETURN(1);
9095 }
9096 DBUG_RETURN(0);
9097 }
9098
9099 C_MODE_END
9100
9101
9102 /**
9103 Check that host name string is valid.
9104
9105 @param[in] str string to be checked
9106
9107 @return Operation status
9108 @retval FALSE host name is ok
9109 @retval TRUE host name string is longer than max_length or
9110 has invalid symbols
9111 */
9112
9113 bool check_host_name(LEX_STRING *str)
9114 {
9115 const char *name= str->str;
9116 const char *end= str->str + str->length;
9117 if (check_string_byte_length(str, ER(ER_HOSTNAME), HOSTNAME_LENGTH))
9118 return TRUE;
9119
9120 while (name != end)
9121 {
9122 if (*name == '@')
9123 {
9124 my_printf_error(ER_UNKNOWN_ERROR,
9125 "Malformed hostname (illegal symbol: '%c')", MYF(0),
9126 *name);
9127 return TRUE;
9128 }
9129 name++;
9130 }
9131 return FALSE;
9132 }
9133
9134
9135 extern int MYSQLparse(class THD *thd); // from sql_yacc.cc
9136
9137
9138 /**
9139 This is a wrapper of MYSQLparse(). All the code should call parse_sql()
9140 instead of MYSQLparse().
9141
9142 @param thd Thread context.
9143 @param parser_state Parser state.
9144 @param creation_ctx Object creation context.
9145
9146 @return Error status.
9147 @retval FALSE on success.
9148 @retval TRUE on parsing error.
9149 */
9150
9151 bool parse_sql(THD *thd,
9152 Parser_state *parser_state,
9153 Object_creation_ctx *creation_ctx)
9154 {
9155 bool ret_value;
9156 DBUG_ASSERT(thd->m_parser_state == NULL);
9157 DBUG_ASSERT(thd->lex->m_sql_cmd == NULL);
9158
9159 MYSQL_QUERY_PARSE_START(thd->query());
9160 /* Backup creation context. */
9161
9162 Object_creation_ctx *backup_ctx= NULL;
9163
9164 if (creation_ctx)
9165 backup_ctx= creation_ctx->set_n_backup(thd);
9166
9167 /* Set parser state. */
9168
9169 thd->m_parser_state= parser_state;
9170
9171 parser_state->m_digest_psi= NULL;
9172 parser_state->m_lip.m_digest= NULL;
9173
9174 if (thd->m_digest != NULL)
9175 {
9176 /* Start Digest */
9177 parser_state->m_digest_psi= MYSQL_DIGEST_START(thd->m_statement_psi);
9178
9179 if (parser_state->m_input.m_compute_digest ||
9180 (parser_state->m_digest_psi != NULL))
9181 {
9182 /*
9183 If either:
9184 - the caller wants to compute a digest
9185 - the performance schema wants to compute a digest
9186 set the digest listener in the lexer.
9187 */
9188 parser_state->m_lip.m_digest= thd->m_digest;
9189 parser_state->m_lip.m_digest->m_digest_storage.m_charset_number= thd->charset()->number;
9190 }
9191 }
9192
9193 /* Parse the query. */
9194
9195 bool mysql_parse_status= MYSQLparse(thd) != 0;
9196
9197 /*
9198 Check that if MYSQLparse() failed either thd->is_error() is set, or an
9199 internal error handler is set.
9200
9201 The assert will not catch a situation where parsing fails without an
9202 error reported if an error handler exists. The problem is that the
9203 error handler might have intercepted the error, so thd->is_error() is
9204 not set. However, there is no way to be 100% sure here (the error
9205 handler might be for other errors than parsing one).
9206 */
9207
9208 DBUG_ASSERT(!mysql_parse_status ||
9209 (mysql_parse_status && thd->is_error()) ||
9210 (mysql_parse_status && thd->get_internal_handler()));
9211
9212 /* Reset parser state. */
9213
9214 thd->m_parser_state= NULL;
9215
9216 /* Restore creation context. */
9217
9218 if (creation_ctx)
9219 creation_ctx->restore_env(thd, backup_ctx);
9220
9221 /* That's it. */
9222
9223 ret_value= mysql_parse_status || thd->is_fatal_error;
9224
9225 if ((ret_value == 0) &&
9226 (parser_state->m_digest_psi != NULL))
9227 {
9228 /*
9229 On parsing success, record the digest in the performance schema.
9230 */
9231 DBUG_ASSERT(thd->m_digest != NULL);
9232 MYSQL_DIGEST_END(parser_state->m_digest_psi,
9233 & thd->m_digest->m_digest_storage);
9234 }
9235
9236 MYSQL_QUERY_PARSE_DONE(ret_value);
9237 return ret_value;
9238 }
9239
9240 /**
9241 @} (end of group Runtime_Environment)
9242 */
9243
9244
9245
9246 /**
9247 Check and merge "CHARACTER SET cs [ COLLATE cl ]" clause
9248
9249 @param cs character set pointer.
9250 @param cl collation pointer.
9251
9252 Check if collation "cl" is applicable to character set "cs".
9253
9254 If "cl" is NULL (e.g. when COLLATE clause is not specified),
9255 then simply "cs" is returned.
9256
9257 @return Error status.
9258 @retval NULL, if "cl" is not applicable to "cs".
9259 @retval pointer to merged CHARSET_INFO on success.
9260 */
9261
9262
9263 const CHARSET_INFO*
9264 merge_charset_and_collation(const CHARSET_INFO *cs, const CHARSET_INFO *cl)
9265 {
9266 if (cl)
9267 {
9268 if (!my_charset_same(cs, cl))
9269 {
9270 my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), cl->name, cs->csname);
9271 return NULL;
9272 }
9273 return cl;
9274 }
9275 return cs;
9276 }
9277