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