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