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