1 /* Copyright (c) 2000, 2017, Oracle and/or its affiliates.
2    Copyright (c) 2008, 2021, MariaDB
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; version 2 of the License.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 
13    You should have received a copy of the GNU General Public License
14    along with this program; if not, write to the Free Software
15    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1335  USA */
16 
17 #define MYSQL_LEX 1
18 #include "mariadb.h"
19 #include "sql_priv.h"
20 #include "sql_parse.h"        // sql_kill, *_precheck, *_prepare
21 #include "lock.h"             // try_transactional_lock,
22                               // check_transactional_lock,
23                               // set_handler_table_locks,
24                               // lock_global_read_lock,
25                               // make_global_read_lock_block_commit
26 #include "sql_base.h"         // open_tables, open_and_lock_tables,
27                               // lock_tables, unique_table,
28                               // close_thread_tables, is_temporary_table
29                               // table_cache.h
30 #include "sql_cache.h"        // QUERY_CACHE_FLAGS_SIZE, query_cache_*
31 #include "sql_show.h"         // mysqld_list_*, mysqld_show_*,
32                               // calc_sum_of_all_status
33 #include "mysqld.h"
34 #include "sql_locale.h"                         // my_locale_en_US
35 #include "log.h"                                // flush_error_log
36 #include "sql_view.h"         // mysql_create_view, mysql_drop_view
37 #include "sql_delete.h"       // mysql_delete
38 #include "sql_insert.h"       // mysql_insert
39 #include "sql_update.h"       // mysql_update, mysql_multi_update
40 #include "sql_partition.h"    // struct partition_info
41 #include "sql_db.h"           // mysql_change_db, mysql_create_db,
42                               // mysql_rm_db, mysql_upgrade_db,
43                               // mysql_alter_db,
44                               // check_db_dir_existence,
45                               // my_dbopt_cleanup
46 #include "sql_table.h"        // mysql_create_like_table,
47                               // mysql_create_table,
48                               // mysql_alter_table,
49                               // mysql_backup_table,
50                               // mysql_restore_table
51 #include "sql_reload.h"       // reload_acl_and_cache
52 #include "sql_admin.h"        // mysql_assign_to_keycache
53 #include "sql_connect.h"      // decrease_user_connections,
54                               // check_mqh,
55                               // reset_mqh
56 #include "sql_rename.h"       // mysql_rename_tables
57 #include "sql_tablespace.h"   // mysql_alter_tablespace
58 #include "hostname.h"         // hostname_cache_refresh
59 #include "sql_test.h"         // mysql_print_status
60 #include "sql_select.h"       // handle_select, mysql_select,
61                               // mysql_explain_union
62 #include "sql_load.h"         // mysql_load
63 #include "sql_servers.h"      // create_servers, alter_servers,
64                               // drop_servers, servers_reload
65 #include "sql_handler.h"      // mysql_ha_open, mysql_ha_close,
66                               // mysql_ha_read
67 #include "sql_binlog.h"       // mysql_client_binlog_statement
68 #include "sql_do.h"           // mysql_do
69 #include "sql_help.h"         // mysqld_help
70 #include "rpl_constants.h"    // Incident, INCIDENT_LOST_EVENTS
71 #include "log_event.h"
72 #include "sql_repl.h"
73 #include "rpl_filter.h"
74 #include "repl_failsafe.h"
75 #include <m_ctype.h>
76 #include <myisam.h>
77 #include <my_dir.h>
78 #include "rpl_mi.h"
79 
80 #include "sql_digest.h"
81 
82 #include "sp_head.h"
83 #include "sp.h"
84 #include "sp_cache.h"
85 #include "events.h"
86 #include "sql_trigger.h"
87 #include "transaction.h"
88 #include "sql_audit.h"
89 #include "sql_prepare.h"
90 #include "sql_cte.h"
91 #include "debug_sync.h"
92 #include "probes_mysql.h"
93 #include "set_var.h"
94 #include "sql_bootstrap.h"
95 #include "sql_sequence.h"
96 #include "opt_trace.h"
97 #include "mysql/psi/mysql_sp.h"
98 
99 #include "my_json_writer.h"
100 
101 #define PRIV_LOCK_TABLES (SELECT_ACL | LOCK_TABLES_ACL)
102 
103 #define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
104 
105 #ifdef WITH_ARIA_STORAGE_ENGINE
106 #include "../storage/maria/ha_maria.h"
107 #endif
108 
109 #include "wsrep.h"
110 #include "wsrep_mysqld.h"
111 #ifdef WITH_WSREP
112 #include "wsrep_thd.h"
113 #include "wsrep_trans_observer.h" /* wsrep transaction hooks */
114 
115 static bool wsrep_mysql_parse(THD *thd, char *rawbuf, uint length,
116                               Parser_state *parser_state,
117                               bool is_com_multi,
118                               bool is_next_command);
119 
120 #endif /* WITH_WSREP */
121 /**
122   @defgroup Runtime_Environment Runtime Environment
123   @{
124 */
125 
126 static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables);
127 static void sql_kill(THD *thd, longlong id, killed_state state, killed_type type);
128 static void sql_kill_user(THD *thd, LEX_USER *user, killed_state state);
129 static bool lock_tables_precheck(THD *thd, TABLE_LIST *tables);
130 static bool execute_show_status(THD *, TABLE_LIST *);
131 static bool check_rename_table(THD *, TABLE_LIST *, TABLE_LIST *);
132 static bool generate_incident_event(THD *thd);
133 static int  show_create_db(THD *thd, LEX *lex);
134 static bool alter_routine(THD *thd, LEX *lex);
135 static bool drop_routine(THD *thd, LEX *lex);
136 
137 const char *any_db="*any*";	// Special symbol for check_access
138 
139 const LEX_CSTRING command_name[257]={
140   { STRING_WITH_LEN("Sleep") },           //0
141   { STRING_WITH_LEN("Quit") },            //1
142   { STRING_WITH_LEN("Init DB") },         //2
143   { STRING_WITH_LEN("Query") },           //3
144   { STRING_WITH_LEN("Field List") },      //4
145   { STRING_WITH_LEN("Create DB") },       //5
146   { STRING_WITH_LEN("Drop DB") },         //6
147   { STRING_WITH_LEN("Refresh") },         //7
148   { STRING_WITH_LEN("Shutdown") },        //8
149   { STRING_WITH_LEN("Statistics") },      //9
150   { STRING_WITH_LEN("Processlist") },     //10
151   { STRING_WITH_LEN("Connect") },         //11
152   { STRING_WITH_LEN("Kill") },            //12
153   { STRING_WITH_LEN("Debug") },           //13
154   { STRING_WITH_LEN("Ping") },            //14
155   { STRING_WITH_LEN("Time") },            //15
156   { STRING_WITH_LEN("Delayed insert") },  //16
157   { STRING_WITH_LEN("Change user") },     //17
158   { STRING_WITH_LEN("Binlog Dump") },     //18
159   { STRING_WITH_LEN("Table Dump") },      //19
160   { STRING_WITH_LEN("Connect Out") },     //20
161   { STRING_WITH_LEN("Register Slave") },  //21
162   { STRING_WITH_LEN("Prepare") },         //22
163   { STRING_WITH_LEN("Execute") },         //23
164   { STRING_WITH_LEN("Long Data") },       //24
165   { STRING_WITH_LEN("Close stmt") },      //25
166   { STRING_WITH_LEN("Reset stmt") },      //26
167   { STRING_WITH_LEN("Set option") },      //27
168   { STRING_WITH_LEN("Fetch") },           //28
169   { STRING_WITH_LEN("Daemon") },          //29
170   { STRING_WITH_LEN("Unimpl get tid") },  //30
171   { STRING_WITH_LEN("Reset connection") },//31
172   { 0, 0 }, //32
173   { 0, 0 }, //33
174   { 0, 0 }, //34
175   { 0, 0 }, //35
176   { 0, 0 }, //36
177   { 0, 0 }, //37
178   { 0, 0 }, //38
179   { 0, 0 }, //39
180   { 0, 0 }, //40
181   { 0, 0 }, //41
182   { 0, 0 }, //42
183   { 0, 0 }, //43
184   { 0, 0 }, //44
185   { 0, 0 }, //45
186   { 0, 0 }, //46
187   { 0, 0 }, //47
188   { 0, 0 }, //48
189   { 0, 0 }, //49
190   { 0, 0 }, //50
191   { 0, 0 }, //51
192   { 0, 0 }, //52
193   { 0, 0 }, //53
194   { 0, 0 }, //54
195   { 0, 0 }, //55
196   { 0, 0 }, //56
197   { 0, 0 }, //57
198   { 0, 0 }, //58
199   { 0, 0 }, //59
200   { 0, 0 }, //60
201   { 0, 0 }, //61
202   { 0, 0 }, //62
203   { 0, 0 }, //63
204   { 0, 0 }, //64
205   { 0, 0 }, //65
206   { 0, 0 }, //66
207   { 0, 0 }, //67
208   { 0, 0 }, //68
209   { 0, 0 }, //69
210   { 0, 0 }, //70
211   { 0, 0 }, //71
212   { 0, 0 }, //72
213   { 0, 0 }, //73
214   { 0, 0 }, //74
215   { 0, 0 }, //75
216   { 0, 0 }, //76
217   { 0, 0 }, //77
218   { 0, 0 }, //78
219   { 0, 0 }, //79
220   { 0, 0 }, //80
221   { 0, 0 }, //81
222   { 0, 0 }, //82
223   { 0, 0 }, //83
224   { 0, 0 }, //84
225   { 0, 0 }, //85
226   { 0, 0 }, //86
227   { 0, 0 }, //87
228   { 0, 0 }, //88
229   { 0, 0 }, //89
230   { 0, 0 }, //90
231   { 0, 0 }, //91
232   { 0, 0 }, //92
233   { 0, 0 }, //93
234   { 0, 0 }, //94
235   { 0, 0 }, //95
236   { 0, 0 }, //96
237   { 0, 0 }, //97
238   { 0, 0 }, //98
239   { 0, 0 }, //99
240   { 0, 0 }, //100
241   { 0, 0 }, //101
242   { 0, 0 }, //102
243   { 0, 0 }, //103
244   { 0, 0 }, //104
245   { 0, 0 }, //105
246   { 0, 0 }, //106
247   { 0, 0 }, //107
248   { 0, 0 }, //108
249   { 0, 0 }, //109
250   { 0, 0 }, //110
251   { 0, 0 }, //111
252   { 0, 0 }, //112
253   { 0, 0 }, //113
254   { 0, 0 }, //114
255   { 0, 0 }, //115
256   { 0, 0 }, //116
257   { 0, 0 }, //117
258   { 0, 0 }, //118
259   { 0, 0 }, //119
260   { 0, 0 }, //120
261   { 0, 0 }, //121
262   { 0, 0 }, //122
263   { 0, 0 }, //123
264   { 0, 0 }, //124
265   { 0, 0 }, //125
266   { 0, 0 }, //126
267   { 0, 0 }, //127
268   { 0, 0 }, //128
269   { 0, 0 }, //129
270   { 0, 0 }, //130
271   { 0, 0 }, //131
272   { 0, 0 }, //132
273   { 0, 0 }, //133
274   { 0, 0 }, //134
275   { 0, 0 }, //135
276   { 0, 0 }, //136
277   { 0, 0 }, //137
278   { 0, 0 }, //138
279   { 0, 0 }, //139
280   { 0, 0 }, //140
281   { 0, 0 }, //141
282   { 0, 0 }, //142
283   { 0, 0 }, //143
284   { 0, 0 }, //144
285   { 0, 0 }, //145
286   { 0, 0 }, //146
287   { 0, 0 }, //147
288   { 0, 0 }, //148
289   { 0, 0 }, //149
290   { 0, 0 }, //150
291   { 0, 0 }, //151
292   { 0, 0 }, //152
293   { 0, 0 }, //153
294   { 0, 0 }, //154
295   { 0, 0 }, //155
296   { 0, 0 }, //156
297   { 0, 0 }, //157
298   { 0, 0 }, //158
299   { 0, 0 }, //159
300   { 0, 0 }, //160
301   { 0, 0 }, //161
302   { 0, 0 }, //162
303   { 0, 0 }, //163
304   { 0, 0 }, //164
305   { 0, 0 }, //165
306   { 0, 0 }, //166
307   { 0, 0 }, //167
308   { 0, 0 }, //168
309   { 0, 0 }, //169
310   { 0, 0 }, //170
311   { 0, 0 }, //171
312   { 0, 0 }, //172
313   { 0, 0 }, //173
314   { 0, 0 }, //174
315   { 0, 0 }, //175
316   { 0, 0 }, //176
317   { 0, 0 }, //177
318   { 0, 0 }, //178
319   { 0, 0 }, //179
320   { 0, 0 }, //180
321   { 0, 0 }, //181
322   { 0, 0 }, //182
323   { 0, 0 }, //183
324   { 0, 0 }, //184
325   { 0, 0 }, //185
326   { 0, 0 }, //186
327   { 0, 0 }, //187
328   { 0, 0 }, //188
329   { 0, 0 }, //189
330   { 0, 0 }, //190
331   { 0, 0 }, //191
332   { 0, 0 }, //192
333   { 0, 0 }, //193
334   { 0, 0 }, //194
335   { 0, 0 }, //195
336   { 0, 0 }, //196
337   { 0, 0 }, //197
338   { 0, 0 }, //198
339   { 0, 0 }, //199
340   { 0, 0 }, //200
341   { 0, 0 }, //201
342   { 0, 0 }, //202
343   { 0, 0 }, //203
344   { 0, 0 }, //204
345   { 0, 0 }, //205
346   { 0, 0 }, //206
347   { 0, 0 }, //207
348   { 0, 0 }, //208
349   { 0, 0 }, //209
350   { 0, 0 }, //210
351   { 0, 0 }, //211
352   { 0, 0 }, //212
353   { 0, 0 }, //213
354   { 0, 0 }, //214
355   { 0, 0 }, //215
356   { 0, 0 }, //216
357   { 0, 0 }, //217
358   { 0, 0 }, //218
359   { 0, 0 }, //219
360   { 0, 0 }, //220
361   { 0, 0 }, //221
362   { 0, 0 }, //222
363   { 0, 0 }, //223
364   { 0, 0 }, //224
365   { 0, 0 }, //225
366   { 0, 0 }, //226
367   { 0, 0 }, //227
368   { 0, 0 }, //228
369   { 0, 0 }, //229
370   { 0, 0 }, //230
371   { 0, 0 }, //231
372   { 0, 0 }, //232
373   { 0, 0 }, //233
374   { 0, 0 }, //234
375   { 0, 0 }, //235
376   { 0, 0 }, //236
377   { 0, 0 }, //237
378   { 0, 0 }, //238
379   { 0, 0 }, //239
380   { 0, 0 }, //240
381   { 0, 0 }, //241
382   { 0, 0 }, //242
383   { 0, 0 }, //243
384   { 0, 0 }, //244
385   { 0, 0 }, //245
386   { 0, 0 }, //246
387   { 0, 0 }, //247
388   { 0, 0 }, //248
389   { 0, 0 }, //249
390   { STRING_WITH_LEN("Bulk_execute") }, //250
391   { STRING_WITH_LEN("Slave_worker") }, //251
392   { STRING_WITH_LEN("Slave_IO") }, //252
393   { STRING_WITH_LEN("Slave_SQL") }, //253
394   { STRING_WITH_LEN("Com_multi") }, //254
395   { STRING_WITH_LEN("Error") }  // Last command number 255
396 };
397 
398 #ifdef HAVE_REPLICATION
399 /**
400   Returns true if all tables should be ignored.
401 */
all_tables_not_ok(THD * thd,TABLE_LIST * tables)402 inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables)
403 {
404   Rpl_filter *rpl_filter= thd->system_thread_info.rpl_sql_info->rpl_filter;
405   return rpl_filter->is_on() && tables && !thd->spcont &&
406          !rpl_filter->tables_ok(thd->db.str, tables);
407 }
408 #endif
409 
410 
some_non_temp_table_to_be_updated(THD * thd,TABLE_LIST * tables)411 static bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables)
412 {
413   for (TABLE_LIST *table= tables; table; table= table->next_global)
414   {
415     DBUG_ASSERT(table->db.str && table->table_name.str);
416     if (table->updating && !thd->find_tmp_table_share(table))
417       return 1;
418   }
419   return 0;
420 }
421 
422 
423 /*
424   Check whether the statement implicitly commits an active transaction.
425 
426   @param thd    Thread handle.
427   @param mask   Bitmask used for the SQL command match.
428 
429   @return 0     No implicit commit
430   @return 1     Do a commit
431 */
stmt_causes_implicit_commit(THD * thd,uint mask)432 bool stmt_causes_implicit_commit(THD *thd, uint mask)
433 {
434   LEX *lex= thd->lex;
435   bool skip= FALSE;
436   DBUG_ENTER("stmt_causes_implicit_commit");
437 
438   if (!(sql_command_flags[lex->sql_command] & mask))
439     DBUG_RETURN(FALSE);
440 
441   switch (lex->sql_command) {
442   case SQLCOM_ALTER_TABLE:
443   case SQLCOM_ALTER_SEQUENCE:
444     /* If ALTER TABLE of non-temporary table, do implicit commit */
445     skip= (lex->tmp_table());
446     break;
447   case SQLCOM_DROP_TABLE:
448   case SQLCOM_DROP_SEQUENCE:
449   case SQLCOM_CREATE_TABLE:
450   case SQLCOM_CREATE_SEQUENCE:
451     /*
452       If CREATE TABLE of non-temporary table and the table is not part
453       if a BEGIN GTID ... COMMIT group, do a implicit commit.
454       This ensures that CREATE ... SELECT will in the same GTID group on the
455       master and slave.
456     */
457     skip= (lex->tmp_table() ||
458            (thd->variables.option_bits & OPTION_GTID_BEGIN));
459     break;
460   case SQLCOM_SET_OPTION:
461     skip= lex->autocommit ? FALSE : TRUE;
462     break;
463   default:
464     break;
465   }
466 
467   DBUG_RETURN(!skip);
468 }
469 
470 
471 /**
472   Mark all commands that somehow changes a table.
473 
474   This is used to check number of updates / hour.
475 
476   sql_command is actually set to SQLCOM_END sometimes
477   so we need the +1 to include it in the array.
478 
479   See COMMAND_FLAG_xxx for different type of commands
480      2  - query that returns meaningful ROW_COUNT() -
481           a number of modified rows
482 */
483 
484 uint sql_command_flags[SQLCOM_END+1];
485 uint server_command_flags[COM_END+1];
486 
init_update_queries(void)487 void init_update_queries(void)
488 {
489   /* Initialize the server command flags array. */
490   memset(server_command_flags, 0, sizeof(server_command_flags));
491 
492   server_command_flags[COM_STATISTICS]= CF_SKIP_QUERY_ID | CF_SKIP_QUESTIONS | CF_SKIP_WSREP_CHECK;
493   server_command_flags[COM_PING]=       CF_SKIP_QUERY_ID | CF_SKIP_QUESTIONS | CF_SKIP_WSREP_CHECK | CF_NO_COM_MULTI;
494 
495   server_command_flags[COM_QUIT]= CF_SKIP_WSREP_CHECK;
496   server_command_flags[COM_PROCESS_INFO]= CF_SKIP_WSREP_CHECK;
497   server_command_flags[COM_PROCESS_KILL]= CF_SKIP_WSREP_CHECK;
498   server_command_flags[COM_SHUTDOWN]= CF_SKIP_WSREP_CHECK;
499   server_command_flags[COM_SLEEP]= CF_SKIP_WSREP_CHECK;
500   server_command_flags[COM_TIME]= CF_SKIP_WSREP_CHECK;
501   server_command_flags[COM_INIT_DB]= CF_SKIP_WSREP_CHECK;
502   server_command_flags[COM_END]= CF_SKIP_WSREP_CHECK;
503   for (uint i= COM_MDB_GAP_BEG; i <= COM_MDB_GAP_END; i++)
504   {
505     server_command_flags[i]= CF_SKIP_WSREP_CHECK;
506   }
507 
508   /*
509     COM_QUERY, COM_SET_OPTION and COM_STMT_XXX are allowed to pass the early
510     COM_xxx filter, they're checked later in mysql_execute_command().
511   */
512   server_command_flags[COM_QUERY]= CF_SKIP_WSREP_CHECK;
513   server_command_flags[COM_SET_OPTION]= CF_SKIP_WSREP_CHECK;
514   server_command_flags[COM_STMT_PREPARE]= CF_SKIP_QUESTIONS | CF_SKIP_WSREP_CHECK;
515   server_command_flags[COM_STMT_EXECUTE]= CF_SKIP_WSREP_CHECK;
516   server_command_flags[COM_STMT_FETCH]=   CF_SKIP_WSREP_CHECK;
517   server_command_flags[COM_STMT_CLOSE]= CF_SKIP_QUESTIONS | CF_SKIP_WSREP_CHECK;
518   server_command_flags[COM_STMT_RESET]= CF_SKIP_QUESTIONS | CF_SKIP_WSREP_CHECK;
519   server_command_flags[COM_STMT_EXECUTE]= CF_SKIP_WSREP_CHECK;
520   server_command_flags[COM_STMT_SEND_LONG_DATA]= CF_SKIP_WSREP_CHECK;
521   server_command_flags[COM_REGISTER_SLAVE]= CF_SKIP_WSREP_CHECK;
522   server_command_flags[COM_MULTI]= CF_SKIP_WSREP_CHECK | CF_NO_COM_MULTI;
523 
524   /* Initialize the sql command flags array. */
525   memset(sql_command_flags, 0, sizeof(sql_command_flags));
526 
527   /*
528     In general, DDL statements do not generate row events and do not go
529     through a cache before being written to the binary log. However, the
530     CREATE TABLE...SELECT is an exception because it may generate row
531     events. For that reason,  the SQLCOM_CREATE_TABLE  which represents
532     a CREATE TABLE, including the CREATE TABLE...SELECT, has the
533     CF_CAN_GENERATE_ROW_EVENTS flag. The distinction between a regular
534     CREATE TABLE and the CREATE TABLE...SELECT is made in other parts of
535     the code, in particular in the Query_log_event's constructor.
536   */
537   sql_command_flags[SQLCOM_CREATE_TABLE]=   CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
538                                             CF_AUTO_COMMIT_TRANS | CF_REPORT_PROGRESS |
539                                             CF_CAN_GENERATE_ROW_EVENTS |
540                                             CF_SCHEMA_CHANGE;
541   sql_command_flags[SQLCOM_CREATE_SEQUENCE]=  (CF_CHANGES_DATA |
542                                             CF_REEXECUTION_FRAGILE |
543                                             CF_AUTO_COMMIT_TRANS |
544                                             CF_SCHEMA_CHANGE);
545   sql_command_flags[SQLCOM_CREATE_INDEX]=   CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS |
546                                             CF_ADMIN_COMMAND | CF_REPORT_PROGRESS;
547   sql_command_flags[SQLCOM_ALTER_TABLE]=    CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND |
548                                             CF_AUTO_COMMIT_TRANS | CF_REPORT_PROGRESS |
549                                             CF_INSERTS_DATA | CF_ADMIN_COMMAND;
550   sql_command_flags[SQLCOM_ALTER_SEQUENCE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND |
551                                             CF_AUTO_COMMIT_TRANS | CF_SCHEMA_CHANGE |
552                                             CF_ADMIN_COMMAND;
553   sql_command_flags[SQLCOM_TRUNCATE]=       CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND |
554                                             CF_AUTO_COMMIT_TRANS;
555   sql_command_flags[SQLCOM_DROP_TABLE]=     CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_SCHEMA_CHANGE;
556   sql_command_flags[SQLCOM_DROP_SEQUENCE]=  CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_SCHEMA_CHANGE;
557   sql_command_flags[SQLCOM_LOAD]=           CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
558                                             CF_CAN_GENERATE_ROW_EVENTS | CF_REPORT_PROGRESS |
559                                             CF_INSERTS_DATA;
560   sql_command_flags[SQLCOM_CREATE_DB]=      CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_DB_CHANGE;
561   sql_command_flags[SQLCOM_DROP_DB]=        CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_DB_CHANGE;
562   sql_command_flags[SQLCOM_CREATE_PACKAGE]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
563   sql_command_flags[SQLCOM_DROP_PACKAGE]=   CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
564   sql_command_flags[SQLCOM_CREATE_PACKAGE_BODY]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
565   sql_command_flags[SQLCOM_DROP_PACKAGE_BODY]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
566   sql_command_flags[SQLCOM_ALTER_DB_UPGRADE]= CF_AUTO_COMMIT_TRANS;
567   sql_command_flags[SQLCOM_ALTER_DB]=       CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_DB_CHANGE;
568   sql_command_flags[SQLCOM_RENAME_TABLE]=   CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_ADMIN_COMMAND;
569   sql_command_flags[SQLCOM_DROP_INDEX]=     CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS |
570                                             CF_REPORT_PROGRESS | CF_ADMIN_COMMAND;
571   sql_command_flags[SQLCOM_CREATE_VIEW]=    CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
572                                             CF_AUTO_COMMIT_TRANS;
573   sql_command_flags[SQLCOM_DROP_VIEW]=      CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
574   sql_command_flags[SQLCOM_CREATE_TRIGGER]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
575   sql_command_flags[SQLCOM_DROP_TRIGGER]=   CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
576   sql_command_flags[SQLCOM_CREATE_EVENT]=   CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
577   sql_command_flags[SQLCOM_ALTER_EVENT]=    CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
578   sql_command_flags[SQLCOM_DROP_EVENT]=     CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
579 
580   sql_command_flags[SQLCOM_UPDATE]=	    CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
581                                             CF_CAN_GENERATE_ROW_EVENTS |
582                                             CF_OPTIMIZER_TRACE |
583                                             CF_CAN_BE_EXPLAINED |
584                                             CF_UPDATES_DATA |
585                                             CF_PS_ARRAY_BINDING_SAFE;
586   sql_command_flags[SQLCOM_UPDATE_MULTI]=   CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
587                                             CF_CAN_GENERATE_ROW_EVENTS |
588                                             CF_OPTIMIZER_TRACE |
589                                             CF_CAN_BE_EXPLAINED |
590                                             CF_UPDATES_DATA |
591                                             CF_PS_ARRAY_BINDING_SAFE;
592   sql_command_flags[SQLCOM_INSERT]=	    CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
593                                             CF_CAN_GENERATE_ROW_EVENTS |
594                                             CF_OPTIMIZER_TRACE |
595                                             CF_CAN_BE_EXPLAINED |
596                                             CF_INSERTS_DATA |
597                                             CF_PS_ARRAY_BINDING_SAFE |
598                                             CF_PS_ARRAY_BINDING_OPTIMIZED;
599   sql_command_flags[SQLCOM_INSERT_SELECT]=  CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
600                                             CF_CAN_GENERATE_ROW_EVENTS |
601                                             CF_OPTIMIZER_TRACE |
602                                             CF_CAN_BE_EXPLAINED |
603                                             CF_INSERTS_DATA;
604   sql_command_flags[SQLCOM_DELETE]=         CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
605                                             CF_CAN_GENERATE_ROW_EVENTS |
606                                             CF_OPTIMIZER_TRACE |
607                                             CF_CAN_BE_EXPLAINED |
608                                             CF_DELETES_DATA |
609                                             CF_PS_ARRAY_BINDING_SAFE;
610   sql_command_flags[SQLCOM_DELETE_MULTI]=   CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
611                                             CF_CAN_GENERATE_ROW_EVENTS |
612                                             CF_OPTIMIZER_TRACE |
613                                             CF_CAN_BE_EXPLAINED |
614                                             CF_DELETES_DATA;
615   sql_command_flags[SQLCOM_REPLACE]=        CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
616                                             CF_CAN_GENERATE_ROW_EVENTS |
617                                             CF_OPTIMIZER_TRACE |
618                                             CF_CAN_BE_EXPLAINED |
619                                             CF_INSERTS_DATA |
620                                             CF_PS_ARRAY_BINDING_SAFE |
621                                             CF_PS_ARRAY_BINDING_OPTIMIZED;
622   sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
623                                             CF_CAN_GENERATE_ROW_EVENTS |
624                                             CF_OPTIMIZER_TRACE |
625                                             CF_CAN_BE_EXPLAINED |
626                                             CF_INSERTS_DATA;
627   sql_command_flags[SQLCOM_SELECT]=         CF_REEXECUTION_FRAGILE |
628                                             CF_CAN_GENERATE_ROW_EVENTS |
629                                             CF_OPTIMIZER_TRACE |
630                                             CF_CAN_BE_EXPLAINED;
631   // (1) so that subquery is traced when doing "SET @var = (subquery)"
632   /*
633     @todo SQLCOM_SET_OPTION should have CF_CAN_GENERATE_ROW_EVENTS
634     set, because it may invoke a stored function that generates row
635     events. /Sven
636   */
637   sql_command_flags[SQLCOM_SET_OPTION]=     CF_REEXECUTION_FRAGILE |
638                                             CF_AUTO_COMMIT_TRANS |
639                                             CF_CAN_GENERATE_ROW_EVENTS |
640                                             CF_OPTIMIZER_TRACE; // (1)
641   // (1) so that subquery is traced when doing "DO @var := (subquery)"
642   sql_command_flags[SQLCOM_DO]=             CF_REEXECUTION_FRAGILE |
643                                             CF_CAN_GENERATE_ROW_EVENTS |
644                                             CF_OPTIMIZER_TRACE; // (1)
645 
646   sql_command_flags[SQLCOM_SHOW_STATUS_PROC]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
647   sql_command_flags[SQLCOM_SHOW_STATUS_PACKAGE]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
648   sql_command_flags[SQLCOM_SHOW_STATUS_PACKAGE_BODY]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
649   sql_command_flags[SQLCOM_SHOW_STATUS]=      CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
650   sql_command_flags[SQLCOM_SHOW_DATABASES]=   CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
651   sql_command_flags[SQLCOM_SHOW_TRIGGERS]=    CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
652   sql_command_flags[SQLCOM_SHOW_EVENTS]=      CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
653   sql_command_flags[SQLCOM_SHOW_OPEN_TABLES]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
654   sql_command_flags[SQLCOM_SHOW_PLUGINS]=     CF_STATUS_COMMAND;
655   sql_command_flags[SQLCOM_SHOW_GENERIC]=     CF_STATUS_COMMAND;
656   sql_command_flags[SQLCOM_SHOW_FIELDS]=      CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
657   sql_command_flags[SQLCOM_SHOW_KEYS]=        CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
658   sql_command_flags[SQLCOM_SHOW_VARIABLES]=   CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
659   sql_command_flags[SQLCOM_SHOW_CHARSETS]=    CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
660   sql_command_flags[SQLCOM_SHOW_COLLATIONS]=  CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
661   sql_command_flags[SQLCOM_SHOW_BINLOGS]=     CF_STATUS_COMMAND;
662   sql_command_flags[SQLCOM_SHOW_SLAVE_HOSTS]= CF_STATUS_COMMAND;
663   sql_command_flags[SQLCOM_SHOW_BINLOG_EVENTS]= CF_STATUS_COMMAND;
664   sql_command_flags[SQLCOM_SHOW_STORAGE_ENGINES]= CF_STATUS_COMMAND;
665   sql_command_flags[SQLCOM_SHOW_AUTHORS]=     CF_STATUS_COMMAND;
666   sql_command_flags[SQLCOM_SHOW_CONTRIBUTORS]= CF_STATUS_COMMAND;
667   sql_command_flags[SQLCOM_SHOW_PRIVILEGES]=  CF_STATUS_COMMAND;
668   sql_command_flags[SQLCOM_SHOW_WARNS]=       CF_STATUS_COMMAND | CF_DIAGNOSTIC_STMT;
669   sql_command_flags[SQLCOM_SHOW_ERRORS]=      CF_STATUS_COMMAND | CF_DIAGNOSTIC_STMT;
670   sql_command_flags[SQLCOM_SHOW_ENGINE_STATUS]= CF_STATUS_COMMAND;
671   sql_command_flags[SQLCOM_SHOW_ENGINE_MUTEX]= CF_STATUS_COMMAND;
672   sql_command_flags[SQLCOM_SHOW_ENGINE_LOGS]= CF_STATUS_COMMAND;
673   sql_command_flags[SQLCOM_SHOW_EXPLAIN]= CF_STATUS_COMMAND;
674   sql_command_flags[SQLCOM_SHOW_PROCESSLIST]= CF_STATUS_COMMAND;
675   sql_command_flags[SQLCOM_SHOW_GRANTS]=      CF_STATUS_COMMAND;
676   sql_command_flags[SQLCOM_SHOW_CREATE_USER]= CF_STATUS_COMMAND;
677   sql_command_flags[SQLCOM_SHOW_CREATE_DB]=   CF_STATUS_COMMAND;
678   sql_command_flags[SQLCOM_SHOW_CREATE]=  CF_STATUS_COMMAND;
679   sql_command_flags[SQLCOM_SHOW_BINLOG_STAT]= CF_STATUS_COMMAND;
680   sql_command_flags[SQLCOM_SHOW_SLAVE_STAT]=  CF_STATUS_COMMAND;
681   sql_command_flags[SQLCOM_SHOW_CREATE_PROC]= CF_STATUS_COMMAND;
682   sql_command_flags[SQLCOM_SHOW_CREATE_FUNC]= CF_STATUS_COMMAND;
683   sql_command_flags[SQLCOM_SHOW_CREATE_PACKAGE]= CF_STATUS_COMMAND;
684   sql_command_flags[SQLCOM_SHOW_CREATE_PACKAGE_BODY]= CF_STATUS_COMMAND;
685   sql_command_flags[SQLCOM_SHOW_CREATE_TRIGGER]=  CF_STATUS_COMMAND;
686   sql_command_flags[SQLCOM_SHOW_STATUS_FUNC]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
687   sql_command_flags[SQLCOM_SHOW_PROC_CODE]=   CF_STATUS_COMMAND;
688   sql_command_flags[SQLCOM_SHOW_FUNC_CODE]=   CF_STATUS_COMMAND;
689   sql_command_flags[SQLCOM_SHOW_PACKAGE_BODY_CODE]= CF_STATUS_COMMAND;
690   sql_command_flags[SQLCOM_SHOW_CREATE_EVENT]= CF_STATUS_COMMAND;
691   sql_command_flags[SQLCOM_SHOW_PROFILES]=    CF_STATUS_COMMAND;
692   sql_command_flags[SQLCOM_SHOW_PROFILE]=     CF_STATUS_COMMAND;
693   sql_command_flags[SQLCOM_BINLOG_BASE64_EVENT]= CF_STATUS_COMMAND | CF_CAN_GENERATE_ROW_EVENTS;
694   sql_command_flags[SQLCOM_SHOW_TABLES]=       (CF_STATUS_COMMAND | CF_SHOW_TABLE_COMMAND | CF_REEXECUTION_FRAGILE);
695   sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]= (CF_STATUS_COMMAND | CF_SHOW_TABLE_COMMAND | CF_REEXECUTION_FRAGILE);
696 
697 
698   sql_command_flags[SQLCOM_CREATE_USER]=       CF_CHANGES_DATA;
699   sql_command_flags[SQLCOM_RENAME_USER]=       CF_CHANGES_DATA;
700   sql_command_flags[SQLCOM_DROP_USER]=         CF_CHANGES_DATA;
701   sql_command_flags[SQLCOM_ALTER_USER]=        CF_CHANGES_DATA;
702   sql_command_flags[SQLCOM_CREATE_ROLE]=       CF_CHANGES_DATA;
703   sql_command_flags[SQLCOM_GRANT]=             CF_CHANGES_DATA;
704   sql_command_flags[SQLCOM_GRANT_ROLE]=        CF_CHANGES_DATA;
705   sql_command_flags[SQLCOM_REVOKE]=            CF_CHANGES_DATA;
706   sql_command_flags[SQLCOM_REVOKE_ROLE]=       CF_CHANGES_DATA;
707   sql_command_flags[SQLCOM_OPTIMIZE]=          CF_CHANGES_DATA;
708   sql_command_flags[SQLCOM_CREATE_FUNCTION]=   CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
709   sql_command_flags[SQLCOM_CREATE_PROCEDURE]=  CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
710   sql_command_flags[SQLCOM_CREATE_SPFUNCTION]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
711   sql_command_flags[SQLCOM_DROP_PROCEDURE]=    CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
712   sql_command_flags[SQLCOM_DROP_FUNCTION]=     CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
713   sql_command_flags[SQLCOM_ALTER_PROCEDURE]=   CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
714   sql_command_flags[SQLCOM_ALTER_FUNCTION]=    CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
715   sql_command_flags[SQLCOM_INSTALL_PLUGIN]=    CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
716   sql_command_flags[SQLCOM_UNINSTALL_PLUGIN]=  CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
717 
718   /*
719     The following is used to preserver CF_ROW_COUNT during the
720     a CALL or EXECUTE statement, so the value generated by the
721     last called (or executed) statement is preserved.
722     See mysql_execute_command() for how CF_ROW_COUNT is used.
723   */
724   /*
725     (1): without it, in "CALL some_proc((subq))", subquery would not be
726     traced.
727   */
728   sql_command_flags[SQLCOM_CALL]=      CF_REEXECUTION_FRAGILE |
729                                        CF_CAN_GENERATE_ROW_EVENTS |
730                                        CF_OPTIMIZER_TRACE; // (1)
731   sql_command_flags[SQLCOM_EXECUTE]=   CF_CAN_GENERATE_ROW_EVENTS;
732   sql_command_flags[SQLCOM_EXECUTE_IMMEDIATE]= CF_CAN_GENERATE_ROW_EVENTS;
733   sql_command_flags[SQLCOM_COMPOUND]=  CF_CAN_GENERATE_ROW_EVENTS;
734 
735   /*
736     We don't want to change to statement based replication for these commands
737   */
738   sql_command_flags[SQLCOM_ROLLBACK]|= CF_FORCE_ORIGINAL_BINLOG_FORMAT;
739   /* We don't want to replicate ALTER TABLE for temp tables in row format */
740   sql_command_flags[SQLCOM_ALTER_TABLE]|= CF_FORCE_ORIGINAL_BINLOG_FORMAT;
741   /* We don't want to replicate TRUNCATE for temp tables in row format */
742   sql_command_flags[SQLCOM_TRUNCATE]|= CF_FORCE_ORIGINAL_BINLOG_FORMAT;
743   /* We don't want to replicate DROP for temp tables in row format */
744   sql_command_flags[SQLCOM_DROP_TABLE]|= CF_FORCE_ORIGINAL_BINLOG_FORMAT;
745   sql_command_flags[SQLCOM_DROP_SEQUENCE]|= CF_FORCE_ORIGINAL_BINLOG_FORMAT;
746   /* We don't want to replicate CREATE/DROP INDEX for temp tables in row format */
747   sql_command_flags[SQLCOM_CREATE_INDEX]|= CF_FORCE_ORIGINAL_BINLOG_FORMAT;
748   sql_command_flags[SQLCOM_DROP_INDEX]|= CF_FORCE_ORIGINAL_BINLOG_FORMAT;
749   /* One can change replication mode with SET */
750   sql_command_flags[SQLCOM_SET_OPTION]|= CF_FORCE_ORIGINAL_BINLOG_FORMAT;
751 
752   /*
753     The following admin table operations are allowed
754     on log tables.
755   */
756   sql_command_flags[SQLCOM_REPAIR]=    CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS |
757                                        CF_REPORT_PROGRESS | CF_ADMIN_COMMAND;
758   sql_command_flags[SQLCOM_OPTIMIZE]|= CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS |
759                                        CF_REPORT_PROGRESS | CF_ADMIN_COMMAND;
760   sql_command_flags[SQLCOM_ANALYZE]=   CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS |
761                                        CF_REPORT_PROGRESS | CF_ADMIN_COMMAND;
762   sql_command_flags[SQLCOM_CHECK]=     CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS |
763                                        CF_REPORT_PROGRESS | CF_ADMIN_COMMAND;
764   sql_command_flags[SQLCOM_CHECKSUM]=  CF_REPORT_PROGRESS;
765 
766   sql_command_flags[SQLCOM_CREATE_USER]|=       CF_AUTO_COMMIT_TRANS;
767   sql_command_flags[SQLCOM_ALTER_USER]|=        CF_AUTO_COMMIT_TRANS;
768   sql_command_flags[SQLCOM_DROP_USER]|=         CF_AUTO_COMMIT_TRANS;
769   sql_command_flags[SQLCOM_RENAME_USER]|=       CF_AUTO_COMMIT_TRANS;
770   sql_command_flags[SQLCOM_CREATE_ROLE]|=       CF_AUTO_COMMIT_TRANS;
771   sql_command_flags[SQLCOM_DROP_ROLE]|=         CF_AUTO_COMMIT_TRANS;
772   sql_command_flags[SQLCOM_REVOKE]|=            CF_AUTO_COMMIT_TRANS;
773   sql_command_flags[SQLCOM_REVOKE_ALL]=         CF_AUTO_COMMIT_TRANS;
774   sql_command_flags[SQLCOM_REVOKE_ROLE]|=       CF_AUTO_COMMIT_TRANS;
775   sql_command_flags[SQLCOM_GRANT]|=             CF_AUTO_COMMIT_TRANS;
776   sql_command_flags[SQLCOM_GRANT_ROLE]|=        CF_AUTO_COMMIT_TRANS;
777 
778   sql_command_flags[SQLCOM_FLUSH]=              CF_AUTO_COMMIT_TRANS;
779   sql_command_flags[SQLCOM_RESET]=              CF_AUTO_COMMIT_TRANS;
780   sql_command_flags[SQLCOM_CREATE_SERVER]=      CF_AUTO_COMMIT_TRANS;
781   sql_command_flags[SQLCOM_ALTER_SERVER]=       CF_AUTO_COMMIT_TRANS;
782   sql_command_flags[SQLCOM_DROP_SERVER]=        CF_AUTO_COMMIT_TRANS;
783   sql_command_flags[SQLCOM_BACKUP]=             CF_AUTO_COMMIT_TRANS;
784   sql_command_flags[SQLCOM_BACKUP_LOCK]=        CF_AUTO_COMMIT_TRANS;
785 
786   /*
787     The following statements can deal with temporary tables,
788     so temporary tables should be pre-opened for those statements to
789     simplify privilege checking.
790 
791     There are other statements that deal with temporary tables and open
792     them, but which are not listed here. The thing is that the order of
793     pre-opening temporary tables for those statements is somewhat custom.
794 
795     Note that SQLCOM_RENAME_TABLE should not be in this list!
796   */
797   sql_command_flags[SQLCOM_CREATE_TABLE]|=    CF_PREOPEN_TMP_TABLES;
798   sql_command_flags[SQLCOM_CREATE_INDEX]|=    CF_PREOPEN_TMP_TABLES;
799   sql_command_flags[SQLCOM_ALTER_TABLE]|=     CF_PREOPEN_TMP_TABLES;
800   sql_command_flags[SQLCOM_TRUNCATE]|=        CF_PREOPEN_TMP_TABLES;
801   sql_command_flags[SQLCOM_LOAD]|=            CF_PREOPEN_TMP_TABLES;
802   sql_command_flags[SQLCOM_DROP_INDEX]|=      CF_PREOPEN_TMP_TABLES;
803   sql_command_flags[SQLCOM_UPDATE]|=          CF_PREOPEN_TMP_TABLES;
804   sql_command_flags[SQLCOM_UPDATE_MULTI]|=    CF_PREOPEN_TMP_TABLES;
805   sql_command_flags[SQLCOM_INSERT_SELECT]|=   CF_PREOPEN_TMP_TABLES;
806   sql_command_flags[SQLCOM_DELETE]|=          CF_PREOPEN_TMP_TABLES;
807   sql_command_flags[SQLCOM_DELETE_MULTI]|=    CF_PREOPEN_TMP_TABLES;
808   sql_command_flags[SQLCOM_REPLACE_SELECT]|=  CF_PREOPEN_TMP_TABLES;
809   sql_command_flags[SQLCOM_SELECT]|=          CF_PREOPEN_TMP_TABLES;
810   sql_command_flags[SQLCOM_SET_OPTION]|=      CF_PREOPEN_TMP_TABLES;
811   sql_command_flags[SQLCOM_DO]|=              CF_PREOPEN_TMP_TABLES;
812   sql_command_flags[SQLCOM_HA_OPEN]|=         CF_PREOPEN_TMP_TABLES;
813   sql_command_flags[SQLCOM_CALL]|=            CF_PREOPEN_TMP_TABLES;
814   sql_command_flags[SQLCOM_CHECKSUM]|=        CF_PREOPEN_TMP_TABLES;
815   sql_command_flags[SQLCOM_ANALYZE]|=         CF_PREOPEN_TMP_TABLES;
816   sql_command_flags[SQLCOM_CHECK]|=           CF_PREOPEN_TMP_TABLES;
817   sql_command_flags[SQLCOM_OPTIMIZE]|=        CF_PREOPEN_TMP_TABLES;
818   sql_command_flags[SQLCOM_REPAIR]|=          CF_PREOPEN_TMP_TABLES;
819   sql_command_flags[SQLCOM_PRELOAD_KEYS]|=    CF_PREOPEN_TMP_TABLES;
820   sql_command_flags[SQLCOM_ASSIGN_TO_KEYCACHE]|= CF_PREOPEN_TMP_TABLES;
821 
822   /*
823     DDL statements that should start with closing opened handlers.
824 
825     We use this flag only for statements for which open HANDLERs
826     have to be closed before temporary tables are pre-opened.
827   */
828   sql_command_flags[SQLCOM_CREATE_TABLE]|=    CF_HA_CLOSE;
829   sql_command_flags[SQLCOM_CREATE_SEQUENCE]|= CF_HA_CLOSE;
830   sql_command_flags[SQLCOM_DROP_TABLE]|=      CF_HA_CLOSE;
831   sql_command_flags[SQLCOM_DROP_SEQUENCE]|=   CF_HA_CLOSE;
832   sql_command_flags[SQLCOM_ALTER_TABLE]|=     CF_HA_CLOSE;
833   sql_command_flags[SQLCOM_TRUNCATE]|=        CF_HA_CLOSE;
834   sql_command_flags[SQLCOM_REPAIR]|=          CF_HA_CLOSE;
835   sql_command_flags[SQLCOM_OPTIMIZE]|=        CF_HA_CLOSE;
836   sql_command_flags[SQLCOM_ANALYZE]|=         CF_HA_CLOSE;
837   sql_command_flags[SQLCOM_CHECK]|=           CF_HA_CLOSE;
838   sql_command_flags[SQLCOM_CREATE_INDEX]|=    CF_HA_CLOSE;
839   sql_command_flags[SQLCOM_DROP_INDEX]|=      CF_HA_CLOSE;
840   sql_command_flags[SQLCOM_PRELOAD_KEYS]|=    CF_HA_CLOSE;
841   sql_command_flags[SQLCOM_ASSIGN_TO_KEYCACHE]|=  CF_HA_CLOSE;
842 
843   /*
844     Mark statements that always are disallowed in read-only
845     transactions. Note that according to the SQL standard,
846     even temporary table DDL should be disallowed.
847   */
848   sql_command_flags[SQLCOM_CREATE_TABLE]|=     CF_DISALLOW_IN_RO_TRANS;
849   sql_command_flags[SQLCOM_CREATE_SEQUENCE]|=  CF_DISALLOW_IN_RO_TRANS;
850   sql_command_flags[SQLCOM_ALTER_TABLE]|=      CF_DISALLOW_IN_RO_TRANS;
851   sql_command_flags[SQLCOM_DROP_TABLE]|=       CF_DISALLOW_IN_RO_TRANS;
852   sql_command_flags[SQLCOM_DROP_SEQUENCE]|=    CF_DISALLOW_IN_RO_TRANS;
853   sql_command_flags[SQLCOM_RENAME_TABLE]|=     CF_DISALLOW_IN_RO_TRANS;
854   sql_command_flags[SQLCOM_CREATE_INDEX]|=     CF_DISALLOW_IN_RO_TRANS;
855   sql_command_flags[SQLCOM_DROP_INDEX]|=       CF_DISALLOW_IN_RO_TRANS;
856   sql_command_flags[SQLCOM_CREATE_DB]|=        CF_DISALLOW_IN_RO_TRANS;
857   sql_command_flags[SQLCOM_DROP_DB]|=          CF_DISALLOW_IN_RO_TRANS;
858   sql_command_flags[SQLCOM_CREATE_PACKAGE]|=   CF_DISALLOW_IN_RO_TRANS;
859   sql_command_flags[SQLCOM_DROP_PACKAGE]|=     CF_DISALLOW_IN_RO_TRANS;
860   sql_command_flags[SQLCOM_CREATE_PACKAGE_BODY]|= CF_DISALLOW_IN_RO_TRANS;
861   sql_command_flags[SQLCOM_DROP_PACKAGE_BODY]|= CF_DISALLOW_IN_RO_TRANS;
862   sql_command_flags[SQLCOM_ALTER_DB_UPGRADE]|= CF_DISALLOW_IN_RO_TRANS;
863   sql_command_flags[SQLCOM_ALTER_DB]|=         CF_DISALLOW_IN_RO_TRANS;
864   sql_command_flags[SQLCOM_CREATE_VIEW]|=      CF_DISALLOW_IN_RO_TRANS;
865   sql_command_flags[SQLCOM_DROP_VIEW]|=        CF_DISALLOW_IN_RO_TRANS;
866   sql_command_flags[SQLCOM_CREATE_TRIGGER]|=   CF_DISALLOW_IN_RO_TRANS;
867   sql_command_flags[SQLCOM_DROP_TRIGGER]|=     CF_DISALLOW_IN_RO_TRANS;
868   sql_command_flags[SQLCOM_CREATE_EVENT]|=     CF_DISALLOW_IN_RO_TRANS;
869   sql_command_flags[SQLCOM_ALTER_EVENT]|=      CF_DISALLOW_IN_RO_TRANS;
870   sql_command_flags[SQLCOM_DROP_EVENT]|=       CF_DISALLOW_IN_RO_TRANS;
871   sql_command_flags[SQLCOM_CREATE_USER]|=      CF_DISALLOW_IN_RO_TRANS;
872   sql_command_flags[SQLCOM_ALTER_USER]|=       CF_DISALLOW_IN_RO_TRANS;
873   sql_command_flags[SQLCOM_RENAME_USER]|=      CF_DISALLOW_IN_RO_TRANS;
874   sql_command_flags[SQLCOM_DROP_USER]|=        CF_DISALLOW_IN_RO_TRANS;
875   sql_command_flags[SQLCOM_CREATE_SERVER]|=    CF_DISALLOW_IN_RO_TRANS;
876   sql_command_flags[SQLCOM_ALTER_SERVER]|=     CF_DISALLOW_IN_RO_TRANS;
877   sql_command_flags[SQLCOM_DROP_SERVER]|=      CF_DISALLOW_IN_RO_TRANS;
878   sql_command_flags[SQLCOM_CREATE_FUNCTION]|=  CF_DISALLOW_IN_RO_TRANS;
879   sql_command_flags[SQLCOM_CREATE_PROCEDURE]|= CF_DISALLOW_IN_RO_TRANS;
880   sql_command_flags[SQLCOM_CREATE_SPFUNCTION]|=CF_DISALLOW_IN_RO_TRANS;
881   sql_command_flags[SQLCOM_DROP_PROCEDURE]|=   CF_DISALLOW_IN_RO_TRANS;
882   sql_command_flags[SQLCOM_DROP_FUNCTION]|=    CF_DISALLOW_IN_RO_TRANS;
883   sql_command_flags[SQLCOM_ALTER_PROCEDURE]|=  CF_DISALLOW_IN_RO_TRANS;
884   sql_command_flags[SQLCOM_ALTER_FUNCTION]|=   CF_DISALLOW_IN_RO_TRANS;
885   sql_command_flags[SQLCOM_TRUNCATE]|=         CF_DISALLOW_IN_RO_TRANS;
886   sql_command_flags[SQLCOM_ALTER_TABLESPACE]|= CF_DISALLOW_IN_RO_TRANS;
887   sql_command_flags[SQLCOM_REPAIR]|=           CF_DISALLOW_IN_RO_TRANS;
888   sql_command_flags[SQLCOM_OPTIMIZE]|=         CF_DISALLOW_IN_RO_TRANS;
889   sql_command_flags[SQLCOM_GRANT]|=            CF_DISALLOW_IN_RO_TRANS;
890   sql_command_flags[SQLCOM_REVOKE]|=           CF_DISALLOW_IN_RO_TRANS;
891   sql_command_flags[SQLCOM_REVOKE_ALL]|=       CF_DISALLOW_IN_RO_TRANS;
892   sql_command_flags[SQLCOM_INSTALL_PLUGIN]|=   CF_DISALLOW_IN_RO_TRANS;
893   sql_command_flags[SQLCOM_UNINSTALL_PLUGIN]|= CF_DISALLOW_IN_RO_TRANS;
894 #ifdef WITH_WSREP
895   /*
896     Statements for which some errors are ignored when
897     wsrep_ignore_apply_errors = WSREP_IGNORE_ERRORS_ON_RECONCILING_DDL
898   */
899   sql_command_flags[SQLCOM_DROP_DB]|=          CF_WSREP_MAY_IGNORE_ERRORS;
900   sql_command_flags[SQLCOM_DROP_TABLE]|=       CF_WSREP_MAY_IGNORE_ERRORS;
901   sql_command_flags[SQLCOM_DROP_INDEX]|=       CF_WSREP_MAY_IGNORE_ERRORS;
902   sql_command_flags[SQLCOM_ALTER_TABLE]|=      CF_WSREP_MAY_IGNORE_ERRORS;
903 #endif /* WITH_WSREP */
904 }
905 
sqlcom_can_generate_row_events(const THD * thd)906 bool sqlcom_can_generate_row_events(const THD *thd)
907 {
908   return (sql_command_flags[thd->lex->sql_command] &
909           CF_CAN_GENERATE_ROW_EVENTS);
910 }
911 
is_update_query(enum enum_sql_command command)912 bool is_update_query(enum enum_sql_command command)
913 {
914   DBUG_ASSERT(command <= SQLCOM_END);
915   return (sql_command_flags[command] & CF_CHANGES_DATA) != 0;
916 }
917 
918 /**
919   Check if a sql command is allowed to write to log tables.
920   @param command The SQL command
921   @return true if writing is allowed
922 */
is_log_table_write_query(enum enum_sql_command command)923 bool is_log_table_write_query(enum enum_sql_command command)
924 {
925   DBUG_ASSERT(command <= SQLCOM_END);
926   return (sql_command_flags[command] & CF_WRITE_LOGS_COMMAND) != 0;
927 }
928 
execute_init_command(THD * thd,LEX_STRING * init_command,mysql_rwlock_t * var_lock)929 void execute_init_command(THD *thd, LEX_STRING *init_command,
930                           mysql_rwlock_t *var_lock)
931 {
932   Vio* save_vio;
933   ulonglong save_client_capabilities;
934 
935   mysql_rwlock_rdlock(var_lock);
936   if (!init_command->length)
937   {
938     mysql_rwlock_unlock(var_lock);
939     return;
940   }
941 
942   /*
943     copy the value under a lock, and release the lock.
944     init_command has to be executed without a lock held,
945     as it may try to change itself
946   */
947   size_t len= init_command->length;
948   char *buf= thd->strmake(init_command->str, len);
949   mysql_rwlock_unlock(var_lock);
950 
951   THD_STAGE_INFO(thd, stage_execution_of_init_command);
952   save_client_capabilities= thd->client_capabilities;
953   thd->client_capabilities|= CLIENT_MULTI_QUERIES;
954   /*
955     We don't need return result of execution to client side.
956     To forbid this we should set thd->net.vio to 0.
957   */
958   save_vio= thd->net.vio;
959   thd->net.vio= 0;
960   thd->clear_error(1);
961   dispatch_command(COM_QUERY, thd, buf, (uint)len, FALSE, FALSE);
962   thd->client_capabilities= save_client_capabilities;
963   thd->net.vio= save_vio;
964 
965 }
966 
967 
fgets_fn(char * buffer,size_t size,fgets_input_t input,int * error)968 static char *fgets_fn(char *buffer, size_t size, fgets_input_t input, int *error)
969 {
970   MYSQL_FILE *in= static_cast<MYSQL_FILE*> (input);
971   char *line= mysql_file_fgets(buffer, (int)size, in);
972   if (unlikely(error))
973     *error= (line == NULL) ? ferror(in->m_file) : 0;
974   return line;
975 }
976 
977 
bootstrap(MYSQL_FILE * file)978 int bootstrap(MYSQL_FILE *file)
979 {
980   int bootstrap_error= 0;
981   DBUG_ENTER("handle_bootstrap");
982 
983   THD *thd= new THD(next_thread_id());
984 #ifdef WITH_WSREP
985   thd->variables.wsrep_on= 0;
986 #endif
987   thd->bootstrap=1;
988   my_net_init(&thd->net,(st_vio*) 0, thd, MYF(0));
989   thd->max_client_packet_length= thd->net.max_packet;
990   thd->security_ctx->master_access= ALL_KNOWN_ACL;
991 
992 #ifndef EMBEDDED_LIBRARY
993   mysql_thread_set_psi_id(thd->thread_id);
994 #else
995   thd->mysql= 0;
996 #endif
997 
998   /* The following must be called before DBUG_ENTER */
999   thd->thread_stack= (char*) &thd;
1000   thd->store_globals();
1001 
1002   thd->security_ctx->user= (char*) my_strdup(key_memory_MPVIO_EXT_auth_info,
1003                                              "boot", MYF(MY_WME));
1004   thd->security_ctx->priv_user[0]= thd->security_ctx->priv_host[0]=
1005     thd->security_ctx->priv_role[0]= 0;
1006   /*
1007     Make the "client" handle multiple results. This is necessary
1008     to enable stored procedures with SELECTs and Dynamic SQL
1009     in init-file.
1010   */
1011   thd->client_capabilities|= CLIENT_MULTI_RESULTS;
1012 
1013   thd->init_for_queries();
1014 
1015   for ( ; ; )
1016   {
1017     char buffer[MAX_BOOTSTRAP_QUERY_SIZE] = "";
1018     int rc, length;
1019     char *query;
1020     int error= 0;
1021 
1022     rc= read_bootstrap_query(buffer, &length, file, fgets_fn, &error);
1023 
1024     if (rc == READ_BOOTSTRAP_EOF)
1025       break;
1026     /*
1027       Check for bootstrap file errors. SQL syntax errors will be
1028       caught below.
1029     */
1030     if (rc != READ_BOOTSTRAP_SUCCESS)
1031     {
1032       /*
1033         mysql_parse() may have set a successful error status for the previous
1034         query. We must clear the error status to report the bootstrap error.
1035       */
1036       thd->get_stmt_da()->reset_diagnostics_area();
1037 
1038       /* Get the nearest query text for reference. */
1039       char *err_ptr= buffer + (length <= MAX_BOOTSTRAP_ERROR_LEN ?
1040                                         0 : (length - MAX_BOOTSTRAP_ERROR_LEN));
1041       switch (rc)
1042       {
1043       case READ_BOOTSTRAP_ERROR:
1044         my_printf_error(ER_UNKNOWN_ERROR, "Bootstrap file error, return code (%d). "
1045                         "Nearest query: '%s'", MYF(0), error, err_ptr);
1046         break;
1047 
1048       case READ_BOOTSTRAP_QUERY_SIZE:
1049         my_printf_error(ER_UNKNOWN_ERROR, "Boostrap file error. Query size "
1050                         "exceeded %d bytes near '%s'.", MYF(0),
1051                         MAX_BOOTSTRAP_LINE_SIZE, err_ptr);
1052         break;
1053 
1054       default:
1055         DBUG_ASSERT(false);
1056         break;
1057       }
1058 
1059       thd->protocol->end_statement();
1060       bootstrap_error= 1;
1061       break;
1062     }
1063 
1064     query= (char *) thd->memdup_w_gap(buffer, length + 1,
1065                                       thd->db.length + 1 +
1066                                       QUERY_CACHE_DB_LENGTH_SIZE +
1067                                       QUERY_CACHE_FLAGS_SIZE);
1068     size_t db_len= 0;
1069     memcpy(query + length + 1, (char *) &db_len, sizeof(size_t));
1070     thd->set_query_and_id(query, length, thd->charset(), next_query_id());
1071     int2store(query + length + 1, 0);           // No db in bootstrap
1072     DBUG_PRINT("query",("%-.4096s",thd->query()));
1073 #if defined(ENABLED_PROFILING)
1074     thd->profiling.start_new_query();
1075     thd->profiling.set_query_source(thd->query(), length);
1076 #endif
1077 
1078     thd->set_time();
1079     Parser_state parser_state;
1080     if (parser_state.init(thd, thd->query(), length))
1081     {
1082       thd->protocol->end_statement();
1083       bootstrap_error= 1;
1084       break;
1085     }
1086 
1087     mysql_parse(thd, thd->query(), length, &parser_state, FALSE, FALSE);
1088 
1089     bootstrap_error= thd->is_error();
1090     thd->protocol->end_statement();
1091 
1092 #if defined(ENABLED_PROFILING)
1093     thd->profiling.finish_current_query();
1094 #endif
1095     delete_explain_query(thd->lex);
1096 
1097     if (unlikely(bootstrap_error))
1098       break;
1099 
1100     thd->reset_kill_query();  /* Ensure that killed_errmsg is released */
1101     free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
1102     thd->lex->restore_set_statement_var();
1103   }
1104   delete thd;
1105   DBUG_RETURN(bootstrap_error);
1106 }
1107 
1108 
1109 /* This works because items are allocated on THD::mem_root */
1110 
free_items(Item * item)1111 void free_items(Item *item)
1112 {
1113   Item *next;
1114   DBUG_ENTER("free_items");
1115   for (; item ; item=next)
1116   {
1117     next=item->next;
1118     item->delete_self();
1119   }
1120   DBUG_VOID_RETURN;
1121 }
1122 
1123 /**
1124    This works because items are allocated on THD::mem_root.
1125    @note The function also handles null pointers (empty list).
1126 */
cleanup_items(Item * item)1127 void cleanup_items(Item *item)
1128 {
1129   DBUG_ENTER("cleanup_items");
1130   for (; item ; item=item->next)
1131     item->cleanup();
1132   DBUG_VOID_RETURN;
1133 }
1134 
fetch_command(THD * thd,char * packet)1135 static enum enum_server_command fetch_command(THD *thd, char *packet)
1136 {
1137   enum enum_server_command
1138     command= (enum enum_server_command) (uchar) packet[0];
1139   DBUG_ENTER("fetch_command");
1140 
1141   if (command >= COM_END ||
1142       (command >= COM_MDB_GAP_BEG && command <= COM_MDB_GAP_END))
1143     command= COM_END;				// Wrong command
1144 
1145   DBUG_PRINT("info",("Command on %s = %d (%s)",
1146                      vio_description(thd->net.vio), command,
1147                      command_name[command].str));
1148   DBUG_RETURN(command);
1149 }
1150 
1151 
1152 #ifdef WITH_WSREP
wsrep_tables_accessible_when_detached(const TABLE_LIST * tables)1153 static bool wsrep_tables_accessible_when_detached(const TABLE_LIST *tables)
1154 {
1155   for (const TABLE_LIST *table= tables; table; table= table->next_global)
1156   {
1157     LEX_CSTRING db= table->db, tn= table->table_name;
1158     if (get_table_category(&db, &tn)  < TABLE_CATEGORY_INFORMATION)
1159       return false;
1160   }
1161   return true;
1162 }
1163 
wsrep_command_no_result(char command)1164 static bool wsrep_command_no_result(char command)
1165 {
1166   return (command == COM_STMT_PREPARE          ||
1167           command == COM_STMT_FETCH            ||
1168           command == COM_STMT_SEND_LONG_DATA   ||
1169           command == COM_STMT_CLOSE);
1170 }
1171 #endif /* WITH_WSREP */
1172 #ifndef EMBEDDED_LIBRARY
1173 
1174 /**
1175   Read one command from connection and execute it (query or simple command).
1176   This function is called in loop from thread function.
1177 
1178   For profiling to work, it must never be called recursively.
1179 
1180   @retval
1181     0  success
1182   @retval
1183     1  request of thread shutdown (see dispatch_command() description)
1184 */
1185 
do_command(THD * thd)1186 bool do_command(THD *thd)
1187 {
1188   bool return_value;
1189   char *packet= 0;
1190   ulong packet_length;
1191   NET *net= &thd->net;
1192   enum enum_server_command command;
1193   DBUG_ENTER("do_command");
1194 
1195   /*
1196     indicator of uninitialized lex => normal flow of errors handling
1197     (see my_message_sql)
1198   */
1199   thd->lex->current_select= 0;
1200 
1201   /*
1202     This thread will do a blocking read from the client which
1203     will be interrupted when the next command is received from
1204     the client, the connection is closed or "net_wait_timeout"
1205     number of seconds has passed.
1206   */
1207   if (!thd->skip_wait_timeout)
1208     my_net_set_read_timeout(net, thd->get_net_wait_timeout());
1209 
1210   /* Errors and diagnostics are cleared once here before query */
1211   thd->clear_error(1);
1212 
1213   net_new_transaction(net);
1214 
1215   /* Save for user statistics */
1216   thd->start_bytes_received= thd->status_var.bytes_received;
1217 
1218   /*
1219     Synchronization point for testing of KILL_CONNECTION.
1220     This sync point can wait here, to simulate slow code execution
1221     between the last test of thd->killed and blocking in read().
1222 
1223     The goal of this test is to verify that a connection does not
1224     hang, if it is killed at this point of execution.
1225     (Bug#37780 - main.kill fails randomly)
1226 
1227     Note that the sync point wait itself will be terminated by a
1228     kill. In this case it consumes a condition broadcast, but does
1229     not change anything else. The consumed broadcast should not
1230     matter here, because the read/recv() below doesn't use it.
1231   */
1232   DEBUG_SYNC(thd, "before_do_command_net_read");
1233 
1234   packet_length= my_net_read_packet(net, 1);
1235 
1236   if (unlikely(packet_length == packet_error))
1237   {
1238     DBUG_PRINT("info",("Got error %d reading command from socket %s",
1239 		       net->error,
1240 		       vio_description(net->vio)));
1241 
1242     /* Instrument this broken statement as "statement/com/error" */
1243     thd->m_statement_psi= MYSQL_REFINE_STATEMENT(thd->m_statement_psi,
1244                                                  com_statement_info[COM_END].
1245                                                  m_key);
1246 
1247 
1248     /* Check if we can continue without closing the connection */
1249 
1250     /* The error must be set. */
1251     DBUG_ASSERT(thd->is_error());
1252     thd->protocol->end_statement();
1253 
1254     /* Mark the statement completed. */
1255     MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
1256     thd->m_statement_psi= NULL;
1257     thd->m_digest= NULL;
1258 
1259     if (net->error != 3)
1260     {
1261       return_value= TRUE;                       // We have to close it.
1262       goto out;
1263     }
1264 
1265     net->error= 0;
1266     return_value= FALSE;
1267     goto out;
1268   }
1269 
1270   packet= (char*) net->read_pos;
1271   /*
1272     'packet_length' contains length of data, as it was stored in packet
1273     header. In case of malformed header, my_net_read returns zero.
1274     If packet_length is not zero, my_net_read ensures that the returned
1275     number of bytes was actually read from network.
1276     There is also an extra safety measure in my_net_read:
1277     it sets packet[packet_length]= 0, but only for non-zero packets.
1278   */
1279   if (packet_length == 0)                       /* safety */
1280   {
1281     /* Initialize with COM_SLEEP packet */
1282     packet[0]= (uchar) COM_SLEEP;
1283     packet_length= 1;
1284   }
1285   /* Do not rely on my_net_read, extra safety against programming errors. */
1286   packet[packet_length]= '\0';                  /* safety */
1287 
1288 
1289   command= fetch_command(thd, packet);
1290 
1291 #ifdef WITH_WSREP
1292   DEBUG_SYNC(thd, "wsrep_before_before_command");
1293   /*
1294     If this command does not return a result, then we
1295     instruct wsrep_before_command() to skip result handling.
1296     This causes BF aborted transaction to roll back but keep
1297     the error state until next command which is able to return
1298     a result to the client.
1299   */
1300   if (unlikely(wsrep_service_started) &&
1301       wsrep_before_command(thd, wsrep_command_no_result(command)))
1302   {
1303     /*
1304       Aborted by background rollbacker thread.
1305       Handle error here and jump straight to out.
1306       Notice that thd->store_globals() is called
1307       in wsrep_before_command().
1308     */
1309     WSREP_LOG_THD(thd, "enter found BF aborted");
1310     DBUG_ASSERT(!thd->mdl_context.has_locks());
1311     DBUG_ASSERT(!thd->get_stmt_da()->is_set());
1312     /* We let COM_QUIT and COM_STMT_CLOSE to execute even if wsrep aborted. */
1313     if (command != COM_STMT_CLOSE &&
1314         command != COM_QUIT)
1315     {
1316       my_error(ER_LOCK_DEADLOCK, MYF(0));
1317       WSREP_DEBUG("Deadlock error for: %s", thd->query());
1318       thd->reset_killed();
1319       thd->mysys_var->abort     = 0;
1320       thd->wsrep_retry_counter  = 0;
1321 
1322       /* Instrument this broken statement as "statement/com/error" */
1323       thd->m_statement_psi= MYSQL_REFINE_STATEMENT(thd->m_statement_psi,
1324                                                  com_statement_info[COM_END].
1325                                                  m_key);
1326 
1327       thd->protocol->end_statement();
1328 
1329       /* Mark the statement completed. */
1330       MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
1331       thd->m_statement_psi= NULL;
1332       thd->m_digest= NULL;
1333       return_value= FALSE;
1334 
1335       wsrep_after_command_before_result(thd);
1336       goto out;
1337     }
1338   }
1339 
1340   if (WSREP(thd))
1341   {
1342     /*
1343      * bail out if DB snapshot has not been installed. We however,
1344      * allow queries "SET" and "SHOW", they are trapped later in execute_command
1345      */
1346     if (!(thd->wsrep_applier) &&
1347         (!wsrep_ready_get() || wsrep_reject_queries != WSREP_REJECT_NONE) &&
1348         (server_command_flags[command] & CF_SKIP_WSREP_CHECK) == 0)
1349     {
1350       my_message(ER_UNKNOWN_COM_ERROR,
1351                  "WSREP has not yet prepared node for application use", MYF(0));
1352       thd->protocol->end_statement();
1353 
1354       /* Performance Schema Interface instrumentation end. */
1355       MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
1356       thd->m_statement_psi= NULL;
1357       thd->m_digest= NULL;
1358 
1359       return_value= FALSE;
1360       wsrep_after_command_before_result(thd);
1361       goto out;
1362     }
1363   }
1364 #endif /* WITH_WSREP */
1365   /* Restore read timeout value */
1366   my_net_set_read_timeout(net, thd->variables.net_read_timeout);
1367 
1368   DBUG_ASSERT(packet_length);
1369   DBUG_ASSERT(!thd->apc_target.is_enabled());
1370   return_value= dispatch_command(command, thd, packet+1,
1371                                  (uint) (packet_length-1), FALSE, FALSE);
1372   DBUG_ASSERT(!thd->apc_target.is_enabled());
1373 
1374 out:
1375   thd->lex->restore_set_statement_var();
1376   /* The statement instrumentation must be closed in all cases. */
1377   DBUG_ASSERT(thd->m_digest == NULL);
1378   DBUG_ASSERT(thd->m_statement_psi == NULL);
1379 #ifdef WITH_WSREP
1380   if (packet_length != packet_error)
1381   {
1382     /* there was a command to process, and before_command() has been called */
1383     if (unlikely(wsrep_service_started))
1384       wsrep_after_command_after_result(thd);
1385   }
1386 #endif /* WITH_WSREP */
1387   DBUG_RETURN(return_value);
1388 }
1389 #endif  /* EMBEDDED_LIBRARY */
1390 
1391 /**
1392   @brief Determine if an attempt to update a non-temporary table while the
1393     read-only option was enabled has been made.
1394 
1395   This is a helper function to mysql_execute_command.
1396 
1397   @note SQLCOM_MULTI_UPDATE is an exception and dealt with elsewhere.
1398 
1399   @see mysql_execute_command
1400   @returns Status code
1401     @retval TRUE The statement should be denied.
1402     @retval FALSE The statement isn't updating any relevant tables.
1403 */
1404 
deny_updates_if_read_only_option(THD * thd,TABLE_LIST * all_tables)1405 static bool deny_updates_if_read_only_option(THD *thd, TABLE_LIST *all_tables)
1406 {
1407   DBUG_ENTER("deny_updates_if_read_only_option");
1408 
1409   if (!opt_readonly)
1410     DBUG_RETURN(FALSE);
1411 
1412   LEX *lex= thd->lex;
1413 
1414   /* Super user is allowed to do changes */
1415   if ((thd->security_ctx->master_access & PRIV_IGNORE_READ_ONLY) != NO_ACL)
1416     DBUG_RETURN(FALSE);
1417 
1418   /* Check if command doesn't update anything */
1419   if (!(sql_command_flags[lex->sql_command] & CF_CHANGES_DATA))
1420     DBUG_RETURN(FALSE);
1421 
1422   /* Multi update is an exception and is dealt with later. */
1423   if (lex->sql_command == SQLCOM_UPDATE_MULTI)
1424     DBUG_RETURN(FALSE);
1425 
1426   /*
1427     a table-to-be-created is not in the temp table list yet,
1428     so CREATE TABLE needs a special treatment
1429   */
1430   if (lex->sql_command == SQLCOM_CREATE_TABLE)
1431     DBUG_RETURN(!lex->tmp_table());
1432 
1433   /*
1434     a table-to-be-dropped might not exist (DROP TEMPORARY TABLE IF EXISTS),
1435     cannot use the temp table list either.
1436   */
1437   if (lex->sql_command == SQLCOM_DROP_TABLE && lex->tmp_table())
1438     DBUG_RETURN(FALSE);
1439 
1440   /* Check if we created, dropped, or renamed a database */
1441   if ((sql_command_flags[lex->sql_command] & CF_DB_CHANGE))
1442     DBUG_RETURN(TRUE);
1443 
1444   if (some_non_temp_table_to_be_updated(thd, all_tables))
1445     DBUG_RETURN(TRUE);
1446 
1447   /* Assuming that only temporary tables are modified. */
1448   DBUG_RETURN(FALSE);
1449 }
1450 
1451 #ifdef WITH_WSREP
wsrep_read_only_option(THD * thd,TABLE_LIST * all_tables)1452 static my_bool wsrep_read_only_option(THD *thd, TABLE_LIST *all_tables)
1453 {
1454   int opt_readonly_saved = opt_readonly;
1455   privilege_t flag_saved= thd->security_ctx->master_access & PRIV_IGNORE_READ_ONLY;
1456 
1457   opt_readonly = 0;
1458   thd->security_ctx->master_access &= ~PRIV_IGNORE_READ_ONLY;
1459 
1460   my_bool ret = !deny_updates_if_read_only_option(thd, all_tables);
1461 
1462   opt_readonly = opt_readonly_saved;
1463   thd->security_ctx->master_access |= flag_saved;
1464 
1465   return ret;
1466 }
1467 
wsrep_copy_query(THD * thd)1468 static void wsrep_copy_query(THD *thd)
1469 {
1470   thd->wsrep_retry_command   = thd->get_command();
1471   thd->wsrep_retry_query_len = thd->query_length();
1472   if (thd->wsrep_retry_query) {
1473       my_free(thd->wsrep_retry_query);
1474   }
1475   thd->wsrep_retry_query = (char *)my_malloc(PSI_INSTRUMENT_ME,
1476                                  thd->wsrep_retry_query_len + 1, MYF(0));
1477   strncpy(thd->wsrep_retry_query, thd->query(), thd->wsrep_retry_query_len);
1478   thd->wsrep_retry_query[thd->wsrep_retry_query_len] = '\0';
1479 }
1480 #endif /* WITH_WSREP */
1481 
1482 /**
1483   check COM_MULTI packet
1484 
1485   @param thd             thread handle
1486   @param packet          pointer on the packet of commands
1487   @param packet_length   length of this packet
1488 
1489   @retval 0 - Error
1490   @retval # - Number of commands in the batch
1491 */
1492 
maria_multi_check(THD * thd,char * packet,size_t packet_length)1493 uint maria_multi_check(THD *thd, char *packet, size_t packet_length)
1494 {
1495   uint counter= 0;
1496   DBUG_ENTER("maria_multi_check");
1497   while (packet_length)
1498   {
1499     char *packet_start= packet;
1500     size_t subpacket_length= net_field_length((uchar **)&packet_start);
1501     size_t length_length= packet_start - packet;
1502     // length of command + 3 bytes where that length was stored
1503     DBUG_PRINT("info", ("sub-packet length: %zu + %zu  command: %x",
1504                         subpacket_length, length_length,
1505                         packet_start[3]));
1506 
1507     if (subpacket_length == 0 ||
1508         (subpacket_length + length_length) > packet_length)
1509     {
1510       my_message(ER_UNKNOWN_COM_ERROR, ER_THD(thd, ER_UNKNOWN_COM_ERROR),
1511                  MYF(0));
1512       DBUG_RETURN(0);
1513     }
1514 
1515     counter++;
1516     packet= packet_start + subpacket_length;
1517     packet_length-= (subpacket_length + length_length);
1518   }
1519   DBUG_RETURN(counter);
1520 }
1521 
1522 
1523 #if defined(WITH_ARIA_STORAGE_ENGINE)
1524 class Silence_all_errors : public Internal_error_handler
1525 {
1526   char m_message[MYSQL_ERRMSG_SIZE];
1527   int error;
1528 public:
Silence_all_errors()1529   Silence_all_errors():error(0) {}
~Silence_all_errors()1530   virtual ~Silence_all_errors() {}
1531 
handle_condition(THD * thd,uint sql_errno,const char * sql_state,Sql_condition::enum_warning_level * level,const char * msg,Sql_condition ** cond_hdl)1532   virtual bool handle_condition(THD *thd,
1533                                 uint sql_errno,
1534                                 const char* sql_state,
1535                                 Sql_condition::enum_warning_level *level,
1536                                 const char* msg,
1537                                 Sql_condition ** cond_hdl)
1538   {
1539     error= sql_errno;
1540     *cond_hdl= NULL;
1541     strmake_buf(m_message, msg);
1542     return true;                              // Error handled
1543   }
1544 };
1545 #endif
1546 
1547 
1548 /**
1549   Perform one connection-level (COM_XXXX) command.
1550 
1551   @param command         type of command to perform
1552   @param thd             connection handle
1553   @param packet          data for the command, packet is always null-terminated
1554   @param packet_length   length of packet + 1 (to show that data is
1555                          null-terminated) except for COM_SLEEP, where it
1556                          can be zero.
1557   @param is_com_multi    recursive call from COM_MULTI
1558   @param is_next_command there will be more command in the COM_MULTI batch
1559 
1560   @todo
1561     set thd->lex->sql_command to SQLCOM_END here.
1562   @todo
1563     The following has to be changed to an 8 byte integer
1564 
1565   @retval
1566     0   ok
1567   @retval
1568     1   request of thread shutdown, i. e. if command is
1569         COM_QUIT/COM_SHUTDOWN
1570 */
dispatch_command(enum enum_server_command command,THD * thd,char * packet,uint packet_length,bool is_com_multi,bool is_next_command)1571 bool dispatch_command(enum enum_server_command command, THD *thd,
1572 		      char* packet, uint packet_length, bool is_com_multi,
1573                       bool is_next_command)
1574 {
1575   NET *net= &thd->net;
1576   bool error= 0;
1577   bool do_end_of_statement= true;
1578   DBUG_ENTER("dispatch_command");
1579   DBUG_PRINT("info", ("command: %d %s", command,
1580                       (command_name[command].str != 0 ?
1581                        command_name[command].str :
1582                        "<?>")));
1583   bool drop_more_results= 0;
1584 
1585   /* keep it withing 1 byte */
1586   compile_time_assert(COM_END == 255);
1587 
1588 #if defined(ENABLED_PROFILING)
1589   thd->profiling.start_new_query();
1590 #endif
1591   MYSQL_COMMAND_START(thd->thread_id, command,
1592                       &thd->security_ctx->priv_user[0],
1593                       (char *) thd->security_ctx->host_or_ip);
1594 
1595   DBUG_EXECUTE_IF("crash_dispatch_command_before",
1596                   { DBUG_PRINT("crash_dispatch_command_before", ("now"));
1597                     DBUG_SUICIDE(); });
1598 
1599   /* Performance Schema Interface instrumentation, begin */
1600   thd->m_statement_psi= MYSQL_REFINE_STATEMENT(thd->m_statement_psi,
1601                                                com_statement_info[command].
1602                                                m_key);
1603   /*
1604     We should always call reset_for_next_command() before a query.
1605     mysql_parse() will do this for queries. Ensure it's also done
1606     for other commands.
1607   */
1608   if (command != COM_QUERY)
1609     thd->reset_for_next_command();
1610   thd->set_command(command);
1611 
1612   thd->enable_slow_log= true;
1613   thd->query_plan_flags= QPLAN_INIT;
1614   thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
1615   thd->reset_kill_query();
1616 
1617   DEBUG_SYNC(thd,"dispatch_command_before_set_time");
1618 
1619   thd->set_time();
1620   if (!(server_command_flags[command] & CF_SKIP_QUERY_ID))
1621     thd->set_query_id(next_query_id());
1622   else
1623   {
1624     /*
1625       ping, get statistics or similar stateless command.
1626       No reason to increase query id here.
1627     */
1628     thd->set_query_id(get_query_id());
1629   }
1630 #ifdef WITH_WSREP
1631   if (WSREP(thd) && thd->wsrep_next_trx_id() == WSREP_UNDEFINED_TRX_ID)
1632   {
1633     thd->set_wsrep_next_trx_id(thd->query_id);
1634     WSREP_DEBUG("assigned new next trx id: %" PRIu64, thd->wsrep_next_trx_id());
1635   }
1636 #endif /* WITH_WSREP */
1637 
1638   if (!(server_command_flags[command] & CF_SKIP_QUESTIONS))
1639     statistic_increment(thd->status_var.questions, &LOCK_status);
1640 
1641   /* Copy data for user stats */
1642   if ((thd->userstat_running= opt_userstat_running))
1643   {
1644     thd->start_cpu_time= my_getcputime();
1645     memcpy(&thd->org_status_var, &thd->status_var, sizeof(thd->status_var));
1646     thd->select_commands= thd->update_commands= thd->other_commands= 0;
1647   }
1648 
1649   /**
1650     Clear the set of flags that are expected to be cleared at the
1651     beginning of each command.
1652   */
1653   thd->server_status&= ~SERVER_STATUS_CLEAR_SET;
1654   if (is_next_command)
1655   {
1656     drop_more_results= !MY_TEST(thd->server_status &
1657                                 SERVER_MORE_RESULTS_EXISTS);
1658     thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
1659     if (is_com_multi)
1660       thd->get_stmt_da()->set_skip_flush();
1661   }
1662 
1663   if (unlikely(thd->security_ctx->password_expired &&
1664                command != COM_QUERY &&
1665                command != COM_PING &&
1666                command != COM_QUIT &&
1667                command != COM_STMT_PREPARE &&
1668                command != COM_STMT_EXECUTE))
1669   {
1670     my_error(ER_MUST_CHANGE_PASSWORD, MYF(0));
1671     goto dispatch_end;
1672   }
1673 
1674   switch (command) {
1675   case COM_INIT_DB:
1676   {
1677     LEX_CSTRING tmp;
1678     status_var_increment(thd->status_var.com_stat[SQLCOM_CHANGE_DB]);
1679     if (unlikely(thd->copy_with_error(system_charset_info, (LEX_STRING*) &tmp,
1680                                       thd->charset(), packet, packet_length)))
1681       break;
1682     if (!mysql_change_db(thd, &tmp, FALSE))
1683     {
1684       general_log_write(thd, command, thd->db.str, thd->db.length);
1685       my_ok(thd);
1686     }
1687     break;
1688   }
1689 #ifdef HAVE_REPLICATION
1690   case COM_REGISTER_SLAVE:
1691   {
1692     status_var_increment(thd->status_var.com_register_slave);
1693     if (!thd->register_slave((uchar*) packet, packet_length))
1694       my_ok(thd);
1695     break;
1696   }
1697 #endif
1698   case COM_RESET_CONNECTION:
1699   {
1700     thd->status_var.com_other++;
1701 #ifdef WITH_WSREP
1702     if (unlikely(wsrep_service_started))
1703     {
1704       wsrep_after_command_ignore_result(thd);
1705       wsrep_close(thd);
1706     }
1707 #endif /* WITH_WSREP */
1708     thd->change_user();
1709     thd->clear_error();                         // if errors from rollback
1710 #ifdef WITH_WSREP
1711     if (unlikely(wsrep_service_started))
1712     {
1713       wsrep_open(thd);
1714       wsrep_before_command(thd);
1715     }
1716 #endif /* WITH_WSREP */
1717     /* Restore original charset from client authentication packet.*/
1718     if(thd->org_charset)
1719       thd->update_charset(thd->org_charset,thd->org_charset,thd->org_charset);
1720     my_ok(thd, 0, 0, 0);
1721     break;
1722   }
1723   case COM_CHANGE_USER:
1724   {
1725     int auth_rc;
1726     status_var_increment(thd->status_var.com_other);
1727 
1728 #ifdef WITH_WSREP
1729     if (unlikely(wsrep_service_started))
1730     {
1731       wsrep_after_command_ignore_result(thd);
1732       wsrep_close(thd);
1733     }
1734 #endif /* WITH_WSREP */
1735     thd->change_user();
1736 #ifdef WITH_WSREP
1737     if (unlikely(wsrep_service_started))
1738     {
1739       wsrep_open(thd);
1740       wsrep_before_command(thd);
1741     }
1742 #endif /* WITH_WSREP */
1743     thd->clear_error();                         // if errors from rollback
1744 
1745     /* acl_authenticate() takes the data from net->read_pos */
1746     net->read_pos= (uchar*)packet;
1747 
1748     LEX_CSTRING save_db= thd->db;
1749     USER_CONN *save_user_connect= thd->user_connect;
1750     Security_context save_security_ctx= *thd->security_ctx;
1751     CHARSET_INFO *save_character_set_client=
1752       thd->variables.character_set_client;
1753     CHARSET_INFO *save_collation_connection=
1754       thd->variables.collation_connection;
1755     CHARSET_INFO *save_character_set_results=
1756       thd->variables.character_set_results;
1757 
1758     /* Ensure we don't free security_ctx->user in case we have to revert */
1759     thd->security_ctx->user= 0;
1760     thd->user_connect= 0;
1761 
1762     /*
1763       to limit COM_CHANGE_USER ability to brute-force passwords,
1764       we only allow three unsuccessful COM_CHANGE_USER per connection.
1765     */
1766     if (thd->failed_com_change_user >= 3)
1767     {
1768       my_message(ER_UNKNOWN_COM_ERROR, ER_THD(thd,ER_UNKNOWN_COM_ERROR),
1769                  MYF(0));
1770       auth_rc= 1;
1771     }
1772     else
1773       auth_rc= acl_authenticate(thd, packet_length);
1774 
1775     mysql_audit_notify_connection_change_user(thd, &save_security_ctx);
1776     if (auth_rc)
1777     {
1778       /* Free user if allocated by acl_authenticate */
1779       my_free(const_cast<char*>(thd->security_ctx->user));
1780       *thd->security_ctx= save_security_ctx;
1781       if (thd->user_connect)
1782 	decrease_user_connections(thd->user_connect);
1783       thd->user_connect= save_user_connect;
1784       thd->reset_db(&save_db);
1785       thd->update_charset(save_character_set_client, save_collation_connection,
1786                           save_character_set_results);
1787       thd->failed_com_change_user++;
1788       my_sleep(1000000);
1789     }
1790     else
1791     {
1792 #ifndef NO_EMBEDDED_ACCESS_CHECKS
1793       /* we've authenticated new user */
1794       if (save_user_connect)
1795 	decrease_user_connections(save_user_connect);
1796 #endif /* NO_EMBEDDED_ACCESS_CHECKS */
1797       my_free((char*) save_db.str);
1798       my_free(const_cast<char*>(save_security_ctx.user));
1799     }
1800     break;
1801   }
1802   case COM_STMT_BULK_EXECUTE:
1803   {
1804     mysqld_stmt_bulk_execute(thd, packet, packet_length);
1805 #ifdef WITH_WSREP
1806     if (WSREP(thd))
1807     {
1808         (void)wsrep_after_statement(thd);
1809     }
1810 #endif /* WITH_WSREP */
1811     break;
1812   }
1813   case COM_STMT_EXECUTE:
1814   {
1815     mysqld_stmt_execute(thd, packet, packet_length);
1816 #ifdef WITH_WSREP
1817     if (WSREP(thd))
1818     {
1819         (void)wsrep_after_statement(thd);
1820     }
1821 #endif /* WITH_WSREP */
1822     break;
1823   }
1824   case COM_STMT_FETCH:
1825   {
1826     mysqld_stmt_fetch(thd, packet, packet_length);
1827     break;
1828   }
1829   case COM_STMT_SEND_LONG_DATA:
1830   {
1831     mysql_stmt_get_longdata(thd, packet, packet_length);
1832     break;
1833   }
1834   case COM_STMT_PREPARE:
1835   {
1836     mysqld_stmt_prepare(thd, packet, packet_length);
1837     break;
1838   }
1839   case COM_STMT_CLOSE:
1840   {
1841     mysqld_stmt_close(thd, packet);
1842     break;
1843   }
1844   case COM_STMT_RESET:
1845   {
1846     mysqld_stmt_reset(thd, packet);
1847     break;
1848   }
1849   case COM_QUERY:
1850   {
1851     DBUG_ASSERT(thd->m_digest == NULL);
1852     thd->m_digest= & thd->m_digest_state;
1853     thd->m_digest->reset(thd->m_token_array, max_digest_length);
1854 
1855     if (unlikely(alloc_query(thd, packet, packet_length)))
1856       break;					// fatal error is set
1857     MYSQL_QUERY_START(thd->query(), thd->thread_id,
1858                       thd->get_db(),
1859                       &thd->security_ctx->priv_user[0],
1860                       (char *) thd->security_ctx->host_or_ip);
1861     char *packet_end= thd->query() + thd->query_length();
1862     general_log_write(thd, command, thd->query(), thd->query_length());
1863     DBUG_PRINT("query",("%-.4096s",thd->query()));
1864 #if defined(ENABLED_PROFILING)
1865     thd->profiling.set_query_source(thd->query(), thd->query_length());
1866 #endif
1867     MYSQL_SET_STATEMENT_TEXT(thd->m_statement_psi, thd->query(),
1868                              thd->query_length());
1869 
1870     Parser_state parser_state;
1871     if (unlikely(parser_state.init(thd, thd->query(), thd->query_length())))
1872       break;
1873 
1874 #ifdef WITH_WSREP
1875     if (WSREP(thd))
1876     {
1877       if (wsrep_mysql_parse(thd, thd->query(), thd->query_length(),
1878                             &parser_state,
1879                             is_com_multi, is_next_command))
1880       {
1881         WSREP_DEBUG("Deadlock error for: %s", thd->query());
1882         mysql_mutex_lock(&thd->LOCK_thd_data);
1883         thd->reset_kill_query();
1884         thd->wsrep_retry_counter  = 0;
1885         mysql_mutex_unlock(&thd->LOCK_thd_data);
1886         goto dispatch_end;
1887       }
1888     }
1889     else
1890 #endif /* WITH_WSREP */
1891       mysql_parse(thd, thd->query(), thd->query_length(), &parser_state,
1892                   is_com_multi, is_next_command);
1893 
1894     while (!thd->killed && (parser_state.m_lip.found_semicolon != NULL) &&
1895            ! thd->is_error())
1896     {
1897       /*
1898         Multiple queries exist, execute them individually
1899       */
1900       char *beginning_of_next_stmt= (char*) parser_state.m_lip.found_semicolon;
1901 
1902       /* Finalize server status flags after executing a statement. */
1903       thd->update_server_status();
1904       thd->protocol->end_statement();
1905       query_cache_end_of_result(thd);
1906 
1907       mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_STATUS,
1908                           thd->get_stmt_da()->is_error()
1909                             ? thd->get_stmt_da()->sql_errno()
1910                             : 0,
1911                           command_name[command].str);
1912 
1913       ulong length= (ulong)(packet_end - beginning_of_next_stmt);
1914 
1915       log_slow_statement(thd);
1916       DBUG_ASSERT(!thd->apc_target.is_enabled());
1917 
1918       /* Remove garbage at start of query */
1919       while (length > 0 && my_isspace(thd->charset(), *beginning_of_next_stmt))
1920       {
1921         beginning_of_next_stmt++;
1922         length--;
1923       }
1924 
1925       /* PSI end */
1926       MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
1927       thd->m_statement_psi= NULL;
1928       thd->m_digest= NULL;
1929 
1930       /* DTRACE end */
1931       if (MYSQL_QUERY_DONE_ENABLED())
1932       {
1933         MYSQL_QUERY_DONE(thd->is_error());
1934       }
1935 
1936 #if defined(ENABLED_PROFILING)
1937       thd->profiling.finish_current_query();
1938       thd->profiling.start_new_query("continuing");
1939       thd->profiling.set_query_source(beginning_of_next_stmt, length);
1940 #endif
1941 
1942       /* DTRACE begin */
1943       MYSQL_QUERY_START(beginning_of_next_stmt, thd->thread_id,
1944                         thd->get_db(),
1945                         &thd->security_ctx->priv_user[0],
1946                         (char *) thd->security_ctx->host_or_ip);
1947 
1948       /* PSI begin */
1949       thd->m_digest= & thd->m_digest_state;
1950 
1951       thd->m_statement_psi= MYSQL_START_STATEMENT(&thd->m_statement_state,
1952                                                   com_statement_info[command].m_key,
1953                                                   thd->db.str, thd->db.length,
1954                                                   thd->charset(), NULL);
1955       THD_STAGE_INFO(thd, stage_starting);
1956       MYSQL_SET_STATEMENT_TEXT(thd->m_statement_psi, beginning_of_next_stmt,
1957                                length);
1958 
1959       thd->set_query_and_id(beginning_of_next_stmt, length,
1960                             thd->charset(), next_query_id());
1961 
1962       /*
1963         Count each statement from the client.
1964       */
1965       statistic_increment(thd->status_var.questions, &LOCK_status);
1966 
1967       if (!WSREP(thd))
1968         thd->set_time(); /* Reset the query start time. */
1969 
1970       parser_state.reset(beginning_of_next_stmt, length);
1971 
1972 #ifdef WITH_WSREP
1973       if (WSREP(thd))
1974       {
1975         if (wsrep_mysql_parse(thd, beginning_of_next_stmt,
1976                               length, &parser_state,
1977                               is_com_multi, is_next_command))
1978         {
1979           WSREP_DEBUG("Deadlock error for: %s", thd->query());
1980           mysql_mutex_lock(&thd->LOCK_thd_data);
1981           thd->reset_kill_query();
1982           thd->wsrep_retry_counter  = 0;
1983           mysql_mutex_unlock(&thd->LOCK_thd_data);
1984 
1985           goto dispatch_end;
1986         }
1987       }
1988       else
1989 #endif /* WITH_WSREP */
1990       mysql_parse(thd, beginning_of_next_stmt, length, &parser_state,
1991                   is_com_multi, is_next_command);
1992 
1993     }
1994 
1995     DBUG_PRINT("info",("query ready"));
1996     break;
1997   }
1998   case COM_FIELD_LIST:				// This isn't actually needed
1999 #ifdef DONT_ALLOW_SHOW_COMMANDS
2000     my_message(ER_NOT_ALLOWED_COMMAND, ER_THD(thd, ER_NOT_ALLOWED_COMMAND),
2001                MYF(0));	/* purecov: inspected */
2002     break;
2003 #else
2004   {
2005     char *fields, *packet_end= packet + packet_length, *arg_end;
2006     /* Locked closure of all tables */
2007     TABLE_LIST table_list;
2008     LEX_STRING table_name;
2009     LEX_CSTRING db;
2010     /*
2011       SHOW statements should not add the used tables to the list of tables
2012       used in a transaction.
2013     */
2014     MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint();
2015 
2016     status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_FIELDS]);
2017     if (thd->copy_db_to(&db))
2018       break;
2019     /*
2020       We have name + wildcard in packet, separated by endzero
2021       (The packet is guaranteed to end with an end zero)
2022     */
2023     arg_end= strend(packet);
2024     uint arg_length= (uint)(arg_end - packet);
2025 
2026     /* Check given table name length. */
2027     if (packet_length - arg_length > NAME_LEN + 1 || arg_length > SAFE_NAME_LEN)
2028     {
2029       my_message(ER_UNKNOWN_COM_ERROR, ER_THD(thd, ER_UNKNOWN_COM_ERROR),
2030                  MYF(0));
2031       break;
2032     }
2033     thd->convert_string(&table_name, system_charset_info,
2034 			packet, arg_length, thd->charset());
2035     if (check_table_name(table_name.str, table_name.length, FALSE))
2036     {
2037       /* this is OK due to convert_string() null-terminating the string */
2038       my_error(ER_WRONG_TABLE_NAME, MYF(0), table_name.str);
2039       break;
2040     }
2041     packet= arg_end + 1;
2042     // thd->reset_for_next_command reset state => restore it
2043     if (is_next_command)
2044     {
2045       thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
2046       if (is_com_multi)
2047         thd->get_stmt_da()->set_skip_flush();
2048     }
2049 
2050     lex_start(thd);
2051     /* Must be before we init the table list. */
2052     if (lower_case_table_names)
2053     {
2054       table_name.length= my_casedn_str(files_charset_info, table_name.str);
2055       db.length= my_casedn_str(files_charset_info, (char*) db.str);
2056     }
2057     table_list.init_one_table(&db, (LEX_CSTRING*) &table_name, 0, TL_READ);
2058     /*
2059       Init TABLE_LIST members necessary when the undelrying
2060       table is view.
2061     */
2062     table_list.select_lex= thd->lex->first_select_lex();
2063     thd->lex->
2064       first_select_lex()->table_list.link_in_list(&table_list,
2065                                                   &table_list.next_local);
2066     thd->lex->add_to_query_tables(&table_list);
2067 
2068     if (is_infoschema_db(&table_list.db))
2069     {
2070       ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, &table_list.alias);
2071       if (schema_table)
2072         table_list.schema_table= schema_table;
2073     }
2074 
2075     uint query_length= (uint) (packet_end - packet); // Don't count end \0
2076     if (!(fields= (char *) thd->memdup(packet, query_length + 1)))
2077       break;
2078     thd->set_query(fields, query_length);
2079     general_log_print(thd, command, "%s %s", table_list.table_name.str,
2080                       fields);
2081 
2082     if (thd->open_temporary_tables(&table_list))
2083       break;
2084 
2085     if (check_table_access(thd, SELECT_ACL, &table_list,
2086                            TRUE, UINT_MAX, FALSE))
2087       break;
2088     /*
2089       Turn on an optimization relevant if the underlying table
2090       is a view: do not fill derived tables.
2091     */
2092     thd->lex->sql_command= SQLCOM_SHOW_FIELDS;
2093 
2094     mysqld_list_fields(thd,&table_list,fields);
2095     thd->lex->unit.cleanup();
2096     /* No need to rollback statement transaction, it's not started. */
2097     DBUG_ASSERT(thd->transaction->stmt.is_empty());
2098     close_thread_tables(thd);
2099     thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
2100 
2101     if (thd->transaction_rollback_request)
2102     {
2103       /*
2104         Transaction rollback was requested since MDL deadlock was
2105         discovered while trying to open tables. Rollback transaction
2106         in all storage engines including binary log and release all
2107         locks.
2108       */
2109       trans_rollback_implicit(thd);
2110       thd->release_transactional_locks();
2111     }
2112 
2113     thd->cleanup_after_query();
2114     break;
2115   }
2116 #endif
2117   case COM_QUIT:
2118     /* Note: We don't calculate statistics for this command */
2119 
2120     /* Ensure that quit works even if max_mem_used is set */
2121     thd->variables.max_mem_used= LONGLONG_MAX;
2122     general_log_print(thd, command, NullS);
2123     net->error=0;				// Don't give 'abort' message
2124     thd->get_stmt_da()->disable_status();       // Don't send anything back
2125     error=TRUE;					// End server
2126     break;
2127 #ifndef EMBEDDED_LIBRARY
2128   case COM_BINLOG_DUMP:
2129     {
2130       ulong pos;
2131       ushort flags;
2132       uint32 slave_server_id;
2133 
2134       status_var_increment(thd->status_var.com_other);
2135 
2136       thd->query_plan_flags|= QPLAN_ADMIN;
2137       if (check_global_access(thd, PRIV_COM_BINLOG_DUMP))
2138 	break;
2139 
2140       /* TODO: The following has to be changed to an 8 byte integer */
2141       pos = uint4korr(packet);
2142       flags = uint2korr(packet + 4);
2143       thd->variables.server_id=0; /* avoid suicide */
2144       if ((slave_server_id= uint4korr(packet+6))) // mysqlbinlog.server_id==0
2145 	kill_zombie_dump_threads(slave_server_id);
2146       thd->variables.server_id = slave_server_id;
2147 
2148       const char *name= packet + 10;
2149       size_t nlen= strlen(name);
2150 
2151       general_log_print(thd, command, "Log: '%s'  Pos: %lu", name, pos);
2152       if (nlen < FN_REFLEN)
2153         mysql_binlog_send(thd, thd->strmake(name, nlen), (my_off_t)pos, flags);
2154       thd->unregister_slave(); // todo: can be extraneous
2155       /*  fake COM_QUIT -- if we get here, the thread needs to terminate */
2156       error = TRUE;
2157       break;
2158     }
2159 #endif
2160   case COM_REFRESH:
2161   {
2162     int not_used;
2163 
2164     /*
2165       Initialize thd->lex since it's used in many base functions, such as
2166       open_tables(). Otherwise, it remains unitialized and may cause crash
2167       during execution of COM_REFRESH.
2168     */
2169     lex_start(thd);
2170 
2171     status_var_increment(thd->status_var.com_stat[SQLCOM_FLUSH]);
2172     ulonglong options= (ulonglong) (uchar) packet[0];
2173     if (trans_commit_implicit(thd))
2174       break;
2175     thd->release_transactional_locks();
2176     if (check_global_access(thd,RELOAD_ACL))
2177       break;
2178     general_log_print(thd, command, NullS);
2179 #ifndef DBUG_OFF
2180     bool debug_simulate= FALSE;
2181     DBUG_EXECUTE_IF("simulate_detached_thread_refresh", debug_simulate= TRUE;);
2182     if (debug_simulate)
2183     {
2184       /* This code doesn't work under FTWRL */
2185       DBUG_ASSERT(! (options & REFRESH_READ_LOCK));
2186       /*
2187         Simulate a reload without a attached thread session.
2188         Provides a environment similar to that of when the
2189         server receives a SIGHUP signal and reloads caches
2190         and flushes tables.
2191       */
2192       bool res;
2193       set_current_thd(0);
2194       res= reload_acl_and_cache(NULL, options | REFRESH_FAST,
2195                                 NULL, &not_used);
2196       set_current_thd(thd);
2197       if (res)
2198         break;
2199     }
2200     else
2201 #endif
2202     {
2203       thd->lex->relay_log_connection_name= empty_clex_str;
2204       if (reload_acl_and_cache(thd, options, (TABLE_LIST*) 0, &not_used))
2205         break;
2206     }
2207     if (trans_commit_implicit(thd))
2208       break;
2209     close_thread_tables(thd);
2210     thd->release_transactional_locks();
2211     my_ok(thd);
2212     break;
2213   }
2214 #ifndef EMBEDDED_LIBRARY
2215   case COM_SHUTDOWN:
2216   {
2217     status_var_increment(thd->status_var.com_other);
2218     if (check_global_access(thd,SHUTDOWN_ACL))
2219       break; /* purecov: inspected */
2220     /*
2221       If the client is < 4.1.3, it is going to send us no argument; then
2222       packet_length is 0, packet[0] is the end 0 of the packet. Note that
2223       SHUTDOWN_DEFAULT is 0. If client is >= 4.1.3, the shutdown level is in
2224       packet[0].
2225     */
2226     enum mysql_enum_shutdown_level level;
2227     level= (enum mysql_enum_shutdown_level) (uchar) packet[0];
2228     thd->lex->is_shutdown_wait_for_slaves= false;  // "deferred" cleanup
2229     if (level == SHUTDOWN_DEFAULT)
2230       level= SHUTDOWN_WAIT_ALL_BUFFERS; // soon default will be configurable
2231     else if (level != SHUTDOWN_WAIT_ALL_BUFFERS)
2232     {
2233       my_error(ER_NOT_SUPPORTED_YET, MYF(0), "this shutdown level");
2234       break;
2235     }
2236     DBUG_PRINT("quit",("Got shutdown command for level %u", level));
2237     general_log_print(thd, command, NullS);
2238     my_eof(thd);
2239     kill_mysql(thd);
2240     error=TRUE;
2241     break;
2242   }
2243 #endif
2244   case COM_STATISTICS:
2245   {
2246     STATUS_VAR *current_global_status_var;      // Big; Don't allocate on stack
2247     ulong uptime;
2248     ulonglong queries_per_second1000;
2249     char buff[250];
2250     uint buff_len= sizeof(buff);
2251 
2252     if (!(current_global_status_var= (STATUS_VAR*)
2253           thd->alloc(sizeof(STATUS_VAR))))
2254       break;
2255     general_log_print(thd, command, NullS);
2256     status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS]);
2257     *current_global_status_var= global_status_var;
2258     calc_sum_of_all_status(current_global_status_var);
2259     if (!(uptime= (ulong) (thd->start_time - server_start_time)))
2260       queries_per_second1000= 0;
2261     else
2262       queries_per_second1000= thd->query_id * 1000 / uptime;
2263 #ifndef EMBEDDED_LIBRARY
2264     size_t length=
2265 #endif
2266     my_snprintf(buff, buff_len - 1,
2267                         "Uptime: %lu  Threads: %u  Questions: %lu  "
2268                         "Slow queries: %lu  Opens: %lu  "
2269                         "Open tables: %u  Queries per second avg: %u.%03u",
2270                         uptime, THD_count::value(), (ulong) thd->query_id,
2271                         current_global_status_var->long_query_count,
2272                         current_global_status_var->opened_tables,
2273                         tc_records(),
2274                         (uint) (queries_per_second1000 / 1000),
2275                         (uint) (queries_per_second1000 % 1000));
2276 #ifdef EMBEDDED_LIBRARY
2277     /* Store the buffer in permanent memory */
2278     my_ok(thd, 0, 0, buff);
2279 #else
2280     (void) my_net_write(net, (uchar*) buff, length);
2281     (void) net_flush(net);
2282     thd->get_stmt_da()->disable_status();
2283 #endif
2284     break;
2285   }
2286   case COM_PING:
2287     status_var_increment(thd->status_var.com_other);
2288     my_ok(thd);				// Tell client we are alive
2289     break;
2290   case COM_PROCESS_INFO:
2291     status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_PROCESSLIST]);
2292     if (!thd->security_ctx->priv_user[0] &&
2293         check_global_access(thd, PRIV_COM_PROCESS_INFO))
2294       break;
2295     general_log_print(thd, command, NullS);
2296     mysqld_list_processes(thd,
2297                      thd->security_ctx->master_access & PRIV_COM_PROCESS_INFO ?
2298                      NullS : thd->security_ctx->priv_user, 0);
2299     break;
2300   case COM_PROCESS_KILL:
2301   {
2302     status_var_increment(thd->status_var.com_stat[SQLCOM_KILL]);
2303     ulong id=(ulong) uint4korr(packet);
2304     sql_kill(thd, id, KILL_CONNECTION_HARD, KILL_TYPE_ID);
2305     break;
2306   }
2307   case COM_SET_OPTION:
2308   {
2309     status_var_increment(thd->status_var.com_stat[SQLCOM_SET_OPTION]);
2310     uint opt_command= uint2korr(packet);
2311 
2312     switch (opt_command) {
2313     case (int) MYSQL_OPTION_MULTI_STATEMENTS_ON:
2314       thd->client_capabilities|= CLIENT_MULTI_STATEMENTS;
2315       my_eof(thd);
2316       break;
2317     case (int) MYSQL_OPTION_MULTI_STATEMENTS_OFF:
2318       thd->client_capabilities&= ~CLIENT_MULTI_STATEMENTS;
2319       my_eof(thd);
2320       break;
2321     default:
2322       my_message(ER_UNKNOWN_COM_ERROR, ER_THD(thd, ER_UNKNOWN_COM_ERROR),
2323                  MYF(0));
2324       break;
2325     }
2326     break;
2327   }
2328   case COM_DEBUG:
2329     status_var_increment(thd->status_var.com_other);
2330     if (check_global_access(thd, PRIV_DEBUG))
2331       break;					/* purecov: inspected */
2332     mysql_print_status();
2333     general_log_print(thd, command, NullS);
2334     my_eof(thd);
2335     break;
2336   case COM_MULTI:
2337   {
2338     uint counter;
2339     uint current_com= 0;
2340     DBUG_ASSERT(!is_com_multi);
2341     if (!(thd->client_capabilities & CLIENT_MULTI_RESULTS))
2342     {
2343       /* The client does not support multiple result sets being sent back */
2344       my_error(ER_COMMULTI_BADCONTEXT, MYF(0));
2345       break;
2346     }
2347 
2348     if (!(counter= maria_multi_check(thd, packet, packet_length)))
2349       break;
2350 
2351     {
2352       char *packet_start= packet;
2353       /* We have to store next length because it will be destroyed by '\0' */
2354       size_t next_subpacket_length= net_field_length((uchar **)&packet_start);
2355       size_t next_length_length= packet_start - packet;
2356       unsigned char *readbuff= net->buff;
2357 
2358       if (net_allocate_new_packet(net, thd, MYF(MY_THREAD_SPECIFIC)))
2359         break;
2360 
2361       PSI_statement_locker *save_locker= thd->m_statement_psi;
2362       sql_digest_state *save_digest= thd->m_digest;
2363       thd->m_statement_psi= NULL;
2364       thd->m_digest= NULL;
2365 
2366       while (packet_length)
2367       {
2368         current_com++;
2369         size_t subpacket_length= next_subpacket_length + next_length_length;
2370         size_t length_length= next_length_length;
2371         if (subpacket_length < packet_length)
2372         {
2373           packet_start= packet + subpacket_length;
2374           next_subpacket_length= net_field_length((uchar**)&packet_start);
2375           next_length_length= packet_start - (packet + subpacket_length);
2376         }
2377         /* safety like in do_command() */
2378         packet[subpacket_length]= '\0';
2379 
2380         enum enum_server_command subcommand=
2381           fetch_command(thd, (packet + length_length));
2382 
2383         if (server_command_flags[subcommand] & CF_NO_COM_MULTI)
2384         {
2385           my_error(ER_BAD_COMMAND_IN_MULTI, MYF(0),
2386                    command_name[subcommand].str);
2387           goto com_multi_end;
2388         }
2389 
2390         if (dispatch_command(subcommand, thd, packet + (1 + length_length),
2391                              (uint)(subpacket_length - (1 + length_length)), TRUE,
2392                              (current_com != counter)))
2393         {
2394           DBUG_ASSERT(thd->is_error());
2395           goto com_multi_end;
2396         }
2397 
2398         DBUG_ASSERT(subpacket_length <= packet_length);
2399         packet+= subpacket_length;
2400         packet_length-= (uint)subpacket_length;
2401       }
2402 
2403 com_multi_end:
2404       thd->m_statement_psi= save_locker;
2405       thd->m_digest= save_digest;
2406 
2407       /* release old buffer */
2408       net_flush(net);
2409       DBUG_ASSERT(net->buff == net->write_pos); // nothing to send
2410       my_free(readbuff);
2411     }
2412     break;
2413   }
2414   case COM_SLEEP:
2415   case COM_CONNECT:				// Impossible here
2416   case COM_TIME:				// Impossible from client
2417   case COM_DELAYED_INSERT:
2418   case COM_END:
2419   case COM_UNIMPLEMENTED:
2420   default:
2421     my_message(ER_UNKNOWN_COM_ERROR, ER_THD(thd, ER_UNKNOWN_COM_ERROR),
2422                MYF(0));
2423     break;
2424   }
2425 
2426 dispatch_end:
2427   do_end_of_statement= true;
2428 #ifdef WITH_WSREP
2429   /*
2430     Next test should really be WSREP(thd), but that causes a failure when doing
2431     'set WSREP_ON=0'
2432   */
2433   if (unlikely(wsrep_service_started))
2434   {
2435     if (thd->killed == KILL_QUERY)
2436     {
2437       WSREP_DEBUG("THD is killed at dispatch_end");
2438     }
2439     wsrep_after_command_before_result(thd);
2440     if (wsrep_current_error(thd) && !wsrep_command_no_result(command))
2441     {
2442       /* todo: Pass wsrep client state current error to override */
2443       wsrep_override_error(thd, wsrep_current_error(thd),
2444                            wsrep_current_error_status(thd));
2445       WSREP_LOG_THD(thd, "leave");
2446     }
2447     if (WSREP(thd))
2448     {
2449       /*
2450         MDEV-10812
2451         In the case of COM_QUIT/COM_STMT_CLOSE thread status should be disabled.
2452       */
2453       DBUG_ASSERT((command != COM_QUIT && command != COM_STMT_CLOSE)
2454                   || thd->get_stmt_da()->is_disabled());
2455       DBUG_ASSERT(thd->wsrep_trx().state() != wsrep::transaction::s_replaying);
2456       /* wsrep BF abort in query exec phase */
2457       mysql_mutex_lock(&thd->LOCK_thd_kill);
2458       do_end_of_statement= thd_is_connection_alive(thd);
2459       mysql_mutex_unlock(&thd->LOCK_thd_kill);
2460     }
2461   }
2462 #endif /* WITH_WSREP */
2463 
2464 
2465   if (do_end_of_statement)
2466   {
2467     DBUG_ASSERT(thd->derived_tables == NULL &&
2468                (thd->open_tables == NULL ||
2469                (thd->locked_tables_mode == LTM_LOCK_TABLES)));
2470 
2471     thd_proc_info(thd, "Updating status");
2472     /* Finalize server status flags after executing a command. */
2473     thd->update_server_status();
2474     if (command != COM_MULTI)
2475     {
2476       thd->protocol->end_statement();
2477       query_cache_end_of_result(thd);
2478     }
2479   }
2480   if (drop_more_results)
2481     thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
2482 
2483   if (likely(!thd->is_error() && !thd->killed_errno()))
2484     mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_RESULT, 0, 0);
2485 
2486   mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_STATUS,
2487                       thd->get_stmt_da()->is_error() ?
2488                       thd->get_stmt_da()->sql_errno() : 0,
2489                       command_name[command].str);
2490 
2491   thd->update_all_stats();
2492 
2493   log_slow_statement(thd);
2494 
2495   THD_STAGE_INFO(thd, stage_cleaning_up);
2496   thd->reset_query();
2497 
2498   /* Performance Schema Interface instrumentation, end */
2499   MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
2500   thd->set_examined_row_count(0);                   // For processlist
2501   thd->set_command(COM_SLEEP);
2502 
2503   thd->m_statement_psi= NULL;
2504   thd->m_digest= NULL;
2505 
2506   if (!is_com_multi)
2507     thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory
2508 
2509   thd->reset_kill_query();  /* Ensure that killed_errmsg is released */
2510   /*
2511     LEX::m_sql_cmd can point to Sql_cmd allocated on thd->mem_root.
2512     Unlink it now, before freeing the root.
2513   */
2514   thd->lex->m_sql_cmd= NULL;
2515   free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
2516 
2517 #if defined(ENABLED_PROFILING)
2518   thd->profiling.finish_current_query();
2519 #endif
2520   if (MYSQL_QUERY_DONE_ENABLED() || MYSQL_COMMAND_DONE_ENABLED())
2521   {
2522     int res __attribute__((unused));
2523     res= (int) thd->is_error();
2524     if (command == COM_QUERY)
2525     {
2526       MYSQL_QUERY_DONE(res);
2527     }
2528     MYSQL_COMMAND_DONE(res);
2529   }
2530   DEBUG_SYNC(thd,"dispatch_command_end");
2531 
2532   /* Check that some variables are reset properly */
2533   DBUG_ASSERT(thd->abort_on_warning == 0);
2534   thd->lex->restore_set_statement_var();
2535   DBUG_RETURN(error);
2536 }
2537 
slow_filter_masked(THD * thd,ulonglong mask)2538 static bool slow_filter_masked(THD *thd, ulonglong mask)
2539 {
2540   return thd->variables.log_slow_filter && !(thd->variables.log_slow_filter & mask);
2541 }
2542 
2543 /*
2544   Log query to slow queries, if it passes filtering
2545 
2546   @note
2547     This function must call delete_explain_query().
2548 */
2549 
log_slow_statement(THD * thd)2550 void log_slow_statement(THD *thd)
2551 {
2552   DBUG_ENTER("log_slow_statement");
2553 
2554   /*
2555     The following should never be true with our current code base,
2556     but better to keep this here so we don't accidently try to log a
2557     statement in a trigger or stored function
2558   */
2559   if (unlikely(thd->in_sub_stmt))
2560     goto end;                           // Don't set time for sub stmt
2561   /*
2562     Skip both long_query_count increment and logging if the current
2563     statement forces slow log suppression (e.g. an SP statement).
2564 
2565     Note, we don't check for global_system_variables.sql_log_slow here.
2566     According to the manual, the "Slow_queries" status variable does not require
2567     sql_log_slow to be ON. So even if sql_log_slow is OFF, we still need to
2568     continue and increment long_query_count (and skip only logging, see below):
2569   */
2570   if (!thd->enable_slow_log)
2571     goto end; // E.g. SP statement
2572 
2573   DBUG_EXECUTE_IF("simulate_slow_query", {
2574                   if (thd->get_command() == COM_QUERY ||
2575                       thd->get_command() == COM_STMT_EXECUTE)
2576                     thd->server_status|= SERVER_QUERY_WAS_SLOW;
2577                   });
2578 
2579   if ((thd->server_status &
2580        (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) &&
2581       !(thd->query_plan_flags & QPLAN_STATUS) &&
2582       !slow_filter_masked(thd, QPLAN_NOT_USING_INDEX))
2583   {
2584     thd->query_plan_flags|= QPLAN_NOT_USING_INDEX;
2585     /* We are always logging no index queries if enabled in filter */
2586     thd->server_status|= SERVER_QUERY_WAS_SLOW;
2587   }
2588 
2589   if ((thd->server_status & SERVER_QUERY_WAS_SLOW) &&
2590       thd->get_examined_row_count() >= thd->variables.min_examined_row_limit)
2591   {
2592     thd->status_var.long_query_count++;
2593 
2594     /*
2595       until log_slow_disabled_statements=admin is removed, it
2596       duplicates slow_log_filter=admin
2597     */
2598     if ((thd->query_plan_flags & QPLAN_ADMIN) &&
2599         (thd->variables.log_slow_disabled_statements & LOG_SLOW_DISABLE_ADMIN))
2600       goto end;
2601 
2602     if (!global_system_variables.sql_log_slow || !thd->variables.sql_log_slow)
2603       goto end;
2604 
2605     /*
2606       If rate limiting of slow log writes is enabled, decide whether to log
2607       this query to the log or not.
2608     */
2609     if (thd->variables.log_slow_rate_limit > 1 &&
2610         (global_query_id % thd->variables.log_slow_rate_limit) != 0)
2611       goto end;
2612 
2613     /*
2614       Follow the slow log filter configuration:
2615       skip logging if the current statement matches the filter.
2616     */
2617     if (slow_filter_masked(thd, thd->query_plan_flags))
2618       goto end;
2619 
2620     THD_STAGE_INFO(thd, stage_logging_slow_query);
2621     slow_log_print(thd, thd->query(), thd->query_length(),
2622                    thd->utime_after_query);
2623   }
2624 
2625 end:
2626   delete_explain_query(thd->lex);
2627   DBUG_VOID_RETURN;
2628 }
2629 
2630 
2631 /**
2632   Create a TABLE_LIST object for an INFORMATION_SCHEMA table.
2633 
2634     This function is used in the parser to convert a SHOW or DESCRIBE
2635     table_name command to a SELECT from INFORMATION_SCHEMA.
2636     It prepares a SELECT_LEX and a TABLE_LIST object to represent the
2637     given command as a SELECT parse tree.
2638 
2639   @param thd              thread handle
2640   @param lex              current lex
2641   @param table_ident      table alias if it's used
2642   @param schema_table_idx the type of the INFORMATION_SCHEMA table to be
2643                           created
2644 
2645   @note
2646     Due to the way this function works with memory and LEX it cannot
2647     be used outside the parser (parse tree transformations outside
2648     the parser break PS and SP).
2649 
2650   @retval
2651     0                 success
2652   @retval
2653     1                 out of memory or SHOW commands are not allowed
2654                       in this version of the server.
2655 */
2656 
prepare_schema_table(THD * thd,LEX * lex,Table_ident * table_ident,enum enum_schema_tables schema_table_idx)2657 int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
2658                          enum enum_schema_tables schema_table_idx)
2659 {
2660   SELECT_LEX *schema_select_lex= NULL;
2661   DBUG_ENTER("prepare_schema_table");
2662 
2663   switch (schema_table_idx) {
2664   case SCH_SCHEMATA:
2665 #if defined(DONT_ALLOW_SHOW_COMMANDS)
2666     my_message(ER_NOT_ALLOWED_COMMAND,
2667                ER_THD(thd, ER_NOT_ALLOWED_COMMAND), MYF(0));
2668     DBUG_RETURN(1);
2669 #else
2670     break;
2671 #endif
2672 
2673   case SCH_TABLE_NAMES:
2674   case SCH_TABLES:
2675   case SCH_CHECK_CONSTRAINTS:
2676   case SCH_VIEWS:
2677   case SCH_TRIGGERS:
2678   case SCH_EVENTS:
2679 #ifdef DONT_ALLOW_SHOW_COMMANDS
2680     my_message(ER_NOT_ALLOWED_COMMAND,
2681                ER_THD(thd, ER_NOT_ALLOWED_COMMAND), MYF(0));
2682     DBUG_RETURN(1);
2683 #else
2684     {
2685       if (lex->first_select_lex()->db.str == NULL &&
2686           lex->copy_db_to(&lex->first_select_lex()->db))
2687       {
2688         DBUG_RETURN(1);
2689       }
2690       schema_select_lex= new (thd->mem_root) SELECT_LEX();
2691       schema_select_lex->table_list.first= NULL;
2692       if (lower_case_table_names == 1)
2693         lex->first_select_lex()->db.str=
2694           thd->strdup(lex->first_select_lex()->db.str);
2695       schema_select_lex->db= lex->first_select_lex()->db;
2696       /*
2697         check_db_name() may change db.str if lower_case_table_names == 1,
2698         but that's ok as the db is allocted above in this case.
2699       */
2700       if (check_db_name((LEX_STRING*) &lex->first_select_lex()->db))
2701       {
2702         my_error(ER_WRONG_DB_NAME, MYF(0), lex->first_select_lex()->db.str);
2703         DBUG_RETURN(1);
2704       }
2705       break;
2706     }
2707 #endif
2708   case SCH_COLUMNS:
2709   case SCH_STATISTICS:
2710 #ifdef DONT_ALLOW_SHOW_COMMANDS
2711     my_message(ER_NOT_ALLOWED_COMMAND,
2712                ER_THD(thd, ER_NOT_ALLOWED_COMMAND), MYF(0));
2713     DBUG_RETURN(1);
2714 #else
2715   {
2716     DBUG_ASSERT(table_ident);
2717     TABLE_LIST **query_tables_last= lex->query_tables_last;
2718     schema_select_lex= new (thd->mem_root) SELECT_LEX();
2719     /* 'parent_lex' is used in init_query() so it must be before it. */
2720     schema_select_lex->parent_lex= lex;
2721     schema_select_lex->init_query();
2722     schema_select_lex->select_number= 0;
2723     if (!schema_select_lex->add_table_to_list(thd, table_ident, 0, 0, TL_READ,
2724                                               MDL_SHARED_READ))
2725       DBUG_RETURN(1);
2726     lex->query_tables_last= query_tables_last;
2727     break;
2728 #endif
2729   }
2730   case SCH_PROFILES:
2731     /*
2732       Mark this current profiling record to be discarded.  We don't
2733       wish to have SHOW commands show up in profiling.
2734     */
2735 #if defined(ENABLED_PROFILING)
2736     thd->profiling.discard_current_query();
2737 #endif
2738     break;
2739   default:
2740     break;
2741   }
2742   if (schema_select_lex)
2743     schema_select_lex->set_master_unit(&lex->unit);
2744   SELECT_LEX *select_lex= lex->current_select;
2745   if (make_schema_select(thd, select_lex, get_schema_table(schema_table_idx)))
2746     DBUG_RETURN(1);
2747 
2748   select_lex->table_list.first->schema_select_lex= schema_select_lex;
2749   DBUG_RETURN(0);
2750 }
2751 
2752 
2753 /**
2754   Read query from packet and store in thd->query.
2755   Used in COM_QUERY and COM_STMT_PREPARE.
2756 
2757     Sets the following THD variables:
2758   - query
2759   - query_length
2760 
2761   @retval
2762     FALSE ok
2763   @retval
2764     TRUE  error;  In this case thd->fatal_error is set
2765 */
2766 
alloc_query(THD * thd,const char * packet,size_t packet_length)2767 bool alloc_query(THD *thd, const char *packet, size_t packet_length)
2768 {
2769   char *query;
2770   /* Remove garbage at start and end of query */
2771   while (packet_length > 0 && my_isspace(thd->charset(), packet[0]))
2772   {
2773     packet++;
2774     packet_length--;
2775   }
2776   const char *pos= packet + packet_length;     // Point at end null
2777   while (packet_length > 0 &&
2778 	 (pos[-1] == ';' || my_isspace(thd->charset() ,pos[-1])))
2779   {
2780     pos--;
2781     packet_length--;
2782   }
2783   /* We must allocate some extra memory for query cache
2784 
2785     The query buffer layout is:
2786        buffer :==
2787             <statement>   The input statement(s)
2788             '\0'          Terminating null char  (1 byte)
2789             <length>      Length of following current database name (size_t)
2790             <db_name>     Name of current database
2791             <flags>       Flags struct
2792   */
2793   if (! (query= (char*) thd->memdup_w_gap(packet,
2794                                           packet_length,
2795                                           1 + thd->db.length +
2796                                           QUERY_CACHE_DB_LENGTH_SIZE +
2797                                           QUERY_CACHE_FLAGS_SIZE)))
2798       return TRUE;
2799   query[packet_length]= '\0';
2800   /*
2801     Space to hold the name of the current database is allocated.  We
2802     also store this length, in case current database is changed during
2803     execution.  We might need to reallocate the 'query' buffer
2804   */
2805   int2store(query + packet_length + 1, thd->db.length);
2806 
2807   thd->set_query(query, packet_length);
2808 
2809   /* Reclaim some memory */
2810   thd->packet.shrink(thd->variables.net_buffer_length);
2811   thd->convert_buffer.shrink(thd->variables.net_buffer_length);
2812 
2813   return FALSE;
2814 }
2815 
2816 
sp_process_definer(THD * thd)2817 bool sp_process_definer(THD *thd)
2818 {
2819   DBUG_ENTER("sp_process_definer");
2820 
2821   LEX *lex= thd->lex;
2822 
2823   /*
2824     If the definer is not specified, this means that CREATE-statement missed
2825     DEFINER-clause. DEFINER-clause can be missed in two cases:
2826 
2827       - The user submitted a statement w/o the clause. This is a normal
2828         case, we should assign CURRENT_USER as definer.
2829 
2830       - Our slave received an updated from the master, that does not
2831         replicate definer for stored rountines. We should also assign
2832         CURRENT_USER as definer here, but also we should mark this routine
2833         as NON-SUID. This is essential for the sake of backward
2834         compatibility.
2835 
2836         The problem is the slave thread is running under "special" user (@),
2837         that actually does not exist. In the older versions we do not fail
2838         execution of a stored routine if its definer does not exist and
2839         continue the execution under the authorization of the invoker
2840         (BUG#13198). And now if we try to switch to slave-current-user (@),
2841         we will fail.
2842 
2843         Actually, this leads to the inconsistent state of master and
2844         slave (different definers, different SUID behaviour), but it seems,
2845         this is the best we can do.
2846   */
2847 
2848   if (!lex->definer)
2849   {
2850     Query_arena original_arena;
2851     Query_arena *ps_arena= thd->activate_stmt_arena_if_needed(&original_arena);
2852 
2853     lex->definer= create_default_definer(thd, false);
2854 
2855     if (ps_arena)
2856       thd->restore_active_arena(ps_arena, &original_arena);
2857 
2858     /* Error has been already reported. */
2859     if (lex->definer == NULL)
2860       DBUG_RETURN(TRUE);
2861 
2862     if (thd->slave_thread && lex->sphead)
2863       lex->sphead->set_suid(SP_IS_NOT_SUID);
2864   }
2865   else
2866   {
2867     LEX_USER *d= lex->definer= get_current_user(thd, lex->definer);
2868     if (!d)
2869       DBUG_RETURN(TRUE);
2870 
2871     /*
2872       If the specified definer differs from the current user or role, we
2873       should check that the current user has SUPER privilege (in order
2874       to create a stored routine under another user one must have
2875       SUPER privilege).
2876     */
2877     bool curuser= !strcmp(d->user.str, thd->security_ctx->priv_user);
2878     bool currole= !curuser && !strcmp(d->user.str, thd->security_ctx->priv_role);
2879     bool curuserhost= curuser && d->host.str &&
2880                   !my_strcasecmp(system_charset_info, d->host.str,
2881                                  thd->security_ctx->priv_host);
2882     if (!curuserhost && !currole &&
2883         check_global_access(thd, PRIV_DEFINER_CLAUSE, false))
2884       DBUG_RETURN(TRUE);
2885   }
2886 
2887   /* Check that the specified definer exists. Emit a warning if not. */
2888 
2889 #ifndef NO_EMBEDDED_ACCESS_CHECKS
2890   if (!is_acl_user(lex->definer->host.str, lex->definer->user.str))
2891   {
2892     push_warning_printf(thd,
2893                         Sql_condition::WARN_LEVEL_NOTE,
2894                         ER_NO_SUCH_USER,
2895                         ER_THD(thd, ER_NO_SUCH_USER),
2896                         lex->definer->user.str,
2897                         lex->definer->host.str);
2898   }
2899 #endif /* NO_EMBEDDED_ACCESS_CHECKS */
2900 
2901   DBUG_RETURN(FALSE);
2902 }
2903 
2904 
2905 /**
2906   Auxiliary call that opens and locks tables for LOCK TABLES statement
2907   and initializes the list of locked tables.
2908 
2909   @param thd     Thread context.
2910   @param tables  List of tables to be locked.
2911 
2912   @return FALSE in case of success, TRUE in case of error.
2913 */
2914 
2915 static bool __attribute__ ((noinline))
lock_tables_open_and_lock_tables(THD * thd,TABLE_LIST * tables)2916 lock_tables_open_and_lock_tables(THD *thd, TABLE_LIST *tables)
2917 {
2918   Lock_tables_prelocking_strategy lock_tables_prelocking_strategy;
2919   MDL_deadlock_and_lock_abort_error_handler deadlock_handler;
2920   MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint();
2921   uint counter;
2922   TABLE_LIST *table;
2923 
2924   thd->in_lock_tables= 1;
2925 
2926 retry:
2927 
2928   if (open_tables(thd, &tables, &counter, 0, &lock_tables_prelocking_strategy))
2929     goto err;
2930 
2931   for (table= tables; table; table= table->next_global)
2932   {
2933     if (!table->placeholder())
2934     {
2935       if (table->table->s->tmp_table)
2936       {
2937         /*
2938           We allow to change temporary tables even if they were locked for read
2939           by LOCK TABLES. To avoid a discrepancy between lock acquired at LOCK
2940           TABLES time and by the statement which is later executed under LOCK
2941           TABLES we ensure that for temporary tables we always request a write
2942           lock (such discrepancy can cause problems for the storage engine).
2943           We don't set TABLE_LIST::lock_type in this case as this might result
2944           in extra warnings from THD::decide_logging_format() even though
2945           binary logging is totally irrelevant for LOCK TABLES.
2946         */
2947         table->table->reginfo.lock_type= TL_WRITE;
2948       }
2949       else if (table->mdl_request.type == MDL_SHARED_READ &&
2950                ! table->prelocking_placeholder &&
2951                table->table->file->lock_count() == 0)
2952       {
2953         enum enum_mdl_type lock_type;
2954         /*
2955           In case when LOCK TABLE ... READ LOCAL was issued for table with
2956           storage engine which doesn't support READ LOCAL option and doesn't
2957           use THR_LOCK locks we need to upgrade weak SR metadata lock acquired
2958           in open_tables() to stronger SRO metadata lock.
2959           This is not needed for tables used through stored routines or
2960           triggers as we always acquire SRO (or even stronger SNRW) metadata
2961           lock for them.
2962         */
2963         deadlock_handler.init();
2964         thd->push_internal_handler(&deadlock_handler);
2965 
2966         lock_type= table->table->mdl_ticket->get_type() == MDL_SHARED_WRITE ?
2967                    MDL_SHARED_NO_READ_WRITE : MDL_SHARED_READ_ONLY;
2968 
2969         bool result= thd->mdl_context.upgrade_shared_lock(
2970                                         table->table->mdl_ticket,
2971                                         lock_type,
2972                                         thd->variables.lock_wait_timeout);
2973 
2974         thd->pop_internal_handler();
2975 
2976         if (deadlock_handler.need_reopen())
2977         {
2978           /*
2979             Deadlock occurred during upgrade of metadata lock.
2980             Let us restart acquring and opening tables for LOCK TABLES.
2981           */
2982           close_tables_for_reopen(thd, &tables, mdl_savepoint);
2983           if (thd->open_temporary_tables(tables))
2984             goto err;
2985           goto retry;
2986         }
2987 
2988         if (result)
2989           goto err;
2990       }
2991     }
2992     /*
2993        Check privileges of view tables here, after views were opened.
2994        Either definer or invoker has to have PRIV_LOCK_TABLES to be able
2995        to lock view and its tables. For mysqldump (that locks views
2996        before dumping their structures) compatibility we allow locking
2997        views that select from I_S or P_S tables, but downrade the lock
2998        to TL_READ
2999      */
3000     if (table->belong_to_view &&
3001         check_single_table_access(thd, PRIV_LOCK_TABLES, table, 1))
3002     {
3003       if (table->grant.m_internal.m_schema_access)
3004         table->lock_type= TL_READ;
3005       else
3006       {
3007         bool error= true;
3008         if (Security_context *sctx= table->security_ctx)
3009         {
3010           table->security_ctx= 0;
3011           error= check_single_table_access(thd, PRIV_LOCK_TABLES, table, 1);
3012           table->security_ctx= sctx;
3013         }
3014         if (error)
3015         {
3016           my_error(ER_VIEW_INVALID, MYF(0), table->belong_to_view->view_db.str,
3017                    table->belong_to_view->view_name.str);
3018           goto err;
3019         }
3020       }
3021     }
3022   }
3023 
3024   if (lock_tables(thd, tables, counter, 0) ||
3025       thd->locked_tables_list.init_locked_tables(thd))
3026     goto err;
3027 
3028   thd->in_lock_tables= 0;
3029 
3030   return FALSE;
3031 
3032 err:
3033   thd->in_lock_tables= 0;
3034 
3035   trans_rollback_stmt(thd);
3036   /*
3037     Need to end the current transaction, so the storage engine (InnoDB)
3038     can free its locks if LOCK TABLES locked some tables before finding
3039     that it can't lock a table in its list
3040   */
3041   trans_rollback(thd);
3042   /* Close tables and release metadata locks. */
3043   close_thread_tables(thd);
3044   DBUG_ASSERT(!thd->locked_tables_mode);
3045   thd->release_transactional_locks();
3046   return TRUE;
3047 }
3048 
3049 
do_execute_sp(THD * thd,sp_head * sp)3050 static bool do_execute_sp(THD *thd, sp_head *sp)
3051 {
3052   /* bits that should be cleared in thd->server_status */
3053   uint bits_to_be_cleared= 0;
3054   ulonglong affected_rows;
3055   if (sp->m_flags & sp_head::MULTI_RESULTS)
3056   {
3057     if (!(thd->client_capabilities & CLIENT_MULTI_RESULTS))
3058     {
3059       /* The client does not support multiple result sets being sent back */
3060       my_error(ER_SP_BADSELECT, MYF(0), ErrConvDQName(sp).ptr());
3061       return 1;
3062     }
3063   }
3064   /*
3065     If SERVER_MORE_RESULTS_EXISTS is not set,
3066     then remember that it should be cleared
3067   */
3068   bits_to_be_cleared= (~thd->server_status &
3069                        SERVER_MORE_RESULTS_EXISTS);
3070   thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
3071   ha_rows select_limit= thd->variables.select_limit;
3072   thd->variables.select_limit= HA_POS_ERROR;
3073 
3074   /*
3075     Reset current_select as it may point to random data as a
3076     result of previous parsing.
3077   */
3078   thd->lex->current_select= NULL;
3079   thd->lex->in_sum_func= 0;                     // For Item_field::fix_fields()
3080 
3081   /*
3082     We never write CALL statements into binlog:
3083      - If the mode is non-prelocked, each statement will be logged
3084        separately.
3085      - If the mode is prelocked, the invoking statement will care
3086        about writing into binlog.
3087     So just execute the statement.
3088   */
3089   int res= sp->execute_procedure(thd, &thd->lex->value_list);
3090 
3091   thd->variables.select_limit= select_limit;
3092   thd->server_status&= ~bits_to_be_cleared;
3093 
3094   if (res)
3095   {
3096     DBUG_ASSERT(thd->is_error() || thd->killed);
3097     return 1;  		// Substatement should already have sent error
3098   }
3099 
3100   affected_rows= thd->affected_rows; // Affected rows for all sub statements
3101   thd->affected_rows= 0;             // Reset total, as my_ok() adds to it
3102   my_ok(thd, affected_rows);
3103   return 0;
3104 }
3105 
3106 
3107 static int __attribute__ ((noinline))
mysql_create_routine(THD * thd,LEX * lex)3108 mysql_create_routine(THD *thd, LEX *lex)
3109 {
3110   DBUG_ASSERT(lex->sphead != 0);
3111   DBUG_ASSERT(lex->sphead->m_db.str); /* Must be initialized in the parser */
3112   /*
3113     Verify that the database name is allowed, optionally
3114     lowercase it.
3115   */
3116   if (check_db_name((LEX_STRING*) &lex->sphead->m_db))
3117   {
3118     my_error(ER_WRONG_DB_NAME, MYF(0), lex->sphead->m_db.str);
3119     return true;
3120   }
3121 
3122   if (check_access(thd, CREATE_PROC_ACL, lex->sphead->m_db.str,
3123                    NULL, NULL, 0, 0))
3124     return true;
3125 
3126   /* Checking the drop permissions if CREATE OR REPLACE is used */
3127   if (lex->create_info.or_replace())
3128   {
3129     if (check_routine_access(thd, ALTER_PROC_ACL, &lex->sphead->m_db,
3130                              &lex->sphead->m_name,
3131                              Sp_handler::handler(lex->sql_command), 0))
3132       return true;
3133   }
3134 
3135   const LEX_CSTRING *name= lex->sphead->name();
3136 #ifdef HAVE_DLOPEN
3137   if (lex->sphead->m_handler->type() == SP_TYPE_FUNCTION)
3138   {
3139     udf_func *udf = find_udf(name->str, name->length);
3140 
3141     if (udf)
3142     {
3143       my_error(ER_UDF_EXISTS, MYF(0), name->str);
3144       return true;
3145     }
3146   }
3147 #endif
3148 
3149   if (sp_process_definer(thd))
3150     return true;
3151 
3152   WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
3153 
3154   if (!lex->sphead->m_handler->sp_create_routine(thd, lex->sphead))
3155   {
3156 #ifndef NO_EMBEDDED_ACCESS_CHECKS
3157     /* only add privileges if really neccessary */
3158 
3159     Security_context security_context;
3160     bool restore_backup_context= false;
3161     Security_context *backup= NULL;
3162     LEX_USER *definer= thd->lex->definer;
3163     /*
3164       We're going to issue an implicit GRANT statement so we close all
3165       open tables. We have to keep metadata locks as this ensures that
3166       this statement is atomic against concurent FLUSH TABLES WITH READ
3167       LOCK. Deadlocks which can arise due to fact that this implicit
3168       statement takes metadata locks should be detected by a deadlock
3169       detector in MDL subsystem and reported as errors.
3170 
3171       TODO: Long-term we should either ensure that implicit GRANT statement
3172             is written into binary log as a separate statement or make both
3173             creation of routine and implicit GRANT parts of one fully atomic
3174             statement.
3175       */
3176     if (trans_commit_stmt(thd))
3177       goto wsrep_error_label;
3178     close_thread_tables(thd);
3179     /*
3180       Check if the definer exists on slave,
3181       then use definer privilege to insert routine privileges to mysql.procs_priv.
3182 
3183       For current user of SQL thread has GLOBAL_ACL privilege,
3184       which doesn't any check routine privileges,
3185       so no routine privilege record  will insert into mysql.procs_priv.
3186     */
3187     if (thd->slave_thread && is_acl_user(definer->host.str, definer->user.str))
3188     {
3189       security_context.change_security_context(thd,
3190                                                &thd->lex->definer->user,
3191                                                &thd->lex->definer->host,
3192                                                &thd->lex->sphead->m_db,
3193                                                &backup);
3194       restore_backup_context= true;
3195     }
3196 
3197     if (sp_automatic_privileges && !opt_noacl &&
3198         check_routine_access(thd, DEFAULT_CREATE_PROC_ACLS,
3199                              &lex->sphead->m_db, name,
3200                              Sp_handler::handler(lex->sql_command), 1))
3201     {
3202       if (sp_grant_privileges(thd, lex->sphead->m_db.str, name->str,
3203                               Sp_handler::handler(lex->sql_command)))
3204         push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
3205                      ER_PROC_AUTO_GRANT_FAIL, ER_THD(thd, ER_PROC_AUTO_GRANT_FAIL));
3206       thd->clear_error();
3207     }
3208 
3209     /*
3210       Restore current user with GLOBAL_ACL privilege of SQL thread
3211     */
3212     if (restore_backup_context)
3213     {
3214       DBUG_ASSERT(thd->slave_thread == 1);
3215       thd->security_ctx->restore_security_context(thd, backup);
3216     }
3217 
3218 #endif
3219     return false;
3220   }
3221   (void) trans_commit_stmt(thd);
3222 
3223 #if !defined(NO_EMBEDDED_ACCESS_CHECKS) || defined(WITH_WSREP)
3224 wsrep_error_label:
3225 #endif
3226   return true;
3227 }
3228 
3229 
3230 /**
3231   Prepare for CREATE DATABASE, ALTER DATABASE, DROP DATABASE.
3232 
3233   @param thd         - current THD
3234   @param want_access - access needed
3235   @param dbname      - the database name
3236 
3237   @retval false      - Ok to proceed with CREATE/ALTER/DROP
3238   @retval true       - not OK to proceed (error, or filtered)
3239 
3240   Note, on slave this function returns true if the database
3241   is in the ignore filter. The caller must distinguish this case
3242   from other cases: bad database error, no access error.
3243   This can be done by testing thd->is_error().
3244 */
prepare_db_action(THD * thd,privilege_t want_access,LEX_CSTRING * dbname)3245 static bool prepare_db_action(THD *thd, privilege_t want_access,
3246                               LEX_CSTRING *dbname)
3247 {
3248   if (check_db_name((LEX_STRING*)dbname))
3249   {
3250     my_error(ER_WRONG_DB_NAME, MYF(0), dbname->str);
3251     return true;
3252   }
3253   /*
3254     If in a slave thread :
3255     - CREATE DATABASE DB was certainly not preceded by USE DB.
3256     - ALTER DATABASE DB may not be preceded by USE DB.
3257     - DROP DATABASE DB may not be preceded by USE DB.
3258     For that reason, db_ok() in sql/slave.cc did not check the
3259     do_db/ignore_db. And as this query involves no tables, tables_ok()
3260     was not called. So we have to check rules again here.
3261   */
3262 #ifdef HAVE_REPLICATION
3263   if (thd->slave_thread)
3264   {
3265     Rpl_filter *rpl_filter;
3266     rpl_filter= thd->system_thread_info.rpl_sql_info->rpl_filter;
3267     if (!rpl_filter->db_ok(dbname->str) ||
3268         !rpl_filter->db_ok_with_wild_table(dbname->str))
3269     {
3270       my_message(ER_SLAVE_IGNORED_TABLE,
3271                  ER_THD(thd, ER_SLAVE_IGNORED_TABLE), MYF(0));
3272       return true;
3273     }
3274   }
3275 #endif
3276   return check_access(thd, want_access, dbname->str, NULL, NULL, 1, 0);
3277 }
3278 
3279 
execute(THD * thd)3280 bool Sql_cmd_call::execute(THD *thd)
3281 {
3282   TABLE_LIST *all_tables= thd->lex->query_tables;
3283   sp_head *sp;
3284   /*
3285     This will cache all SP and SF and open and lock all tables
3286     required for execution.
3287   */
3288   if (check_table_access(thd, SELECT_ACL, all_tables, FALSE,
3289                          UINT_MAX, FALSE) ||
3290       open_and_lock_tables(thd, all_tables, TRUE, 0))
3291    return true;
3292 
3293   /*
3294     By this moment all needed SPs should be in cache so no need to look
3295     into DB.
3296   */
3297   if (!(sp= m_handler->sp_find_routine(thd, m_name, true)))
3298   {
3299     /*
3300       If the routine is not found, let's still check EXECUTE_ACL to decide
3301       whether to return "Access denied" or "Routine does not exist".
3302     */
3303     if (check_routine_access(thd, EXECUTE_ACL, &m_name->m_db,
3304                              &m_name->m_name,
3305                              &sp_handler_procedure,
3306                              false))
3307       return true;
3308     /*
3309       sp_find_routine can have issued an ER_SP_RECURSION_LIMIT error.
3310       Send message ER_SP_DOES_NOT_EXIST only if procedure is not found in
3311       cache.
3312     */
3313     if (!sp_cache_lookup(&thd->sp_proc_cache, m_name))
3314       my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PROCEDURE",
3315                ErrConvDQName(m_name).ptr());
3316     return true;
3317   }
3318   else
3319   {
3320     if (sp->check_execute_access(thd))
3321       return true;
3322     /*
3323       Check that the stored procedure doesn't contain Dynamic SQL
3324       and doesn't return result sets: such stored procedures can't
3325       be called from a function or trigger.
3326     */
3327     if (thd->in_sub_stmt)
3328     {
3329       const char *where= (thd->in_sub_stmt & SUB_STMT_TRIGGER ?
3330                           "trigger" : "function");
3331       if (sp->is_not_allowed_in_function(where))
3332         return true;
3333     }
3334 
3335     if (do_execute_sp(thd, sp))
3336       return true;
3337 
3338     /*
3339       Disable slow log for the above call(), if calls are disabled.
3340       Instead we will log the executed statements to the slow log.
3341     */
3342     if (thd->variables.log_slow_disabled_statements & LOG_SLOW_DISABLE_CALL)
3343       thd->enable_slow_log= 0;
3344   }
3345   return false;
3346 }
3347 
3348 
3349 /**
3350   Check whether the SQL statement being processed is prepended by
3351   SET STATEMENT clause and handle variables assignment if it is.
3352 
3353   @param thd  thread handle
3354   @param lex  current lex
3355 
3356   @return false in case of success, true in case of error.
3357 */
3358 
run_set_statement_if_requested(THD * thd,LEX * lex)3359 bool run_set_statement_if_requested(THD *thd, LEX *lex)
3360 {
3361   if (!lex->stmt_var_list.is_empty() && !thd->slave_thread)
3362   {
3363     Query_arena backup;
3364     DBUG_PRINT("info", ("SET STATEMENT %d vars", lex->stmt_var_list.elements));
3365 
3366     lex->old_var_list.empty();
3367     List_iterator_fast<set_var_base> it(lex->stmt_var_list);
3368     set_var_base *var;
3369 
3370     if (lex->set_arena_for_set_stmt(&backup))
3371       return true;
3372 
3373     MEM_ROOT *mem_root= thd->mem_root;
3374     while ((var= it++))
3375     {
3376       DBUG_ASSERT(var->is_system());
3377       set_var *o= NULL, *v= (set_var*)var;
3378       if (!v->var->is_set_stmt_ok())
3379       {
3380         my_error(ER_SET_STATEMENT_NOT_SUPPORTED, MYF(0), v->var->name.str);
3381         lex->reset_arena_for_set_stmt(&backup);
3382         lex->old_var_list.empty();
3383         lex->free_arena_for_set_stmt();
3384         return true;
3385       }
3386       if (v->var->session_is_default(thd))
3387         o= new set_var(thd,v->type, v->var, &v->base, NULL);
3388       else
3389       {
3390         switch (v->var->option.var_type & GET_TYPE_MASK)
3391         {
3392           case GET_BOOL:
3393           case GET_INT:
3394           case GET_LONG:
3395           case GET_LL:
3396           {
3397             bool null_value;
3398             longlong val= v->var->val_int(&null_value, thd, v->type, &v->base);
3399             o= new set_var(thd, v->type, v->var, &v->base,
3400                            (null_value ?
3401                             (Item *) new (mem_root) Item_null(thd) :
3402                             (Item *) new (mem_root) Item_int(thd, val)));
3403           }
3404           break;
3405           case GET_UINT:
3406           case GET_ULONG:
3407           case GET_ULL:
3408           {
3409             bool null_value;
3410             ulonglong val= v->var->val_int(&null_value, thd, v->type, &v->base);
3411             o= new set_var(thd, v->type, v->var, &v->base,
3412                            (null_value ?
3413                             (Item *) new (mem_root) Item_null(thd) :
3414                             (Item *) new (mem_root) Item_uint(thd, val)));
3415           }
3416           break;
3417           case GET_DOUBLE:
3418           {
3419             bool null_value;
3420             double val= v->var->val_real(&null_value, thd, v->type, &v->base);
3421             o= new set_var(thd, v->type, v->var, &v->base,
3422                            (null_value ?
3423                             (Item *) new (mem_root) Item_null(thd) :
3424                             (Item *) new (mem_root) Item_float(thd, val, 1)));
3425           }
3426           break;
3427           default:
3428           case GET_NO_ARG:
3429           case GET_DISABLED:
3430             DBUG_ASSERT(0);
3431             /* fall through */
3432           case 0:
3433           case GET_FLAGSET:
3434           case GET_ENUM:
3435           case GET_SET:
3436           case GET_STR:
3437           case GET_STR_ALLOC:
3438           {
3439             char buff[STRING_BUFFER_USUAL_SIZE];
3440             String tmp(buff, sizeof(buff), v->var->charset(thd)),*val;
3441             val= v->var->val_str(&tmp, thd, v->type, &v->base);
3442             if (val)
3443             {
3444               Item_string *str=
3445 		new (mem_root) Item_string(thd, v->var->charset(thd),
3446                                            val->ptr(), val->length());
3447               o= new set_var(thd, v->type, v->var, &v->base, str);
3448             }
3449             else
3450               o= new set_var(thd, v->type, v->var, &v->base,
3451                              new (mem_root) Item_null(thd));
3452           }
3453           break;
3454         }
3455       }
3456       DBUG_ASSERT(o);
3457       lex->old_var_list.push_back(o, thd->mem_root);
3458     }
3459     lex->reset_arena_for_set_stmt(&backup);
3460 
3461     if (lex->old_var_list.is_empty())
3462       lex->free_arena_for_set_stmt();
3463 
3464     if (thd->is_error() ||
3465         sql_set_variables(thd, &lex->stmt_var_list, false))
3466     {
3467       if (!thd->is_error())
3468         my_error(ER_WRONG_ARGUMENTS, MYF(0), "SET");
3469       lex->restore_set_statement_var();
3470       return true;
3471     }
3472     /*
3473       The value of last_insert_id is remembered in THD to be written to binlog
3474       when it's used *the first time* in the statement. But SET STATEMENT
3475       must read the old value of last_insert_id to be able to restore it at
3476       the end. This should not count at "reading of last_insert_id" and
3477       should not remember last_insert_id for binlog. That is, it should clear
3478       stmt_depends_on_first_successful_insert_id_in_prev_stmt flag.
3479     */
3480     if (!thd->in_sub_stmt)
3481     {
3482       thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
3483     }
3484   }
3485   return false;
3486 }
3487 
3488 
3489 /**
3490   Execute command saved in thd and lex->sql_command.
3491 
3492   @param thd                       Thread handle
3493 
3494   @todo
3495     - Invalidate the table in the query cache if something changed
3496     after unlocking when changes become visible.
3497     TODO: this is workaround. right way will be move invalidating in
3498     the unlock procedure.
3499     - TODO: use check_change_password()
3500 
3501   @retval
3502     FALSE       OK
3503   @retval
3504     TRUE        Error
3505 */
3506 
3507 int
mysql_execute_command(THD * thd)3508 mysql_execute_command(THD *thd)
3509 {
3510   int res= 0;
3511   int  up_result= 0;
3512   LEX  *lex= thd->lex;
3513   /* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */
3514   SELECT_LEX *select_lex= lex->first_select_lex();
3515   /* first table of first SELECT_LEX */
3516   TABLE_LIST *first_table= select_lex->table_list.first;
3517   /* list of all tables in query */
3518   TABLE_LIST *all_tables;
3519   /* most outer SELECT_LEX_UNIT of query */
3520   SELECT_LEX_UNIT *unit= &lex->unit;
3521 #ifdef HAVE_REPLICATION
3522   /* have table map for update for multi-update statement (BUG#37051) */
3523   bool have_table_map_for_update= FALSE;
3524   /* */
3525   Rpl_filter *rpl_filter;
3526 #endif
3527   DBUG_ENTER("mysql_execute_command");
3528 
3529   // check that we correctly marked first table for data insertion
3530   DBUG_ASSERT(!(sql_command_flags[lex->sql_command] & CF_INSERTS_DATA) ||
3531               first_table->for_insert_data);
3532 
3533   if (thd->security_ctx->password_expired &&
3534       lex->sql_command != SQLCOM_SET_OPTION &&
3535       lex->sql_command != SQLCOM_PREPARE &&
3536       lex->sql_command != SQLCOM_EXECUTE &&
3537       lex->sql_command != SQLCOM_DEALLOCATE_PREPARE)
3538   {
3539     my_error(ER_MUST_CHANGE_PASSWORD, MYF(0));
3540     DBUG_RETURN(1);
3541   }
3542 
3543   DBUG_ASSERT(thd->transaction->stmt.is_empty() || thd->in_sub_stmt);
3544   /*
3545     Each statement or replication event which might produce deadlock
3546     should handle transaction rollback on its own. So by the start of
3547     the next statement transaction rollback request should be fulfilled
3548     already.
3549   */
3550   DBUG_ASSERT(! thd->transaction_rollback_request || thd->in_sub_stmt);
3551   /*
3552     In many cases first table of main SELECT_LEX have special meaning =>
3553     check that it is first table in global list and relink it first in
3554     queries_tables list if it is necessary (we need such relinking only
3555     for queries with subqueries in select list, in this case tables of
3556     subqueries will go to global list first)
3557 
3558     all_tables will differ from first_table only if most upper SELECT_LEX
3559     do not contain tables.
3560 
3561     Because of above in place where should be at least one table in most
3562     outer SELECT_LEX we have following check:
3563     DBUG_ASSERT(first_table == all_tables);
3564     DBUG_ASSERT(first_table == all_tables && first_table != 0);
3565   */
3566   lex->first_lists_tables_same();
3567   lex->fix_first_select_number();
3568   /* should be assigned after making first tables same */
3569   all_tables= lex->query_tables;
3570   /* set context for commands which do not use setup_tables */
3571   select_lex->
3572     context.resolve_in_table_list_only(select_lex->
3573                                        table_list.first);
3574 
3575   /*
3576     Remember last commmand executed, so that we can use it in functions called by
3577     dispatch_command()
3578   */
3579   thd->last_sql_command= lex->sql_command;
3580 
3581   /*
3582     Reset warning count for each query that uses tables
3583     A better approach would be to reset this for any commands
3584     that is not a SHOW command or a select that only access local
3585     variables, but for now this is probably good enough.
3586   */
3587   if ((sql_command_flags[lex->sql_command] & CF_DIAGNOSTIC_STMT) != 0)
3588     thd->get_stmt_da()->set_warning_info_read_only(TRUE);
3589   else
3590   {
3591     thd->get_stmt_da()->set_warning_info_read_only(FALSE);
3592     if (all_tables)
3593       thd->get_stmt_da()->opt_clear_warning_info(thd->query_id);
3594   }
3595 
3596 #ifdef HAVE_REPLICATION
3597   if (unlikely(thd->slave_thread))
3598   {
3599     if (lex->sql_command == SQLCOM_DROP_TRIGGER)
3600     {
3601       /*
3602         When dropping a trigger, we need to load its table name
3603         before checking slave filter rules.
3604       */
3605       add_table_for_trigger(thd, thd->lex->spname, 1, &all_tables);
3606 
3607       if (!all_tables)
3608       {
3609         /*
3610           If table name cannot be loaded,
3611           it means the trigger does not exists possibly because
3612           CREATE TRIGGER was previously skipped for this trigger
3613           according to slave filtering rules.
3614           Returning success without producing any errors in this case.
3615         */
3616         if (!thd->lex->create_info.if_exists() &&
3617             !(thd->variables.option_bits & OPTION_IF_EXISTS))
3618           DBUG_RETURN(0);
3619         /*
3620           DROP TRIGGER IF NOT EXISTS will return without an error later
3621           after possibly writing the query to a binlog
3622         */
3623       }
3624       else // force searching in slave.cc:tables_ok()
3625         all_tables->updating= 1;
3626     }
3627 
3628     /*
3629       For fix of BUG#37051, the master stores the table map for update
3630       in the Query_log_event, and the value is assigned to
3631       thd->variables.table_map_for_update before executing the update
3632       query.
3633 
3634       If thd->variables.table_map_for_update is set, then we are
3635       replicating from a new master, we can use this value to apply
3636       filter rules without opening all the tables. However If
3637       thd->variables.table_map_for_update is not set, then we are
3638       replicating from an old master, so we just skip this and
3639       continue with the old method. And of course, the bug would still
3640       exist for old masters.
3641     */
3642     if (lex->sql_command == SQLCOM_UPDATE_MULTI &&
3643         thd->table_map_for_update)
3644     {
3645       have_table_map_for_update= TRUE;
3646       table_map table_map_for_update= thd->table_map_for_update;
3647       uint nr= 0;
3648       TABLE_LIST *table;
3649       for (table=all_tables; table; table=table->next_global, nr++)
3650       {
3651         if (table_map_for_update & ((table_map)1 << nr))
3652           table->updating= TRUE;
3653         else
3654           table->updating= FALSE;
3655       }
3656 
3657       if (all_tables_not_ok(thd, all_tables))
3658       {
3659         /* we warn the slave SQL thread */
3660         my_message(ER_SLAVE_IGNORED_TABLE, ER_THD(thd, ER_SLAVE_IGNORED_TABLE),
3661                    MYF(0));
3662       }
3663     }
3664 
3665     /*
3666       Check if statment should be skipped because of slave filtering
3667       rules
3668 
3669       Exceptions are:
3670       - UPDATE MULTI: For this statement, we want to check the filtering
3671         rules later in the code
3672       - SET: we always execute it (Not that many SET commands exists in
3673         the binary log anyway -- only 4.1 masters write SET statements,
3674 	in 5.0 there are no SET statements in the binary log)
3675       - DROP TEMPORARY TABLE IF EXISTS: we always execute it (otherwise we
3676         have stale files on slave caused by exclusion of one tmp table).
3677     */
3678     if (!(lex->sql_command == SQLCOM_UPDATE_MULTI) &&
3679 	!(lex->sql_command == SQLCOM_SET_OPTION) &&
3680 	!((lex->sql_command == SQLCOM_DROP_TABLE ||
3681            lex->sql_command == SQLCOM_DROP_SEQUENCE) &&
3682           lex->tmp_table() && lex->if_exists()) &&
3683         all_tables_not_ok(thd, all_tables))
3684     {
3685       /* we warn the slave SQL thread */
3686       my_message(ER_SLAVE_IGNORED_TABLE, ER_THD(thd, ER_SLAVE_IGNORED_TABLE),
3687                  MYF(0));
3688       DBUG_RETURN(0);
3689     }
3690     /*
3691        Execute deferred events first
3692     */
3693     if (slave_execute_deferred_events(thd))
3694       DBUG_RETURN(-1);
3695   }
3696   else
3697   {
3698 #endif /* HAVE_REPLICATION */
3699     /*
3700       When option readonly is set deny operations which change non-temporary
3701       tables. Except for the replication thread and the 'super' users.
3702     */
3703     if (deny_updates_if_read_only_option(thd, all_tables))
3704     {
3705       my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
3706       DBUG_RETURN(-1);
3707     }
3708 #ifdef HAVE_REPLICATION
3709   } /* endif unlikely slave */
3710 #endif
3711   Opt_trace_start ots(thd, all_tables, lex->sql_command, &lex->var_list,
3712                       thd->query(), thd->query_length(),
3713                       thd->variables.character_set_client);
3714 
3715   Json_writer_object trace_command(thd);
3716   Json_writer_array trace_command_steps(thd, "steps");
3717 
3718   /* store old value of binlog format */
3719   enum_binlog_format orig_binlog_format,orig_current_stmt_binlog_format;
3720 
3721   thd->get_binlog_format(&orig_binlog_format,
3722                          &orig_current_stmt_binlog_format);
3723 #ifdef WITH_WSREP
3724   if (WSREP(thd))
3725   {
3726     /*
3727       change LOCK TABLE WRITE to transaction
3728     */
3729     if (lex->sql_command== SQLCOM_LOCK_TABLES && wsrep_convert_LOCK_to_trx)
3730     {
3731       for (TABLE_LIST *table= all_tables; table; table= table->next_global)
3732       {
3733 	if (table->lock_type >= TL_WRITE_ALLOW_WRITE)
3734         {
3735 	  lex->sql_command= SQLCOM_BEGIN;
3736 	  thd->wsrep_converted_lock_session= true;
3737 	  break;
3738 	}
3739       }
3740     }
3741     if (lex->sql_command== SQLCOM_UNLOCK_TABLES &&
3742 	thd->wsrep_converted_lock_session)
3743     {
3744       thd->wsrep_converted_lock_session= false;
3745       lex->sql_command= SQLCOM_COMMIT;
3746       lex->tx_release= TVL_NO;
3747     }
3748 
3749     /*
3750      * Bail out if DB snapshot has not been installed. We however,
3751      * allow SET and SHOW queries and reads from information schema
3752      * and dirty reads (if configured)
3753      */
3754     if (!(thd->wsrep_applier) &&
3755         !(wsrep_ready_get() && wsrep_reject_queries == WSREP_REJECT_NONE)  &&
3756         !(thd->variables.wsrep_dirty_reads &&
3757           (sql_command_flags[lex->sql_command] & CF_CHANGES_DATA) == 0)    &&
3758         !wsrep_tables_accessible_when_detached(all_tables)                 &&
3759         lex->sql_command != SQLCOM_SET_OPTION                              &&
3760         !wsrep_is_show_query(lex->sql_command))
3761     {
3762       my_message(ER_UNKNOWN_COM_ERROR,
3763                  "WSREP has not yet prepared node for application use", MYF(0));
3764       goto error;
3765     }
3766   }
3767 #endif /* WITH_WSREP */
3768   status_var_increment(thd->status_var.com_stat[lex->sql_command]);
3769   thd->progress.report_to_client= MY_TEST(sql_command_flags[lex->sql_command] &
3770                                           CF_REPORT_PROGRESS);
3771 
3772   DBUG_ASSERT(thd->transaction->stmt.modified_non_trans_table == FALSE);
3773 
3774   /*
3775     Assign system variables with values specified by the clause
3776     SET STATEMENT var1=value1 [, var2=value2, ...] FOR <statement>
3777     if they are any.
3778   */
3779   if (run_set_statement_if_requested(thd, lex))
3780     goto error;
3781 
3782   if (thd->lex->mi.connection_name.str == NULL)
3783       thd->lex->mi.connection_name= thd->variables.default_master_connection;
3784 
3785   /*
3786     Force statement logging for DDL commands to allow us to update
3787     privilege, system or statistic tables directly without the updates
3788     getting logged.
3789   */
3790   if (!(sql_command_flags[lex->sql_command] &
3791         (CF_CAN_GENERATE_ROW_EVENTS | CF_FORCE_ORIGINAL_BINLOG_FORMAT |
3792          CF_STATUS_COMMAND)))
3793     thd->set_binlog_format_stmt();
3794 
3795   /*
3796     End a active transaction so that this command will have it's
3797     own transaction and will also sync the binary log. If a DDL is
3798     not run in it's own transaction it may simply never appear on
3799     the slave in case the outside transaction rolls back.
3800   */
3801   if (stmt_causes_implicit_commit(thd, CF_IMPLICIT_COMMIT_BEGIN))
3802   {
3803     /*
3804       Note that this should never happen inside of stored functions
3805       or triggers as all such statements prohibited there.
3806     */
3807     DBUG_ASSERT(! thd->in_sub_stmt);
3808     /* Statement transaction still should not be started. */
3809     DBUG_ASSERT(thd->transaction->stmt.is_empty());
3810     if (!(thd->variables.option_bits & OPTION_GTID_BEGIN))
3811     {
3812       /* Commit the normal transaction if one is active. */
3813       bool commit_failed= trans_commit_implicit(thd);
3814       /* Release metadata locks acquired in this transaction. */
3815       thd->release_transactional_locks();
3816       if (commit_failed)
3817       {
3818         WSREP_DEBUG("implicit commit failed, MDL released: %lld",
3819                     (longlong) thd->thread_id);
3820         goto error;
3821       }
3822     }
3823     thd->transaction->stmt.mark_trans_did_ddl();
3824 #ifdef WITH_WSREP
3825     /* Clean up the previous transaction on implicit commit */
3826     if (WSREP_NNULL(thd) && wsrep_thd_is_local(thd) &&
3827         wsrep_after_statement(thd))
3828     {
3829       goto error;
3830     }
3831 #endif /* WITH_WSREP */
3832   }
3833 
3834 #ifndef DBUG_OFF
3835   if (lex->sql_command != SQLCOM_SET_OPTION)
3836     DEBUG_SYNC(thd,"before_execute_sql_command");
3837 #endif
3838 
3839   /*
3840     Check if we are in a read-only transaction and we're trying to
3841     execute a statement which should always be disallowed in such cases.
3842 
3843     Note that this check is done after any implicit commits.
3844   */
3845   if (thd->tx_read_only &&
3846       (sql_command_flags[lex->sql_command] & CF_DISALLOW_IN_RO_TRANS))
3847   {
3848     my_error(ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION, MYF(0));
3849     goto error;
3850   }
3851 
3852   /*
3853     Close tables open by HANDLERs before executing DDL statement
3854     which is going to affect those tables.
3855 
3856     This should happen before temporary tables are pre-opened as
3857     otherwise we will get errors about attempt to re-open tables
3858     if table to be changed is open through HANDLER.
3859 
3860     Note that even although this is done before any privilege
3861     checks there is no security problem here as closing open
3862     HANDLER doesn't require any privileges anyway.
3863   */
3864   if (sql_command_flags[lex->sql_command] & CF_HA_CLOSE)
3865     mysql_ha_rm_tables(thd, all_tables);
3866 
3867   /*
3868     Pre-open temporary tables to simplify privilege checking
3869     for statements which need this.
3870   */
3871   if (sql_command_flags[lex->sql_command] & CF_PREOPEN_TMP_TABLES)
3872   {
3873     if (thd->open_temporary_tables(all_tables))
3874       goto error;
3875   }
3876 
3877   if (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND)
3878     thd->query_plan_flags|= QPLAN_STATUS;
3879   if (sql_command_flags[lex->sql_command] & CF_ADMIN_COMMAND)
3880     thd->query_plan_flags|= QPLAN_ADMIN;
3881 
3882   /* Start timeouts */
3883   thd->set_query_timer();
3884 
3885 #ifdef WITH_WSREP
3886   /*
3887     Always start a new transaction for a wsrep THD unless the
3888     current command is DDL or explicit BEGIN. This will guarantee that
3889     the THD is BF abortable even if it does not generate any
3890     changes and takes only read locks. If the statement does not
3891     start a multi STMT transaction, the wsrep_transaction is
3892     committed as empty at the end of this function.
3893 
3894     Transaction is started for BEGIN in trans_begin(), for DDL the
3895     implicit commit took care of committing previous transaction
3896     above and a new transaction should not be started.
3897 
3898     Do not start transaction for stored procedures, it will be handled
3899     internally in SP processing.
3900   */
3901   if (WSREP_NNULL(thd)                    &&
3902       wsrep_thd_is_local(thd)             &&
3903       lex->sql_command != SQLCOM_BEGIN    &&
3904       lex->sql_command != SQLCOM_CALL     &&
3905       lex->sql_command != SQLCOM_EXECUTE  &&
3906       lex->sql_command != SQLCOM_EXECUTE_IMMEDIATE &&
3907       !(sql_command_flags[lex->sql_command] & CF_AUTO_COMMIT_TRANS))
3908   {
3909     wsrep_start_trx_if_not_started(thd);
3910   }
3911 #endif /* WITH_WSREP */
3912 
3913   switch (lex->sql_command) {
3914 
3915   case SQLCOM_SHOW_EVENTS:
3916 #ifndef HAVE_EVENT_SCHEDULER
3917     my_error(ER_NOT_SUPPORTED_YET, MYF(0), "embedded server");
3918     break;
3919 #endif
3920   case SQLCOM_SHOW_STATUS:
3921   {
3922     WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW);
3923     execute_show_status(thd, all_tables);
3924 
3925     break;
3926   }
3927   case SQLCOM_SHOW_EXPLAIN:
3928   {
3929     if (!thd->security_ctx->priv_user[0] &&
3930         check_global_access(thd, PRIV_STMT_SHOW_EXPLAIN))
3931       break;
3932 
3933     /*
3934       The select should use only one table, it's the SHOW EXPLAIN pseudo-table
3935     */
3936     if (lex->sroutines.records || lex->query_tables->next_global)
3937     {
3938       my_message(ER_SET_CONSTANTS_ONLY, ER_THD(thd, ER_SET_CONSTANTS_ONLY),
3939 		 MYF(0));
3940       goto error;
3941     }
3942 
3943     Item **it= lex->value_list.head_ref();
3944     if (!(*it)->basic_const_item() ||
3945         (*it)->fix_fields_if_needed_for_scalar(lex->thd, it))
3946     {
3947       my_message(ER_SET_CONSTANTS_ONLY, ER_THD(thd, ER_SET_CONSTANTS_ONLY),
3948 		 MYF(0));
3949       goto error;
3950     }
3951   }
3952     /* fall through */
3953   case SQLCOM_SHOW_STATUS_PROC:
3954   case SQLCOM_SHOW_STATUS_FUNC:
3955   case SQLCOM_SHOW_STATUS_PACKAGE:
3956   case SQLCOM_SHOW_STATUS_PACKAGE_BODY:
3957   case SQLCOM_SHOW_DATABASES:
3958   case SQLCOM_SHOW_TABLES:
3959   case SQLCOM_SHOW_TRIGGERS:
3960   case SQLCOM_SHOW_TABLE_STATUS:
3961   case SQLCOM_SHOW_OPEN_TABLES:
3962   case SQLCOM_SHOW_GENERIC:
3963   case SQLCOM_SHOW_PLUGINS:
3964   case SQLCOM_SHOW_FIELDS:
3965   case SQLCOM_SHOW_KEYS:
3966   case SQLCOM_SHOW_VARIABLES:
3967   case SQLCOM_SHOW_CHARSETS:
3968   case SQLCOM_SHOW_COLLATIONS:
3969   case SQLCOM_SHOW_STORAGE_ENGINES:
3970   case SQLCOM_SHOW_PROFILE:
3971   case SQLCOM_SELECT:
3972   {
3973 #ifdef WITH_WSREP
3974     if (lex->sql_command == SQLCOM_SELECT)
3975     {
3976       WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_READ);
3977     }
3978     else
3979     {
3980       WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW);
3981 # ifdef ENABLED_PROFILING
3982       if (lex->sql_command == SQLCOM_SHOW_PROFILE)
3983         thd->profiling.discard_current_query();
3984 # endif
3985     }
3986 #endif /* WITH_WSREP */
3987 
3988     thd->status_var.last_query_cost= 0.0;
3989 
3990     /*
3991       lex->exchange != NULL implies SELECT .. INTO OUTFILE and this
3992       requires FILE_ACL access.
3993     */
3994     privilege_t privileges_requested= lex->exchange ? SELECT_ACL | FILE_ACL :
3995                                                       SELECT_ACL;
3996 
3997     if (all_tables)
3998       res= check_table_access(thd,
3999                               privileges_requested,
4000                               all_tables, FALSE, UINT_MAX, FALSE);
4001     else
4002       res= check_access(thd, privileges_requested, any_db, NULL, NULL, 0, 0);
4003 
4004     if (!res)
4005       res= execute_sqlcom_select(thd, all_tables);
4006 
4007     break;
4008   }
4009   case SQLCOM_EXECUTE_IMMEDIATE:
4010   {
4011     mysql_sql_stmt_execute_immediate(thd);
4012     break;
4013   }
4014   case SQLCOM_PREPARE:
4015   {
4016     mysql_sql_stmt_prepare(thd);
4017     break;
4018   }
4019   case SQLCOM_EXECUTE:
4020   {
4021     mysql_sql_stmt_execute(thd);
4022     break;
4023   }
4024   case SQLCOM_DEALLOCATE_PREPARE:
4025   {
4026     mysql_sql_stmt_close(thd);
4027     break;
4028   }
4029   case SQLCOM_DO:
4030     if (check_table_access(thd, SELECT_ACL, all_tables, FALSE, UINT_MAX, FALSE)
4031         || open_and_lock_tables(thd, all_tables, TRUE, 0))
4032       goto error;
4033 
4034     res= mysql_do(thd, *lex->insert_list);
4035     break;
4036 
4037   case SQLCOM_EMPTY_QUERY:
4038     my_ok(thd);
4039     break;
4040 
4041   case SQLCOM_HELP:
4042     res= mysqld_help(thd,lex->help_arg);
4043     break;
4044 
4045 #ifndef EMBEDDED_LIBRARY
4046   case SQLCOM_PURGE:
4047   {
4048     if (check_global_access(thd, PRIV_STMT_PURGE_BINLOG))
4049       goto error;
4050     /* PURGE MASTER LOGS TO 'file' */
4051     res = purge_master_logs(thd, lex->to_log);
4052     break;
4053   }
4054   case SQLCOM_PURGE_BEFORE:
4055   {
4056     Item *it;
4057 
4058     if (check_global_access(thd, PRIV_STMT_PURGE_BINLOG))
4059       goto error;
4060     /* PURGE MASTER LOGS BEFORE 'data' */
4061     it= (Item *)lex->value_list.head();
4062     if (it->fix_fields_if_needed_for_scalar(lex->thd, &it))
4063     {
4064       my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE LOGS BEFORE");
4065       goto error;
4066     }
4067     it= new (thd->mem_root) Item_func_unix_timestamp(thd, it);
4068     it->fix_fields(thd, &it);
4069     res = purge_master_logs_before_date(thd, (ulong)it->val_int());
4070     break;
4071   }
4072 #endif
4073   case SQLCOM_SHOW_WARNS:
4074   {
4075     res= mysqld_show_warnings(thd, (ulong)
4076 			      ((1L << (uint) Sql_condition::WARN_LEVEL_NOTE) |
4077 			       (1L << (uint) Sql_condition::WARN_LEVEL_WARN) |
4078 			       (1L << (uint) Sql_condition::WARN_LEVEL_ERROR)
4079 			       ));
4080     break;
4081   }
4082   case SQLCOM_SHOW_ERRORS:
4083   {
4084     res= mysqld_show_warnings(thd, (ulong)
4085 			      (1L << (uint) Sql_condition::WARN_LEVEL_ERROR));
4086     break;
4087   }
4088   case SQLCOM_SHOW_PROFILES:
4089   {
4090 #if defined(ENABLED_PROFILING)
4091     thd->profiling.discard_current_query();
4092     res= thd->profiling.show_profiles();
4093     if (res)
4094       goto error;
4095 #else
4096     my_error(ER_FEATURE_DISABLED, MYF(0), "SHOW PROFILES", "enable-profiling");
4097     goto error;
4098 #endif
4099     break;
4100   }
4101 
4102 #ifdef HAVE_REPLICATION
4103   case SQLCOM_SHOW_SLAVE_HOSTS:
4104   {
4105     if (check_global_access(thd, PRIV_STMT_SHOW_SLAVE_HOSTS))
4106       goto error;
4107     res = show_slave_hosts(thd);
4108     break;
4109   }
4110   case SQLCOM_SHOW_RELAYLOG_EVENTS:
4111   {
4112     WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW);
4113     if (check_global_access(thd, PRIV_STMT_SHOW_RELAYLOG_EVENTS))
4114       goto error;
4115     res = mysql_show_binlog_events(thd);
4116     break;
4117   }
4118   case SQLCOM_SHOW_BINLOG_EVENTS:
4119   {
4120     WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW);
4121     if (check_global_access(thd, PRIV_STMT_SHOW_BINLOG_EVENTS))
4122       goto error;
4123     res = mysql_show_binlog_events(thd);
4124     break;
4125   }
4126 #endif
4127 
4128   case SQLCOM_ASSIGN_TO_KEYCACHE:
4129   {
4130     DBUG_ASSERT(first_table == all_tables && first_table != 0);
4131     if (check_access(thd, INDEX_ACL, first_table->db.str,
4132                      &first_table->grant.privilege,
4133                      &first_table->grant.m_internal,
4134                      0, 0))
4135       goto error;
4136     res= mysql_assign_to_keycache(thd, first_table, &lex->ident);
4137     break;
4138   }
4139   case SQLCOM_PRELOAD_KEYS:
4140   {
4141     DBUG_ASSERT(first_table == all_tables && first_table != 0);
4142     if (check_access(thd, INDEX_ACL, first_table->db.str,
4143                      &first_table->grant.privilege,
4144                      &first_table->grant.m_internal,
4145                      0, 0))
4146       goto error;
4147     res = mysql_preload_keys(thd, first_table);
4148     break;
4149   }
4150 #ifdef HAVE_REPLICATION
4151   case SQLCOM_CHANGE_MASTER:
4152   {
4153     LEX_MASTER_INFO *lex_mi= &thd->lex->mi;
4154     Master_info *mi;
4155     bool new_master= 0;
4156     bool master_info_added;
4157 
4158     if (check_global_access(thd, PRIV_STMT_CHANGE_MASTER))
4159       goto error;
4160     /*
4161       In this code it's ok to use LOCK_active_mi as we are adding new things
4162       into master_info_index
4163     */
4164     mysql_mutex_lock(&LOCK_active_mi);
4165     if (!master_info_index)
4166     {
4167       mysql_mutex_unlock(&LOCK_active_mi);
4168       my_error(ER_SERVER_SHUTDOWN, MYF(0));
4169       goto error;
4170     }
4171 
4172     mi= master_info_index->get_master_info(&lex_mi->connection_name,
4173                                            Sql_condition::WARN_LEVEL_NOTE);
4174 
4175     if (mi == NULL)
4176     {
4177       /* New replication created */
4178       mi= new Master_info(&lex_mi->connection_name, relay_log_recovery);
4179       if (unlikely(!mi || mi->error()))
4180       {
4181         delete mi;
4182         res= 1;
4183         mysql_mutex_unlock(&LOCK_active_mi);
4184         break;
4185       }
4186       new_master= 1;
4187     }
4188 
4189     res= change_master(thd, mi, &master_info_added);
4190     if (res && new_master)
4191     {
4192       /*
4193         If the new master was added by change_master(), remove it as it didn't
4194         work (this will free mi as well).
4195 
4196         If new master was not added, we still need to free mi.
4197       */
4198       if (master_info_added)
4199         master_info_index->remove_master_info(mi);
4200       else
4201         delete mi;
4202     }
4203     else
4204     {
4205       mi->rpl_filter= get_or_create_rpl_filter(lex_mi->connection_name.str,
4206                                                lex_mi->connection_name.length);
4207     }
4208 
4209     mysql_mutex_unlock(&LOCK_active_mi);
4210     break;
4211   }
4212 
4213   case SQLCOM_SHOW_BINLOG_STAT:
4214   {
4215     /* Accept one of two privileges */
4216     if (check_global_access(thd, PRIV_STMT_SHOW_BINLOG_STATUS))
4217       goto error;
4218     res = show_binlog_info(thd);
4219     break;
4220   }
4221 
4222 #endif /* HAVE_REPLICATION */
4223   case SQLCOM_SHOW_ENGINE_STATUS:
4224     {
4225       if (check_global_access(thd, PRIV_STMT_SHOW_ENGINE_STATUS))
4226         goto error;
4227       res = ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_STATUS);
4228       break;
4229     }
4230   case SQLCOM_SHOW_ENGINE_MUTEX:
4231     {
4232       if (check_global_access(thd, PRIV_STMT_SHOW_ENGINE_MUTEX))
4233         goto error;
4234       res = ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_MUTEX);
4235       break;
4236     }
4237   case SQLCOM_DROP_INDEX:
4238     if (thd->variables.option_bits & OPTION_IF_EXISTS)
4239       lex->create_info.set(DDL_options_st::OPT_IF_EXISTS);
4240     /* fall through */
4241   case SQLCOM_CREATE_INDEX:
4242   /*
4243     CREATE INDEX and DROP INDEX are implemented by calling ALTER
4244     TABLE with proper arguments.
4245 
4246     In the future ALTER TABLE will notice that the request is to
4247     only add indexes and create these one by one for the existing
4248     table without having to do a full rebuild.
4249   */
4250   {
4251     /* Prepare stack copies to be re-execution safe */
4252     HA_CREATE_INFO create_info;
4253     Alter_info alter_info(lex->alter_info, thd->mem_root);
4254 
4255     if (unlikely(thd->is_fatal_error)) /* out of memory creating alter_info */
4256       goto error;
4257 
4258     DBUG_ASSERT(first_table == all_tables && first_table != 0);
4259     if (check_one_table_access(thd, INDEX_ACL, all_tables))
4260       goto error; /* purecov: inspected */
4261 
4262     bzero((char*) &create_info, sizeof(create_info));
4263     create_info.db_type= 0;
4264     create_info.row_type= ROW_TYPE_NOT_USED;
4265     create_info.default_table_charset= thd->variables.collation_database;
4266     create_info.alter_info= &alter_info;
4267 
4268     WSREP_TO_ISOLATION_BEGIN(first_table->db.str, first_table->table_name.str, NULL);
4269 
4270     res= mysql_alter_table(thd, &first_table->db, &first_table->table_name,
4271                            &create_info, first_table, &alter_info,
4272                            0, (ORDER*) 0, 0, lex->if_exists());
4273     break;
4274   }
4275 #ifdef HAVE_REPLICATION
4276   case SQLCOM_SLAVE_START:
4277   {
4278     LEX_MASTER_INFO* lex_mi= &thd->lex->mi;
4279     Master_info *mi;
4280     int load_error;
4281 
4282     load_error= rpl_load_gtid_slave_state(thd);
4283 
4284     /*
4285       We don't need to ensure that only one user is using master_info
4286       as start_slave is protected against simultaneous usage
4287     */
4288     if (unlikely((mi= get_master_info(&lex_mi->connection_name,
4289                                       Sql_condition::WARN_LEVEL_ERROR))))
4290     {
4291       if (load_error)
4292       {
4293         /*
4294           We cannot start a slave using GTID if we cannot load the
4295           GTID position from the mysql.gtid_slave_pos table. But we
4296           can allow non-GTID replication (useful eg. during upgrade).
4297         */
4298         if (mi->using_gtid != Master_info::USE_GTID_NO)
4299         {
4300           mi->release();
4301           break;
4302         }
4303         else
4304           thd->clear_error();
4305       }
4306       if (!start_slave(thd, mi, 1 /* net report*/))
4307         my_ok(thd);
4308       mi->release();
4309     }
4310     break;
4311   }
4312   case SQLCOM_SLAVE_STOP:
4313   {
4314     LEX_MASTER_INFO *lex_mi;
4315     Master_info *mi;
4316     /*
4317       If the client thread has locked tables, a deadlock is possible.
4318       Assume that
4319       - the client thread does LOCK TABLE t READ.
4320       - then the master updates t.
4321       - then the SQL slave thread wants to update t,
4322         so it waits for the client thread because t is locked by it.
4323     - then the client thread does SLAVE STOP.
4324       SLAVE STOP waits for the SQL slave thread to terminate its
4325       update t, which waits for the client thread because t is locked by it.
4326       To prevent that, refuse SLAVE STOP if the
4327       client thread has locked tables
4328     */
4329     if (thd->locked_tables_mode ||
4330         thd->in_active_multi_stmt_transaction() ||
4331         thd->global_read_lock.is_acquired())
4332     {
4333       my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
4334                  ER_THD(thd, ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
4335       goto error;
4336     }
4337 
4338     lex_mi= &thd->lex->mi;
4339     if ((mi= get_master_info(&lex_mi->connection_name,
4340                              Sql_condition::WARN_LEVEL_ERROR)))
4341     {
4342       if (stop_slave(thd, mi, 1/* net report*/))
4343         res= 1;
4344       mi->release();
4345       if (rpl_parallel_resize_pool_if_no_slaves())
4346         res= 1;
4347       if (!res)
4348         my_ok(thd);
4349     }
4350     break;
4351   }
4352   case SQLCOM_SLAVE_ALL_START:
4353   {
4354     mysql_mutex_lock(&LOCK_active_mi);
4355     if (master_info_index && !master_info_index->start_all_slaves(thd))
4356       my_ok(thd);
4357     mysql_mutex_unlock(&LOCK_active_mi);
4358     break;
4359   }
4360   case SQLCOM_SLAVE_ALL_STOP:
4361   {
4362     if (thd->locked_tables_mode ||
4363         thd->in_active_multi_stmt_transaction() ||
4364         thd->global_read_lock.is_acquired())
4365     {
4366       my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
4367                  ER_THD(thd, ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
4368       goto error;
4369     }
4370     mysql_mutex_lock(&LOCK_active_mi);
4371     if (master_info_index && !master_info_index->stop_all_slaves(thd))
4372       my_ok(thd);
4373     mysql_mutex_unlock(&LOCK_active_mi);
4374     break;
4375   }
4376 #endif /* HAVE_REPLICATION */
4377   case SQLCOM_RENAME_TABLE:
4378   {
4379     if (check_rename_table(thd, first_table, all_tables))
4380       goto error;
4381 
4382     WSREP_TO_ISOLATION_BEGIN(0, 0, first_table);
4383 
4384     if (thd->variables.option_bits & OPTION_IF_EXISTS)
4385       lex->create_info.set(DDL_options_st::OPT_IF_EXISTS);
4386 
4387     if (mysql_rename_tables(thd, first_table, 0, lex->if_exists()))
4388       goto error;
4389     break;
4390   }
4391 #ifndef EMBEDDED_LIBRARY
4392   case SQLCOM_SHOW_BINLOGS:
4393 #ifdef DONT_ALLOW_SHOW_COMMANDS
4394     my_message(ER_NOT_ALLOWED_COMMAND, ER_THD(thd, ER_NOT_ALLOWED_COMMAND),
4395                MYF(0)); /* purecov: inspected */
4396     goto error;
4397 #else
4398     {
4399       if (check_global_access(thd, PRIV_STMT_SHOW_BINARY_LOGS))
4400 	goto error;
4401       WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW);
4402       res = show_binlogs(thd);
4403       break;
4404     }
4405 #endif
4406 #endif /* EMBEDDED_LIBRARY */
4407   case SQLCOM_SHOW_CREATE:
4408   {
4409      DBUG_ASSERT(first_table == all_tables && first_table != 0);
4410 #ifdef DONT_ALLOW_SHOW_COMMANDS
4411     my_message(ER_NOT_ALLOWED_COMMAND, ER_THD(thd, ER_NOT_ALLOWED_COMMAND),
4412                MYF(0)); /* purecov: inspected */
4413     goto error;
4414 #else
4415       WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW);
4416 
4417      /*
4418         Access check:
4419         SHOW CREATE TABLE require any privileges on the table level (ie
4420         effecting all columns in the table).
4421         SHOW CREATE VIEW require the SHOW_VIEW and SELECT ACLs on the table
4422         level.
4423         NOTE: SHOW_VIEW ACL is checked when the view is created.
4424       */
4425 
4426       DBUG_PRINT("debug", ("lex->only_view: %d, table: %s.%s",
4427                            lex->table_type == TABLE_TYPE_VIEW,
4428                            first_table->db.str, first_table->table_name.str));
4429       res= mysqld_show_create(thd, first_table);
4430       break;
4431 #endif
4432   }
4433   case SQLCOM_CHECKSUM:
4434   {
4435     DBUG_ASSERT(first_table == all_tables && first_table != 0);
4436     WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_READ);
4437 
4438     if (check_table_access(thd, SELECT_ACL, all_tables,
4439                            FALSE, UINT_MAX, FALSE))
4440       goto error; /* purecov: inspected */
4441 
4442     res = mysql_checksum_table(thd, first_table, &lex->check_opt);
4443     break;
4444   }
4445   case SQLCOM_UPDATE:
4446   {
4447     WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_UPDATE_DELETE);
4448     ha_rows found= 0, updated= 0;
4449     DBUG_ASSERT(first_table == all_tables && first_table != 0);
4450     WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_UPDATE_DELETE);
4451 
4452     if (update_precheck(thd, all_tables))
4453       break;
4454 
4455     /*
4456       UPDATE IGNORE can be unsafe. We therefore use row based
4457       logging if mixed or row based logging is available.
4458       TODO: Check if the order of the output of the select statement is
4459       deterministic. Waiting for BUG#42415
4460     */
4461     if (lex->ignore)
4462       lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_UPDATE_IGNORE);
4463 
4464     DBUG_ASSERT(select_lex->offset_limit == 0);
4465     unit->set_limit(select_lex);
4466     MYSQL_UPDATE_START(thd->query());
4467     res= up_result= mysql_update(thd, all_tables,
4468                                   select_lex->item_list,
4469                                   lex->value_list,
4470                                   select_lex->where,
4471                                   select_lex->order_list.elements,
4472                                   select_lex->order_list.first,
4473                                   unit->lim.get_select_limit(),
4474                                   lex->ignore, &found, &updated);
4475     MYSQL_UPDATE_DONE(res, found, updated);
4476     /* mysql_update return 2 if we need to switch to multi-update */
4477     if (up_result != 2)
4478       break;
4479     if (thd->lex->period_conditions.is_set())
4480     {
4481       DBUG_ASSERT(0); // Should never happen
4482       goto error;
4483     }
4484   }
4485   /* fall through */
4486   case SQLCOM_UPDATE_MULTI:
4487   {
4488     DBUG_ASSERT(first_table == all_tables && first_table != 0);
4489     /* if we switched from normal update, rights are checked */
4490     if (up_result != 2)
4491     {
4492       WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_UPDATE_DELETE);
4493       if ((res= multi_update_precheck(thd, all_tables)))
4494         break;
4495     }
4496     else
4497       res= 0;
4498 
4499     unit->set_limit(select_lex);
4500     /*
4501       We can not use mysql_explain_union() because of parameters of
4502       mysql_select in mysql_multi_update so just set the option if needed
4503     */
4504     if (thd->lex->describe)
4505     {
4506       select_lex->set_explain_type(FALSE);
4507       select_lex->options|= SELECT_DESCRIBE;
4508     }
4509 
4510     res= mysql_multi_update_prepare(thd);
4511 
4512 #ifdef HAVE_REPLICATION
4513     /* Check slave filtering rules */
4514     if (unlikely(thd->slave_thread && !have_table_map_for_update))
4515     {
4516       if (all_tables_not_ok(thd, all_tables))
4517       {
4518         if (res!= 0)
4519         {
4520           res= 0;             /* don't care of prev failure  */
4521           thd->clear_error(); /* filters are of highest prior */
4522         }
4523         /* we warn the slave SQL thread */
4524         my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
4525         break;
4526       }
4527       if (res)
4528         break;
4529     }
4530     else
4531     {
4532 #endif /* HAVE_REPLICATION */
4533       if (res)
4534         break;
4535       if (opt_readonly &&
4536 	  !(thd->security_ctx->master_access & PRIV_IGNORE_READ_ONLY) &&
4537 	  some_non_temp_table_to_be_updated(thd, all_tables))
4538       {
4539 	my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
4540 	break;
4541       }
4542 #ifdef HAVE_REPLICATION
4543     }  /* unlikely */
4544 #endif
4545     {
4546       multi_update *result_obj;
4547       MYSQL_MULTI_UPDATE_START(thd->query());
4548       res= mysql_multi_update(thd, all_tables,
4549                               &select_lex->item_list,
4550                               &lex->value_list,
4551                               select_lex->where,
4552                               select_lex->options,
4553                               lex->duplicates,
4554                               lex->ignore,
4555                               unit,
4556                               select_lex,
4557                               &result_obj);
4558       if (result_obj)
4559       {
4560         MYSQL_MULTI_UPDATE_DONE(res, result_obj->num_found(),
4561                                 result_obj->num_updated());
4562         res= FALSE; /* Ignore errors here */
4563         delete result_obj;
4564       }
4565       else
4566       {
4567         MYSQL_MULTI_UPDATE_DONE(1, 0, 0);
4568       }
4569     }
4570     break;
4571   }
4572   case SQLCOM_REPLACE:
4573     if ((res= generate_incident_event(thd)))
4574       break;
4575     /* fall through */
4576   case SQLCOM_INSERT:
4577   {
4578     WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_INSERT_REPLACE);
4579     select_result *sel_result= NULL;
4580     DBUG_ASSERT(first_table == all_tables && first_table != 0);
4581 
4582     WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_INSERT_REPLACE);
4583 
4584     /*
4585       Since INSERT DELAYED doesn't support temporary tables, we could
4586       not pre-open temporary tables for SQLCOM_INSERT / SQLCOM_REPLACE.
4587       Open them here instead.
4588     */
4589     if (first_table->lock_type != TL_WRITE_DELAYED)
4590     {
4591       res= (thd->open_temporary_tables(all_tables)) ? TRUE : FALSE;
4592       if (res)
4593         break;
4594     }
4595 
4596     if ((res= insert_precheck(thd, all_tables)))
4597       break;
4598 
4599     MYSQL_INSERT_START(thd->query());
4600     Protocol* save_protocol=NULL;
4601 
4602     if (lex->has_returning())
4603     {
4604       status_var_increment(thd->status_var.feature_insert_returning);
4605 
4606       /* This is INSERT ... RETURNING. It will return output to the client */
4607       if (thd->lex->analyze_stmt)
4608       {
4609         /*
4610           Actually, it is ANALYZE .. INSERT .. RETURNING. We need to produce
4611           output and then discard it.
4612         */
4613         sel_result= new (thd->mem_root) select_send_analyze(thd);
4614         save_protocol= thd->protocol;
4615         thd->protocol= new Protocol_discard(thd);
4616       }
4617       else
4618       {
4619         if (!(sel_result= new (thd->mem_root) select_send(thd)))
4620           goto error;
4621       }
4622     }
4623 
4624     res= mysql_insert(thd, all_tables, lex->field_list, lex->many_values,
4625                       lex->update_list, lex->value_list,
4626                       lex->duplicates, lex->ignore, sel_result);
4627     if (save_protocol)
4628     {
4629       delete thd->protocol;
4630       thd->protocol= save_protocol;
4631     }
4632     if (!res && thd->lex->analyze_stmt)
4633       res= thd->lex->explain->send_explain(thd);
4634     delete sel_result;
4635     MYSQL_INSERT_DONE(res, (ulong) thd->get_row_count_func());
4636     /*
4637       If we have inserted into a VIEW, and the base table has
4638       AUTO_INCREMENT column, but this column is not accessible through
4639       a view, then we should restore LAST_INSERT_ID to the value it
4640       had before the statement.
4641     */
4642     if (first_table->view && !first_table->contain_auto_increment)
4643       thd->first_successful_insert_id_in_cur_stmt=
4644         thd->first_successful_insert_id_in_prev_stmt;
4645 
4646 #ifdef ENABLED_DEBUG_SYNC
4647     DBUG_EXECUTE_IF("after_mysql_insert",
4648                     {
4649                       const char act1[]= "now wait_for signal.continue";
4650                       const char act2[]= "now signal signal.continued";
4651                       DBUG_ASSERT(debug_sync_service);
4652                       DBUG_ASSERT(!debug_sync_set_action(thd,
4653                                                          STRING_WITH_LEN(act1)));
4654                       DBUG_ASSERT(!debug_sync_set_action(thd,
4655                                                          STRING_WITH_LEN(act2)));
4656                     };);
4657     DEBUG_SYNC(thd, "after_mysql_insert");
4658 #endif
4659     break;
4660   }
4661   case SQLCOM_REPLACE_SELECT:
4662   case SQLCOM_INSERT_SELECT:
4663   {
4664     WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_INSERT_REPLACE);
4665     select_insert *sel_result;
4666     select_result *result= NULL;
4667     bool explain= MY_TEST(lex->describe);
4668     DBUG_ASSERT(first_table == all_tables && first_table != 0);
4669     WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_UPDATE_DELETE);
4670 
4671     if ((res= insert_precheck(thd, all_tables)))
4672       break;
4673 #ifdef WITH_WSREP
4674     if (WSREP(thd) && thd->wsrep_consistency_check == CONSISTENCY_CHECK_DECLARED)
4675     {
4676       thd->wsrep_consistency_check = CONSISTENCY_CHECK_RUNNING;
4677       WSREP_TO_ISOLATION_BEGIN(first_table->db.str, first_table->table_name.str, NULL);
4678     }
4679 #endif /* WITH_WSREP */
4680 
4681     /*
4682       INSERT...SELECT...ON DUPLICATE KEY UPDATE/REPLACE SELECT/
4683       INSERT...IGNORE...SELECT can be unsafe, unless ORDER BY PRIMARY KEY
4684       clause is used in SELECT statement. We therefore use row based
4685       logging if mixed or row based logging is available.
4686       TODO: Check if the order of the output of the select statement is
4687       deterministic. Waiting for BUG#42415
4688     */
4689     if (lex->sql_command == SQLCOM_INSERT_SELECT &&
4690         lex->duplicates == DUP_UPDATE)
4691       lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_INSERT_SELECT_UPDATE);
4692 
4693     if (lex->sql_command == SQLCOM_INSERT_SELECT && lex->ignore)
4694       lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_INSERT_IGNORE_SELECT);
4695 
4696     if (lex->sql_command == SQLCOM_REPLACE_SELECT)
4697       lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_REPLACE_SELECT);
4698 
4699     /* Fix lock for first table */
4700     if (first_table->lock_type == TL_WRITE_DELAYED)
4701       first_table->lock_type= TL_WRITE;
4702 
4703     /* Don't unlock tables until command is written to binary log */
4704     select_lex->options|= SELECT_NO_UNLOCK;
4705 
4706     unit->set_limit(select_lex);
4707 
4708     if (!(res=open_and_lock_tables(thd, all_tables, TRUE, 0)))
4709     {
4710       MYSQL_INSERT_SELECT_START(thd->query());
4711       /*
4712         Only the INSERT table should be merged. Other will be handled by
4713         select.
4714       */
4715 
4716       Protocol* save_protocol=NULL;
4717 
4718       if (lex->has_returning())
4719       {
4720         status_var_increment(thd->status_var.feature_insert_returning);
4721 
4722         /* This is INSERT ... RETURNING. It will return output to the client */
4723         if (thd->lex->analyze_stmt)
4724         {
4725           /*
4726             Actually, it is ANALYZE .. INSERT .. RETURNING. We need to produce
4727             output and then discard it.
4728           */
4729           result= new (thd->mem_root) select_send_analyze(thd);
4730           save_protocol= thd->protocol;
4731           thd->protocol= new Protocol_discard(thd);
4732         }
4733         else
4734         {
4735           if (!(result= new (thd->mem_root) select_send(thd)))
4736             goto error;
4737         }
4738       }
4739 
4740       /* Skip first table, which is the table we are inserting in */
4741       TABLE_LIST *second_table= first_table->next_local;
4742       /*
4743         This is a hack: this leaves select_lex->table_list in an inconsistent
4744         state as 'elements' does not contain number of elements in the list.
4745         Moreover, if second_table == NULL then 'next' becomes invalid.
4746         TODO: fix it by removing the front element (restoring of it should
4747         be done properly as well)
4748       */
4749       select_lex->table_list.first= second_table;
4750       select_lex->context.table_list=
4751         select_lex->context.first_name_resolution_table= second_table;
4752       res= mysql_insert_select_prepare(thd, result);
4753       if (!res &&
4754           (sel_result= new (thd->mem_root)
4755                        select_insert(thd, first_table,
4756                                     first_table->table,
4757                                     &lex->field_list,
4758                                     &lex->update_list,
4759                                     &lex->value_list,
4760                                     lex->duplicates,
4761                                     lex->ignore,
4762                                     result)))
4763       {
4764         if (lex->analyze_stmt)
4765           ((select_result_interceptor*)sel_result)->disable_my_ok_calls();
4766 
4767         if (explain)
4768           res= mysql_explain_union(thd, &thd->lex->unit, sel_result);
4769         else
4770           res= handle_select(thd, lex, sel_result, OPTION_SETUP_TABLES_DONE);
4771         /*
4772           Invalidate the table in the query cache if something changed
4773           after unlocking when changes become visible.
4774           TODO: this is workaround. right way will be move invalidating in
4775           the unlock procedure.
4776         */
4777         if (!res && first_table->lock_type ==  TL_WRITE_CONCURRENT_INSERT &&
4778             thd->lock)
4779         {
4780           /* INSERT ... SELECT should invalidate only the very first table */
4781           TABLE_LIST *save_table= first_table->next_local;
4782           first_table->next_local= 0;
4783           query_cache_invalidate3(thd, first_table, 1);
4784           first_table->next_local= save_table;
4785         }
4786         if (explain)
4787         {
4788           /*
4789             sel_result needs to be cleaned up properly.
4790             INSERT... SELECT statement will call either send_eof() or
4791             abort_result_set(). EXPLAIN doesn't call either, so we need
4792             to cleanup manually.
4793           */
4794           sel_result->abort_result_set();
4795         }
4796         delete sel_result;
4797       }
4798       else if (res < 0)
4799       {
4800         /*
4801           Insert should be ignored but we have to log the query in statement
4802           format in the binary log
4803         */
4804         res= thd->binlog_current_query_unfiltered();
4805       }
4806       delete result;
4807       if (save_protocol)
4808       {
4809         delete thd->protocol;
4810         thd->protocol= save_protocol;
4811       }
4812       if (!res && (explain || lex->analyze_stmt))
4813         res= thd->lex->explain->send_explain(thd);
4814 
4815       /* revert changes for SP */
4816       MYSQL_INSERT_SELECT_DONE(res, (ulong) thd->get_row_count_func());
4817       select_lex->table_list.first= first_table;
4818     }
4819     /*
4820       If we have inserted into a VIEW, and the base table has
4821       AUTO_INCREMENT column, but this column is not accessible through
4822       a view, then we should restore LAST_INSERT_ID to the value it
4823       had before the statement.
4824     */
4825     if (first_table->view && !first_table->contain_auto_increment)
4826       thd->first_successful_insert_id_in_cur_stmt=
4827         thd->first_successful_insert_id_in_prev_stmt;
4828 
4829     break;
4830   }
4831   case SQLCOM_DELETE:
4832   {
4833     WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_UPDATE_DELETE);
4834     select_result *sel_result= NULL;
4835     DBUG_ASSERT(first_table == all_tables && first_table != 0);
4836     WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_UPDATE_DELETE);
4837 
4838     if ((res= delete_precheck(thd, all_tables)))
4839       break;
4840     DBUG_ASSERT(select_lex->offset_limit == 0);
4841     unit->set_limit(select_lex);
4842 
4843     MYSQL_DELETE_START(thd->query());
4844     Protocol *save_protocol= NULL;
4845 
4846     if (lex->has_returning())
4847     {
4848       /* This is DELETE ... RETURNING.  It will return output to the client */
4849       if (thd->lex->analyze_stmt)
4850       {
4851         /*
4852           Actually, it is ANALYZE .. DELETE .. RETURNING. We need to produce
4853           output and then discard it.
4854         */
4855         sel_result= new (thd->mem_root) select_send_analyze(thd);
4856         save_protocol= thd->protocol;
4857         thd->protocol= new Protocol_discard(thd);
4858       }
4859       else
4860       {
4861         if (!lex->result && !(sel_result= new (thd->mem_root) select_send(thd)))
4862           goto error;
4863       }
4864     }
4865 
4866     res = mysql_delete(thd, all_tables,
4867                        select_lex->where, &select_lex->order_list,
4868                        unit->lim.get_select_limit(), select_lex->options,
4869                        lex->result ? lex->result : sel_result);
4870 
4871     if (save_protocol)
4872     {
4873       delete thd->protocol;
4874       thd->protocol= save_protocol;
4875     }
4876 
4877     if (thd->lex->analyze_stmt || thd->lex->describe)
4878     {
4879       if (!res)
4880         res= thd->lex->explain->send_explain(thd);
4881     }
4882 
4883     delete sel_result;
4884     MYSQL_DELETE_DONE(res, (ulong) thd->get_row_count_func());
4885     break;
4886   }
4887   case SQLCOM_DELETE_MULTI:
4888   {
4889     WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_UPDATE_DELETE);
4890     DBUG_ASSERT(first_table == all_tables && first_table != 0);
4891     TABLE_LIST *aux_tables= thd->lex->auxiliary_table_list.first;
4892     multi_delete *result;
4893     WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_UPDATE_DELETE);
4894 
4895     if ((res= multi_delete_precheck(thd, all_tables)))
4896       break;
4897 
4898     /* condition will be TRUE on SP re-excuting */
4899     if (select_lex->item_list.elements != 0)
4900       select_lex->item_list.empty();
4901     if (add_item_to_list(thd, new (thd->mem_root) Item_null(thd)))
4902       goto error;
4903 
4904     THD_STAGE_INFO(thd, stage_init);
4905     if ((res= open_and_lock_tables(thd, all_tables, TRUE, 0)))
4906       break;
4907 
4908     MYSQL_MULTI_DELETE_START(thd->query());
4909     if (unlikely(res= mysql_multi_delete_prepare(thd)))
4910     {
4911       MYSQL_MULTI_DELETE_DONE(1, 0);
4912       goto error;
4913     }
4914 
4915     if (likely(!thd->is_fatal_error))
4916     {
4917       result= new (thd->mem_root) multi_delete(thd, aux_tables,
4918                                                lex->table_count);
4919       if (likely(result))
4920       {
4921         if (unlikely(select_lex->vers_setup_conds(thd, aux_tables)))
4922           goto multi_delete_error;
4923         res= mysql_select(thd,
4924                           select_lex->get_table_list(),
4925                           select_lex->item_list,
4926                           select_lex->where,
4927                           0, (ORDER *)NULL, (ORDER *)NULL, (Item *)NULL,
4928                           (ORDER *)NULL,
4929                           (select_lex->options | thd->variables.option_bits |
4930                           SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
4931                           OPTION_SETUP_TABLES_DONE) & ~OPTION_BUFFER_RESULT,
4932                           result, unit, select_lex);
4933         res|= (int)(thd->is_error());
4934 
4935         MYSQL_MULTI_DELETE_DONE(res, result->num_deleted());
4936         if (res)
4937           result->abort_result_set(); /* for both DELETE and EXPLAIN DELETE */
4938         else
4939         {
4940           if (lex->describe || lex->analyze_stmt)
4941             res= thd->lex->explain->send_explain(thd);
4942         }
4943       multi_delete_error:
4944         delete result;
4945       }
4946     }
4947     else
4948     {
4949       res= TRUE;                                // Error
4950       MYSQL_MULTI_DELETE_DONE(1, 0);
4951     }
4952     break;
4953   }
4954   case SQLCOM_DROP_SEQUENCE:
4955   case SQLCOM_DROP_TABLE:
4956   {
4957     int result;
4958     DBUG_ASSERT(first_table == all_tables && first_table != 0);
4959 
4960     thd->open_options|= HA_OPEN_FOR_REPAIR;
4961     result= thd->open_temporary_tables(all_tables);
4962     thd->open_options&= ~HA_OPEN_FOR_REPAIR;
4963     if (result)
4964       goto error;
4965     if (!lex->tmp_table())
4966     {
4967       if (check_table_access(thd, DROP_ACL, all_tables, FALSE, UINT_MAX, FALSE))
4968 	goto error;				/* purecov: inspected */
4969     }
4970     else
4971     {
4972       if (thd->transaction->xid_state.check_has_uncommitted_xa())
4973         goto error;
4974       status_var_decrement(thd->status_var.com_stat[lex->sql_command]);
4975       status_var_increment(thd->status_var.com_drop_tmp_table);
4976 
4977       /* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
4978       thd->variables.option_bits|= OPTION_KEEP_LOG;
4979     }
4980     /*
4981       If we are a slave, we should add IF EXISTS if the query executed
4982       on the master without an error. This will help a slave to
4983       recover from multi-table DROP TABLE that was aborted in the
4984       middle.
4985     */
4986     if ((thd->slave_thread && !thd->slave_expected_error &&
4987          slave_ddl_exec_mode_options == SLAVE_EXEC_MODE_IDEMPOTENT) ||
4988         thd->variables.option_bits & OPTION_IF_EXISTS)
4989       lex->create_info.set(DDL_options_st::OPT_IF_EXISTS);
4990 
4991 #ifdef WITH_WSREP
4992     if (WSREP(thd))
4993     {
4994       for (TABLE_LIST *table= all_tables; table; table= table->next_global)
4995       {
4996         if (!lex->tmp_table() &&
4997            (!thd->is_current_stmt_binlog_format_row() ||
4998 	    !thd->find_temporary_table(table)))
4999         {
5000           WSREP_TO_ISOLATION_BEGIN(NULL, NULL, all_tables);
5001           break;
5002         }
5003       }
5004     }
5005 #endif /* WITH_WSREP */
5006 
5007     /* DDL and binlog write order are protected by metadata locks. */
5008     res= mysql_rm_table(thd, first_table, lex->if_exists(), lex->tmp_table(),
5009                         lex->table_type == TABLE_TYPE_SEQUENCE, 0);
5010 
5011     /*
5012       When dropping temporary tables if @@session_track_state_change is ON
5013       then send the boolean tracker in the OK packet
5014     */
5015     if(!res && (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE))
5016     {
5017       thd->session_tracker.state_change.mark_as_changed(thd);
5018     }
5019     break;
5020   }
5021   case SQLCOM_SHOW_PROCESSLIST:
5022     if (!thd->security_ctx->priv_user[0] &&
5023         check_global_access(thd, PRIV_STMT_SHOW_PROCESSLIST))
5024       break;
5025     mysqld_list_processes(thd,
5026                 (thd->security_ctx->master_access & PRIV_STMT_SHOW_PROCESSLIST ?
5027                  NullS :
5028                  thd->security_ctx->priv_user),
5029                 lex->verbose);
5030     break;
5031   case SQLCOM_SHOW_AUTHORS:
5032     res= mysqld_show_authors(thd);
5033     break;
5034   case SQLCOM_SHOW_CONTRIBUTORS:
5035     res= mysqld_show_contributors(thd);
5036     break;
5037   case SQLCOM_SHOW_PRIVILEGES:
5038     res= mysqld_show_privileges(thd);
5039     break;
5040   case SQLCOM_SHOW_ENGINE_LOGS:
5041 #ifdef DONT_ALLOW_SHOW_COMMANDS
5042     my_message(ER_NOT_ALLOWED_COMMAND, ER_THD(thd, ER_NOT_ALLOWED_COMMAND),
5043                MYF(0));	/* purecov: inspected */
5044     goto error;
5045 #else
5046     {
5047       if (check_access(thd, FILE_ACL, any_db, NULL, NULL, 0, 0))
5048 	goto error;
5049       res= ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_LOGS);
5050       break;
5051     }
5052 #endif
5053   case SQLCOM_CHANGE_DB:
5054   {
5055     if (!mysql_change_db(thd, &select_lex->db, FALSE))
5056       my_ok(thd);
5057 
5058     break;
5059   }
5060 
5061   case SQLCOM_LOAD:
5062   {
5063     DBUG_ASSERT(first_table == all_tables && first_table != 0);
5064     privilege_t privilege= (lex->duplicates == DUP_REPLACE ?
5065                             INSERT_ACL | DELETE_ACL : INSERT_ACL) |
5066                            (lex->local_file ? NO_ACL : FILE_ACL);
5067 
5068     if (lex->local_file)
5069     {
5070       if (!(thd->client_capabilities & CLIENT_LOCAL_FILES) ||
5071           !opt_local_infile)
5072       {
5073         my_message(ER_LOAD_INFILE_CAPABILITY_DISABLED,
5074                    ER_THD(thd, ER_LOAD_INFILE_CAPABILITY_DISABLED), MYF(0));
5075         goto error;
5076       }
5077     }
5078 
5079     if (check_one_table_access(thd, privilege, all_tables))
5080       goto error;
5081 
5082     res= mysql_load(thd, lex->exchange, first_table, lex->field_list,
5083                     lex->update_list, lex->value_list, lex->duplicates,
5084                     lex->ignore, (bool) lex->local_file);
5085     break;
5086   }
5087 
5088   case SQLCOM_SET_OPTION:
5089   {
5090     List<set_var_base> *lex_var_list= &lex->var_list;
5091 
5092     if ((check_table_access(thd, SELECT_ACL, all_tables, FALSE, UINT_MAX, FALSE)
5093          || open_and_lock_tables(thd, all_tables, TRUE, 0)))
5094       goto error;
5095     if (likely(!(res= sql_set_variables(thd, lex_var_list, true))))
5096     {
5097       if (likely(!thd->is_error()))
5098         my_ok(thd);
5099     }
5100     else
5101     {
5102       /*
5103         We encountered some sort of error, but no message was sent.
5104         Send something semi-generic here since we don't know which
5105         assignment in the list caused the error.
5106       */
5107       if (!thd->is_error())
5108         my_error(ER_WRONG_ARGUMENTS,MYF(0),"SET");
5109       goto error;
5110     }
5111 
5112     break;
5113   }
5114 
5115   case SQLCOM_UNLOCK_TABLES:
5116     /*
5117       It is critical for mysqldump --single-transaction --master-data that
5118       UNLOCK TABLES does not implicitely commit a connection which has only
5119       done FLUSH TABLES WITH READ LOCK + BEGIN. If this assumption becomes
5120       false, mysqldump will not work.
5121     */
5122     if (thd->variables.option_bits & OPTION_TABLE_LOCK)
5123     {
5124       res= trans_commit_implicit(thd);
5125       if (thd->locked_tables_list.unlock_locked_tables(thd))
5126         res= 1;
5127       thd->release_transactional_locks();
5128       thd->variables.option_bits&= ~(OPTION_TABLE_LOCK);
5129       thd->reset_binlog_for_next_statement();
5130     }
5131     if (thd->global_read_lock.is_acquired() &&
5132         thd->current_backup_stage == BACKUP_FINISHED)
5133       thd->global_read_lock.unlock_global_read_lock(thd);
5134     if (res)
5135       goto error;
5136     my_ok(thd);
5137     break;
5138   case SQLCOM_LOCK_TABLES:
5139     /* We must end the transaction first, regardless of anything */
5140     res= trans_commit_implicit(thd);
5141     if (thd->locked_tables_list.unlock_locked_tables(thd))
5142       res= 1;
5143     /* Release transactional metadata locks. */
5144     thd->release_transactional_locks();
5145     if (res)
5146       goto error;
5147 
5148 #ifdef WITH_WSREP
5149     /* Clean up the previous transaction on implicit commit. */
5150     if (wsrep_on(thd) && !wsrep_not_committed(thd) && wsrep_after_statement(thd))
5151       goto error;
5152 #endif
5153 
5154     /* We can't have any kind of table locks while backup is active */
5155     if (thd->current_backup_stage != BACKUP_FINISHED)
5156     {
5157       my_error(ER_BACKUP_LOCK_IS_ACTIVE, MYF(0));
5158       goto error;
5159     }
5160 
5161     /* Should not lock tables while BACKUP LOCK is active */
5162     if (thd->mdl_backup_lock)
5163     {
5164       my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
5165       goto error;
5166     }
5167 
5168     /*
5169       Here we have to pre-open temporary tables for LOCK TABLES.
5170 
5171       CF_PREOPEN_TMP_TABLES is not set for this SQL statement simply
5172       because LOCK TABLES calls close_thread_tables() as a first thing
5173       (it's called from unlock_locked_tables() above). So even if
5174       CF_PREOPEN_TMP_TABLES was set and the tables would be pre-opened
5175       in a usual way, they would have been closed.
5176     */
5177     if (thd->open_temporary_tables(all_tables))
5178       goto error;
5179 
5180     if (lock_tables_precheck(thd, all_tables))
5181       goto error;
5182 
5183     thd->variables.option_bits|= OPTION_TABLE_LOCK;
5184 
5185     res= lock_tables_open_and_lock_tables(thd, all_tables);
5186 
5187     if (res)
5188     {
5189       thd->variables.option_bits&= ~(OPTION_TABLE_LOCK);
5190     }
5191     else
5192     {
5193 #ifdef HAVE_QUERY_CACHE
5194       if (thd->variables.query_cache_wlock_invalidate)
5195 	query_cache.invalidate_locked_for_write(thd, first_table);
5196 #endif /*HAVE_QUERY_CACHE*/
5197       my_ok(thd);
5198     }
5199     break;
5200   case SQLCOM_BACKUP:
5201     if (check_global_access(thd, RELOAD_ACL))
5202       goto error;
5203     if (!(res= run_backup_stage(thd, lex->backup_stage)))
5204       my_ok(thd);
5205     break;
5206   case SQLCOM_BACKUP_LOCK:
5207     if (check_global_access(thd, RELOAD_ACL))
5208       goto error;
5209     /* first table is set for lock. For unlock the list is empty */
5210     if (first_table)
5211       res= backup_lock(thd, first_table);
5212     else
5213       backup_unlock(thd);
5214     if (!res)
5215       my_ok(thd);
5216     break;
5217   case SQLCOM_CREATE_DB:
5218   {
5219     if (prepare_db_action(thd, lex->create_info.or_replace() ?
5220                           (CREATE_ACL | DROP_ACL) : CREATE_ACL,
5221                           &lex->name))
5222       break;
5223 
5224     WSREP_TO_ISOLATION_BEGIN(lex->name.str, NULL, NULL);
5225 
5226     res= mysql_create_db(thd, &lex->name,
5227                          lex->create_info, &lex->create_info);
5228     break;
5229   }
5230   case SQLCOM_DROP_DB:
5231   {
5232     if (thd->variables.option_bits & OPTION_IF_EXISTS)
5233       lex->create_info.set(DDL_options_st::OPT_IF_EXISTS);
5234 
5235     if (prepare_db_action(thd, DROP_ACL, &lex->name))
5236       break;
5237 
5238     WSREP_TO_ISOLATION_BEGIN(lex->name.str, NULL, NULL);
5239 
5240     res= mysql_rm_db(thd, &lex->name, lex->if_exists());
5241     break;
5242   }
5243   case SQLCOM_ALTER_DB_UPGRADE:
5244   {
5245     LEX_CSTRING *db= &lex->name;
5246 #ifdef HAVE_REPLICATION
5247     if (thd->slave_thread)
5248     {
5249       rpl_filter= thd->system_thread_info.rpl_sql_info->rpl_filter;
5250       if (!rpl_filter->db_ok(db->str) ||
5251           !rpl_filter->db_ok_with_wild_table(db->str))
5252       {
5253         res= 1;
5254         my_message(ER_SLAVE_IGNORED_TABLE, ER_THD(thd, ER_SLAVE_IGNORED_TABLE), MYF(0));
5255         break;
5256       }
5257     }
5258 #endif
5259     if (check_db_name((LEX_STRING*) db))
5260     {
5261       my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
5262       break;
5263     }
5264     if (check_access(thd, ALTER_ACL, db->str, NULL, NULL, 1, 0) ||
5265         check_access(thd, DROP_ACL, db->str, NULL, NULL, 1, 0) ||
5266         check_access(thd, CREATE_ACL, db->str, NULL, NULL, 1, 0))
5267     {
5268       res= 1;
5269       break;
5270     }
5271 
5272     WSREP_TO_ISOLATION_BEGIN(db->str, NULL, NULL);
5273 
5274     res= mysql_upgrade_db(thd, db);
5275     if (!res)
5276       my_ok(thd);
5277     break;
5278   }
5279   case SQLCOM_ALTER_DB:
5280   {
5281     LEX_CSTRING *db= &lex->name;
5282     if (prepare_db_action(thd, ALTER_ACL, db))
5283       break;
5284 
5285     WSREP_TO_ISOLATION_BEGIN(db->str, NULL, NULL);
5286 
5287     res= mysql_alter_db(thd, db, &lex->create_info);
5288     break;
5289   }
5290   case SQLCOM_SHOW_CREATE_DB:
5291     WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW);
5292     res= show_create_db(thd, lex);
5293     break;
5294   case SQLCOM_CREATE_EVENT:
5295   case SQLCOM_ALTER_EVENT:
5296   #ifdef HAVE_EVENT_SCHEDULER
5297   do
5298   {
5299     DBUG_ASSERT(lex->event_parse_data);
5300     if (lex->table_or_sp_used())
5301     {
5302       my_error(ER_SUBQUERIES_NOT_SUPPORTED, MYF(0), "CREATE/ALTER EVENT");
5303       break;
5304     }
5305 
5306     res= sp_process_definer(thd);
5307     if (res)
5308       break;
5309 
5310     switch (lex->sql_command) {
5311     case SQLCOM_CREATE_EVENT:
5312     {
5313       res= Events::create_event(thd, lex->event_parse_data);
5314       break;
5315     }
5316     case SQLCOM_ALTER_EVENT:
5317       res= Events::update_event(thd, lex->event_parse_data,
5318                                 lex->spname ? &lex->spname->m_db : NULL,
5319                                 lex->spname ? &lex->spname->m_name : NULL);
5320       break;
5321     default:
5322       DBUG_ASSERT(0);
5323     }
5324     DBUG_PRINT("info",("DDL error code=%d", res));
5325     if (!res)
5326       my_ok(thd);
5327 
5328   } while (0);
5329   /* Don't do it, if we are inside a SP */
5330   if (!thd->spcont)
5331   {
5332     sp_head::destroy(lex->sphead);
5333     lex->sphead= NULL;
5334   }
5335   /* lex->unit.cleanup() is called outside, no need to call it here */
5336   break;
5337   case SQLCOM_SHOW_CREATE_EVENT:
5338     WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW);
5339     res= Events::show_create_event(thd, &lex->spname->m_db,
5340                                    &lex->spname->m_name);
5341     break;
5342   case SQLCOM_DROP_EVENT:
5343     if (!(res= Events::drop_event(thd,
5344                                   &lex->spname->m_db, &lex->spname->m_name,
5345                                   lex->if_exists())))
5346       my_ok(thd);
5347     break;
5348 #else
5349     my_error(ER_NOT_SUPPORTED_YET,MYF(0),"embedded server");
5350     break;
5351 #endif
5352   case SQLCOM_CREATE_FUNCTION:                  // UDF function
5353   {
5354     if (check_access(thd, lex->create_info.or_replace() ?
5355                           (INSERT_ACL | DELETE_ACL) : INSERT_ACL,
5356                      "mysql", NULL, NULL, 1, 0))
5357       break;
5358 #ifdef HAVE_DLOPEN
5359     WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
5360 
5361     if (!(res = mysql_create_function(thd, &lex->udf)))
5362       my_ok(thd);
5363 #else
5364     my_error(ER_CANT_OPEN_LIBRARY, MYF(0), lex->udf.dl, 0, "feature disabled");
5365     res= TRUE;
5366 #endif
5367     break;
5368   }
5369 #ifndef NO_EMBEDDED_ACCESS_CHECKS
5370   case SQLCOM_CREATE_USER:
5371   case SQLCOM_CREATE_ROLE:
5372   {
5373     if (check_access(thd, lex->create_info.or_replace() ?
5374                           INSERT_ACL | DELETE_ACL : INSERT_ACL,
5375                      "mysql", NULL, NULL, 1, 1) &&
5376         check_global_access(thd,CREATE_USER_ACL))
5377       break;
5378 
5379     WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
5380 
5381     /* Conditionally writes to binlog */
5382     if (!(res= mysql_create_user(thd, lex->users_list,
5383                                  lex->sql_command == SQLCOM_CREATE_ROLE)))
5384       my_ok(thd);
5385     break;
5386   }
5387   case SQLCOM_DROP_USER:
5388   case SQLCOM_DROP_ROLE:
5389   {
5390     if (check_access(thd, DELETE_ACL, "mysql", NULL, NULL, 1, 1) &&
5391         check_global_access(thd,CREATE_USER_ACL))
5392       break;
5393 
5394     WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
5395 
5396     /* Conditionally writes to binlog */
5397     if (!(res= mysql_drop_user(thd, lex->users_list,
5398                                lex->sql_command == SQLCOM_DROP_ROLE)))
5399       my_ok(thd);
5400     break;
5401   }
5402   case SQLCOM_ALTER_USER:
5403   case SQLCOM_RENAME_USER:
5404   {
5405     if (check_access(thd, UPDATE_ACL, "mysql", NULL, NULL, 1, 1) &&
5406         check_global_access(thd,CREATE_USER_ACL))
5407       break;
5408 
5409     WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
5410 
5411     /* Conditionally writes to binlog */
5412     if (lex->sql_command == SQLCOM_ALTER_USER)
5413       res= mysql_alter_user(thd, lex->users_list);
5414     else
5415       res= mysql_rename_user(thd, lex->users_list);
5416     if (!res)
5417       my_ok(thd);
5418     break;
5419   }
5420   case SQLCOM_REVOKE_ALL:
5421   {
5422     if (check_access(thd, UPDATE_ACL, "mysql", NULL, NULL, 1, 1) &&
5423         check_global_access(thd,CREATE_USER_ACL))
5424       break;
5425 
5426     WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
5427 
5428     /* Conditionally writes to binlog */
5429     if (!(res = mysql_revoke_all(thd, lex->users_list)))
5430       my_ok(thd);
5431     break;
5432   }
5433 
5434   case SQLCOM_REVOKE_ROLE:
5435   case SQLCOM_GRANT_ROLE:
5436   {
5437     WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
5438 
5439     if (!(res= mysql_grant_role(thd, lex->users_list,
5440                                 lex->sql_command != SQLCOM_GRANT_ROLE)))
5441       my_ok(thd);
5442     break;
5443   }
5444 #endif /*!NO_EMBEDDED_ACCESS_CHECKS*/
5445   case SQLCOM_RESET:
5446     /*
5447       RESET commands are never written to the binary log, so we have to
5448       initialize this variable because RESET shares the same code as FLUSH
5449     */
5450     lex->no_write_to_binlog= 1;
5451     /* fall through */
5452   case SQLCOM_FLUSH:
5453   {
5454     int write_to_binlog;
5455     if (check_global_access(thd,RELOAD_ACL))
5456       goto error;
5457 
5458     if (first_table && lex->type & (REFRESH_READ_LOCK|REFRESH_FOR_EXPORT))
5459     {
5460       /* Check table-level privileges. */
5461       if (check_table_access(thd, PRIV_LOCK_TABLES, all_tables,
5462                              FALSE, UINT_MAX, FALSE))
5463         goto error;
5464 
5465       if (flush_tables_with_read_lock(thd, all_tables))
5466         goto error;
5467 
5468       my_ok(thd);
5469       break;
5470     }
5471 
5472 #ifdef WITH_WSREP
5473     if (lex->type & (
5474     REFRESH_GRANT                           |
5475     REFRESH_HOSTS                           |
5476 #ifdef HAVE_OPENSSL
5477     REFRESH_DES_KEY_FILE                    |
5478 #endif
5479     /*
5480       Write all flush log statements except
5481       FLUSH LOGS
5482       FLUSH BINARY LOGS
5483       Check reload_acl_and_cache for why.
5484     */
5485     REFRESH_RELAY_LOG                       |
5486     REFRESH_SLOW_LOG                        |
5487     REFRESH_GENERAL_LOG                     |
5488     REFRESH_ENGINE_LOG                      |
5489     REFRESH_ERROR_LOG                       |
5490 #ifdef HAVE_QUERY_CACHE
5491     REFRESH_QUERY_CACHE_FREE                |
5492 #endif /* HAVE_QUERY_CACHE */
5493     REFRESH_STATUS                          |
5494     REFRESH_USER_RESOURCES))
5495     {
5496       WSREP_TO_ISOLATION_BEGIN_WRTCHK(WSREP_MYSQL_DB, NULL, NULL);
5497     }
5498 #endif /* WITH_WSREP*/
5499 
5500 #ifdef HAVE_REPLICATION
5501     if (lex->type & REFRESH_READ_LOCK)
5502     {
5503       /*
5504         We need to pause any parallel replication slave workers during FLUSH
5505         TABLES WITH READ LOCK. Otherwise we might cause a deadlock, as
5506         worker threads eun run in arbitrary order but need to commit in a
5507         specific given order.
5508       */
5509       if (rpl_pause_for_ftwrl(thd))
5510         goto error;
5511     }
5512 #endif
5513     /*
5514       reload_acl_and_cache() will tell us if we are allowed to write to the
5515       binlog or not.
5516     */
5517     if (!reload_acl_and_cache(thd, lex->type, first_table, &write_to_binlog))
5518     {
5519 #ifdef WITH_WSREP
5520       if ((lex->type & REFRESH_TABLES) && !(lex->type & (REFRESH_FOR_EXPORT|REFRESH_READ_LOCK)))
5521       {
5522         /*
5523           This is done after reload_acl_and_cache is because
5524           LOCK TABLES is not replicated in galera, the upgrade of which
5525           is checked in reload_acl_and_cache.
5526           Hence, done after/if we are able to upgrade locks.
5527         */
5528         if (first_table)
5529         {
5530           WSREP_TO_ISOLATION_BEGIN_WRTCHK(NULL, NULL, first_table);
5531         }
5532         else
5533         {
5534           WSREP_TO_ISOLATION_BEGIN_WRTCHK(WSREP_MYSQL_DB, NULL, NULL);
5535         }
5536       }
5537 #endif /* WITH_WSREP */
5538       /*
5539         We WANT to write and we CAN write.
5540         ! we write after unlocking the table.
5541       */
5542       /*
5543         Presumably, RESET and binlog writing doesn't require synchronization
5544       */
5545 
5546       if (write_to_binlog > 0)  // we should write
5547       {
5548         if (!lex->no_write_to_binlog)
5549           res= write_bin_log(thd, FALSE, thd->query(), thd->query_length());
5550       } else if (write_to_binlog < 0)
5551       {
5552         /*
5553            We should not write, but rather report error because
5554            reload_acl_and_cache binlog interactions failed
5555          */
5556         res= 1;
5557       }
5558 
5559       if (!res)
5560         my_ok(thd);
5561     }
5562     else
5563       res= 1;                                   // reload_acl_and_cache failed
5564 #ifdef HAVE_REPLICATION
5565     if (lex->type & REFRESH_READ_LOCK)
5566       rpl_unpause_after_ftwrl(thd);
5567 #endif
5568 
5569     break;
5570   }
5571   case SQLCOM_KILL:
5572   {
5573     if (lex->table_or_sp_used())
5574     {
5575       my_error(ER_SUBQUERIES_NOT_SUPPORTED, MYF(0), "KILL");
5576       break;
5577     }
5578 
5579     if (lex->kill_type == KILL_TYPE_ID || lex->kill_type == KILL_TYPE_QUERY)
5580     {
5581       Item *it= (Item *)lex->value_list.head();
5582       if (it->fix_fields_if_needed_for_scalar(lex->thd, &it))
5583       {
5584         my_message(ER_SET_CONSTANTS_ONLY, ER_THD(thd, ER_SET_CONSTANTS_ONLY),
5585                    MYF(0));
5586         goto error;
5587       }
5588       sql_kill(thd, it->val_int(), lex->kill_signal, lex->kill_type);
5589     }
5590     else
5591       sql_kill_user(thd, get_current_user(thd, lex->users_list.head()),
5592                     lex->kill_signal);
5593     break;
5594   }
5595   case SQLCOM_SHUTDOWN:
5596 #ifndef EMBEDDED_LIBRARY
5597     DBUG_EXECUTE_IF("crash_shutdown", DBUG_SUICIDE(););
5598     if (check_global_access(thd,SHUTDOWN_ACL))
5599       goto error;
5600     kill_mysql(thd);
5601     my_ok(thd);
5602 #else
5603     my_error(ER_NOT_SUPPORTED_YET, MYF(0), "embedded server");
5604 #endif
5605     break;
5606 
5607 #ifndef NO_EMBEDDED_ACCESS_CHECKS
5608   case SQLCOM_SHOW_CREATE_USER:
5609   {
5610     LEX_USER *grant_user= lex->grant_user;
5611     if (!grant_user)
5612       goto error;
5613 
5614     res = mysql_show_create_user(thd, grant_user);
5615     break;
5616   }
5617   case SQLCOM_SHOW_GRANTS:
5618   {
5619     LEX_USER *grant_user= lex->grant_user;
5620     if (!grant_user)
5621       goto error;
5622 
5623     WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW);
5624     res = mysql_show_grants(thd, grant_user);
5625     break;
5626   }
5627 #endif
5628   case SQLCOM_HA_OPEN:
5629     DBUG_ASSERT(first_table == all_tables && first_table != 0);
5630     if (check_table_access(thd, SELECT_ACL, all_tables, FALSE, UINT_MAX, FALSE))
5631       goto error;
5632     /* Close temporary tables which were pre-opened for privilege checking. */
5633     close_thread_tables(thd);
5634     all_tables->table= NULL;
5635     res= mysql_ha_open(thd, first_table, 0);
5636     break;
5637   case SQLCOM_HA_CLOSE:
5638     DBUG_ASSERT(first_table == all_tables && first_table != 0);
5639     res= mysql_ha_close(thd, first_table);
5640     break;
5641   case SQLCOM_HA_READ:
5642     DBUG_ASSERT(first_table == all_tables && first_table != 0);
5643     /*
5644       There is no need to check for table permissions here, because
5645       if a user has no permissions to read a table, he won't be
5646       able to open it (with SQLCOM_HA_OPEN) in the first place.
5647     */
5648     unit->set_limit(select_lex);
5649 
5650     res= mysql_ha_read(thd, first_table, lex->ha_read_mode, lex->ident.str,
5651                        lex->insert_list, lex->ha_rkey_mode, select_lex->where,
5652                        unit->lim.get_select_limit(),
5653                        unit->lim.get_offset_limit());
5654     break;
5655 
5656   case SQLCOM_BEGIN:
5657     DBUG_PRINT("info", ("Executing SQLCOM_BEGIN  thd: %p", thd));
5658     if (trans_begin(thd, lex->start_transaction_opt))
5659     {
5660       thd->release_transactional_locks();
5661       WSREP_DEBUG("BEGIN failed, MDL released: %lld",
5662                   (longlong) thd->thread_id);
5663       WSREP_DEBUG("stmt_da, sql_errno: %d", (thd->get_stmt_da()->is_error()) ? thd->get_stmt_da()->sql_errno() : 0);
5664       goto error;
5665     }
5666     my_ok(thd);
5667     break;
5668   case SQLCOM_COMMIT:
5669   {
5670     DBUG_ASSERT(thd->lock == NULL ||
5671                 thd->locked_tables_mode == LTM_LOCK_TABLES);
5672     bool tx_chain= (lex->tx_chain == TVL_YES ||
5673                     (thd->variables.completion_type == 1 &&
5674                      lex->tx_chain != TVL_NO));
5675     bool tx_release= (lex->tx_release == TVL_YES ||
5676                       (thd->variables.completion_type == 2 &&
5677                        lex->tx_release != TVL_NO));
5678     bool commit_failed= trans_commit(thd);
5679     thd->release_transactional_locks();
5680     if (commit_failed)
5681     {
5682       WSREP_DEBUG("COMMIT failed, MDL released: %lld",
5683                   (longlong) thd->thread_id);
5684       goto error;
5685     }
5686     /* Begin transaction with the same isolation level. */
5687     if (tx_chain)
5688     {
5689       if (trans_begin(thd))
5690         goto error;
5691     }
5692     else
5693     {
5694       /* Reset the isolation level and access mode if no chaining transaction.*/
5695       trans_reset_one_shot_chistics(thd);
5696     }
5697     /* Disconnect the current client connection. */
5698     if (tx_release)
5699     {
5700       thd->set_killed(KILL_CONNECTION);
5701       thd->print_aborted_warning(3, "RELEASE");
5702     }
5703     my_ok(thd);
5704     break;
5705   }
5706   case SQLCOM_ROLLBACK:
5707   {
5708     DBUG_ASSERT(thd->lock == NULL ||
5709                 thd->locked_tables_mode == LTM_LOCK_TABLES);
5710     bool tx_chain= (lex->tx_chain == TVL_YES ||
5711                     (thd->variables.completion_type == 1 &&
5712                      lex->tx_chain != TVL_NO));
5713     bool tx_release= (lex->tx_release == TVL_YES ||
5714                       (thd->variables.completion_type == 2 &&
5715                        lex->tx_release != TVL_NO));
5716     bool rollback_failed= trans_rollback(thd);
5717     thd->release_transactional_locks();
5718 
5719     if (rollback_failed)
5720     {
5721       WSREP_DEBUG("rollback failed, MDL released: %lld",
5722                   (longlong) thd->thread_id);
5723       goto error;
5724     }
5725     /* Begin transaction with the same isolation level. */
5726     if (tx_chain)
5727     {
5728 #ifdef WITH_WSREP
5729       /* If there are pending changes after rollback we should clear them */
5730       if (wsrep_on(thd) && wsrep_has_changes(thd))
5731         wsrep_after_statement(thd);
5732 #endif
5733       if (trans_begin(thd))
5734         goto error;
5735     }
5736     else
5737     {
5738       /* Reset the isolation level and access mode if no chaining transaction.*/
5739       trans_reset_one_shot_chistics(thd);
5740     }
5741     /* Disconnect the current client connection. */
5742     if (tx_release)
5743       thd->set_killed(KILL_CONNECTION);
5744     my_ok(thd);
5745    break;
5746   }
5747   case SQLCOM_RELEASE_SAVEPOINT:
5748     if (trans_release_savepoint(thd, lex->ident))
5749       goto error;
5750     my_ok(thd);
5751     break;
5752   case SQLCOM_ROLLBACK_TO_SAVEPOINT:
5753     if (trans_rollback_to_savepoint(thd, lex->ident))
5754       goto error;
5755     my_ok(thd);
5756     break;
5757   case SQLCOM_SAVEPOINT:
5758     if (trans_savepoint(thd, lex->ident))
5759       goto error;
5760     my_ok(thd);
5761     break;
5762   case SQLCOM_CREATE_PROCEDURE:
5763   case SQLCOM_CREATE_SPFUNCTION:
5764   case SQLCOM_CREATE_PACKAGE:
5765   case SQLCOM_CREATE_PACKAGE_BODY:
5766   {
5767     if (mysql_create_routine(thd, lex))
5768       goto error;
5769     my_ok(thd);
5770     break; /* break super switch */
5771   } /* end case group bracket */
5772   case SQLCOM_COMPOUND:
5773   {
5774     sp_head *sp= lex->sphead;
5775     DBUG_ASSERT(all_tables == 0);
5776     DBUG_ASSERT(thd->in_sub_stmt == 0);
5777     sp->m_sql_mode= thd->variables.sql_mode;
5778     sp->m_sp_share= MYSQL_GET_SP_SHARE(sp->m_handler->type(),
5779                                        sp->m_db.str, static_cast<uint>(sp->m_db.length),
5780                                        sp->m_name.str, static_cast<uint>(sp->m_name.length));
5781     if (do_execute_sp(thd, lex->sphead))
5782       goto error;
5783     break;
5784   }
5785 
5786   case SQLCOM_ALTER_PROCEDURE:
5787   case SQLCOM_ALTER_FUNCTION:
5788     if (thd->variables.option_bits & OPTION_IF_EXISTS)
5789       lex->create_info.set(DDL_options_st::OPT_IF_EXISTS);
5790     if (alter_routine(thd, lex))
5791       goto error;
5792     break;
5793   case SQLCOM_DROP_PROCEDURE:
5794   case SQLCOM_DROP_FUNCTION:
5795   case SQLCOM_DROP_PACKAGE:
5796   case SQLCOM_DROP_PACKAGE_BODY:
5797     if (thd->variables.option_bits & OPTION_IF_EXISTS)
5798       lex->create_info.set(DDL_options_st::OPT_IF_EXISTS);
5799     if (drop_routine(thd, lex))
5800       goto error;
5801     break;
5802   case SQLCOM_SHOW_CREATE_PROC:
5803   case SQLCOM_SHOW_CREATE_FUNC:
5804   case SQLCOM_SHOW_CREATE_PACKAGE:
5805   case SQLCOM_SHOW_CREATE_PACKAGE_BODY:
5806     {
5807       WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW);
5808       const Sp_handler *sph= Sp_handler::handler(lex->sql_command);
5809       if (sph->sp_show_create_routine(thd, lex->spname))
5810         goto error;
5811       break;
5812     }
5813   case SQLCOM_SHOW_PROC_CODE:
5814   case SQLCOM_SHOW_FUNC_CODE:
5815   case SQLCOM_SHOW_PACKAGE_BODY_CODE:
5816     {
5817 #ifndef DBUG_OFF
5818       Database_qualified_name pkgname(&null_clex_str, &null_clex_str);
5819       sp_head *sp;
5820       const Sp_handler *sph= Sp_handler::handler(lex->sql_command);
5821       WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW);
5822       if (sph->sp_resolve_package_routine(thd, thd->lex->sphead,
5823                                           lex->spname, &sph, &pkgname))
5824         return true;
5825       if (sph->sp_cache_routine(thd, lex->spname, false, &sp))
5826         goto error;
5827       if (!sp || sp->show_routine_code(thd))
5828       {
5829         /* We don't distinguish between errors for now */
5830         my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
5831                  sph->type_str(), lex->spname->m_name.str);
5832         goto error;
5833       }
5834       break;
5835 #else
5836       my_error(ER_FEATURE_DISABLED, MYF(0),
5837                "SHOW PROCEDURE|FUNCTION CODE", "--with-debug");
5838       goto error;
5839 #endif // ifndef DBUG_OFF
5840     }
5841   case SQLCOM_SHOW_CREATE_TRIGGER:
5842     {
5843       if (check_ident_length(&lex->spname->m_name))
5844         goto error;
5845 
5846       WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW);
5847       if (show_create_trigger(thd, lex->spname))
5848         goto error; /* Error has been already logged. */
5849 
5850       break;
5851     }
5852   case SQLCOM_CREATE_VIEW:
5853     {
5854       /*
5855         Note: SQLCOM_CREATE_VIEW also handles 'ALTER VIEW' commands
5856         as specified through the thd->lex->create_view->mode flag.
5857       */
5858       res= mysql_create_view(thd, first_table, thd->lex->create_view->mode);
5859       break;
5860     }
5861   case SQLCOM_DROP_VIEW:
5862     {
5863       if (check_table_access(thd, DROP_ACL, all_tables, FALSE, UINT_MAX, FALSE))
5864         goto error;
5865 
5866       WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
5867 
5868       if (thd->variables.option_bits & OPTION_IF_EXISTS)
5869         lex->create_info.set(DDL_options_st::OPT_IF_EXISTS);
5870 
5871       /* Conditionally writes to binlog. */
5872       res= mysql_drop_view(thd, first_table, thd->lex->drop_mode);
5873       break;
5874     }
5875   case SQLCOM_CREATE_TRIGGER:
5876   {
5877     /* Conditionally writes to binlog. */
5878     res= mysql_create_or_drop_trigger(thd, all_tables, 1);
5879 
5880     break;
5881   }
5882   case SQLCOM_DROP_TRIGGER:
5883   {
5884     if (thd->variables.option_bits & OPTION_IF_EXISTS)
5885       lex->create_info.set(DDL_options_st::OPT_IF_EXISTS);
5886 
5887     /* Conditionally writes to binlog. */
5888     res= mysql_create_or_drop_trigger(thd, all_tables, 0);
5889     break;
5890   }
5891   case SQLCOM_XA_START:
5892 #ifdef WITH_WSREP
5893     if (WSREP(thd))
5894     {
5895       my_error(ER_NOT_SUPPORTED_YET, MYF(0),
5896                "XA transactions with Galera replication");
5897       break;
5898     }
5899 #endif /* WITH_WSREP */
5900     if (trans_xa_start(thd))
5901       goto error;
5902     my_ok(thd);
5903     break;
5904   case SQLCOM_XA_END:
5905     if (trans_xa_end(thd))
5906       goto error;
5907     my_ok(thd);
5908     break;
5909   case SQLCOM_XA_PREPARE:
5910     if (trans_xa_prepare(thd))
5911       goto error;
5912     my_ok(thd);
5913     break;
5914   case SQLCOM_XA_COMMIT:
5915   {
5916     bool commit_failed= trans_xa_commit(thd);
5917     if (commit_failed)
5918     {
5919       WSREP_DEBUG("XA commit failed, MDL released: %lld",
5920                   (longlong) thd->thread_id);
5921       goto error;
5922     }
5923     /*
5924       We've just done a commit, reset transaction
5925       isolation level and access mode to the session default.
5926     */
5927     trans_reset_one_shot_chistics(thd);
5928     my_ok(thd);
5929     break;
5930   }
5931   case SQLCOM_XA_ROLLBACK:
5932   {
5933     bool rollback_failed= trans_xa_rollback(thd);
5934     if (rollback_failed)
5935     {
5936       WSREP_DEBUG("XA rollback failed, MDL released: %lld",
5937                   (longlong) thd->thread_id);
5938       goto error;
5939     }
5940     /*
5941       We've just done a rollback, reset transaction
5942       isolation level and access mode to the session default.
5943     */
5944     trans_reset_one_shot_chistics(thd);
5945     my_ok(thd);
5946     break;
5947   }
5948   case SQLCOM_XA_RECOVER:
5949     res= mysql_xa_recover(thd);
5950     break;
5951   case SQLCOM_ALTER_TABLESPACE:
5952     if (check_global_access(thd, CREATE_TABLESPACE_ACL))
5953       break;
5954     if (!(res= mysql_alter_tablespace(thd, lex->alter_tablespace_info)))
5955       my_ok(thd);
5956     break;
5957   case SQLCOM_INSTALL_PLUGIN:
5958     if (! (res= mysql_install_plugin(thd, &thd->lex->comment,
5959                                      &thd->lex->ident)))
5960       my_ok(thd);
5961     break;
5962   case SQLCOM_UNINSTALL_PLUGIN:
5963     if (! (res= mysql_uninstall_plugin(thd, &thd->lex->comment,
5964                                        &thd->lex->ident)))
5965       my_ok(thd);
5966     break;
5967   case SQLCOM_BINLOG_BASE64_EVENT:
5968   {
5969 #ifndef EMBEDDED_LIBRARY
5970     mysql_client_binlog_statement(thd);
5971 #else /* EMBEDDED_LIBRARY */
5972     my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "embedded");
5973 #endif /* EMBEDDED_LIBRARY */
5974     break;
5975   }
5976   case SQLCOM_CREATE_SERVER:
5977   {
5978     DBUG_PRINT("info", ("case SQLCOM_CREATE_SERVER"));
5979 
5980     if (check_global_access(thd, PRIV_STMT_CREATE_SERVER))
5981       break;
5982 
5983     WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
5984 
5985     res= create_server(thd, &lex->server_options);
5986     break;
5987   }
5988   case SQLCOM_ALTER_SERVER:
5989   {
5990     int error;
5991     DBUG_PRINT("info", ("case SQLCOM_ALTER_SERVER"));
5992 
5993     if (check_global_access(thd, PRIV_STMT_ALTER_SERVER))
5994       break;
5995 
5996     WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
5997 
5998     if (unlikely((error= alter_server(thd, &lex->server_options))))
5999     {
6000       DBUG_PRINT("info", ("problem altering server <%s>",
6001                           lex->server_options.server_name.str));
6002       my_error(error, MYF(0), lex->server_options.server_name.str);
6003       break;
6004     }
6005     my_ok(thd, 1);
6006     break;
6007   }
6008   case SQLCOM_DROP_SERVER:
6009   {
6010     int err_code;
6011     DBUG_PRINT("info", ("case SQLCOM_DROP_SERVER"));
6012 
6013     if (check_global_access(thd, PRIV_STMT_DROP_SERVER))
6014       break;
6015 
6016     WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
6017 
6018     if ((err_code= drop_server(thd, &lex->server_options)))
6019     {
6020       if (! lex->if_exists() && err_code == ER_FOREIGN_SERVER_DOESNT_EXIST)
6021       {
6022         DBUG_PRINT("info", ("problem dropping server %s",
6023                             lex->server_options.server_name.str));
6024         my_error(err_code, MYF(0), lex->server_options.server_name.str);
6025       }
6026       else
6027       {
6028         my_ok(thd, 0);
6029       }
6030       break;
6031     }
6032     my_ok(thd, 1);
6033     break;
6034   }
6035   case SQLCOM_ANALYZE:
6036   case SQLCOM_CHECK:
6037   case SQLCOM_OPTIMIZE:
6038   case SQLCOM_REPAIR:
6039   case SQLCOM_TRUNCATE:
6040   case SQLCOM_CREATE_TABLE:
6041   case SQLCOM_CREATE_SEQUENCE:
6042   case SQLCOM_ALTER_TABLE:
6043       DBUG_ASSERT(first_table == all_tables && first_table != 0);
6044     /* fall through */
6045   case SQLCOM_ALTER_SEQUENCE:
6046   case SQLCOM_SHOW_SLAVE_STAT:
6047   case SQLCOM_SIGNAL:
6048   case SQLCOM_RESIGNAL:
6049   case SQLCOM_GET_DIAGNOSTICS:
6050   case SQLCOM_CALL:
6051   case SQLCOM_REVOKE:
6052   case SQLCOM_GRANT:
6053     if (thd->variables.option_bits & OPTION_IF_EXISTS)
6054       lex->create_info.set(DDL_options_st::OPT_IF_EXISTS);
6055     DBUG_ASSERT(lex->m_sql_cmd != NULL);
6056     res= lex->m_sql_cmd->execute(thd);
6057     DBUG_PRINT("result", ("res: %d  killed: %d  is_error(): %d",
6058                           res, thd->killed, thd->is_error()));
6059     break;
6060   default:
6061 
6062 #ifndef EMBEDDED_LIBRARY
6063     DBUG_ASSERT(0);                             /* Impossible */
6064 #endif
6065     my_ok(thd);
6066     break;
6067   }
6068   THD_STAGE_INFO(thd, stage_query_end);
6069   thd->update_stats();
6070 
6071   goto finish;
6072 
6073 error:
6074 #ifdef WITH_WSREP
6075 wsrep_error_label:
6076 #endif
6077   res= true;
6078 
6079 finish:
6080 
6081   thd->reset_query_timer();
6082   DBUG_ASSERT(!thd->in_active_multi_stmt_transaction() ||
6083                thd->in_multi_stmt_transaction_mode());
6084 
6085   lex->unit.cleanup();
6086 
6087   /* close/reopen tables that were marked to need reopen under LOCK TABLES */
6088   if (unlikely(thd->locked_tables_list.some_table_marked_for_reopen) &&
6089       !thd->lex->requires_prelocking())
6090     thd->locked_tables_list.reopen_tables(thd, true);
6091 
6092   if (! thd->in_sub_stmt)
6093   {
6094     if (thd->killed != NOT_KILLED)
6095     {
6096       /* report error issued during command execution */
6097       if (thd->killed_errno())
6098       {
6099         /* If we already sent 'ok', we can ignore any kill query statements */
6100         if (! thd->get_stmt_da()->is_set())
6101           thd->send_kill_message();
6102       }
6103       thd->reset_kill_query();
6104     }
6105     if (unlikely(thd->is_error()) ||
6106         (thd->variables.option_bits & OPTION_MASTER_SQL_ERROR))
6107     {
6108       THD_STAGE_INFO(thd, stage_rollback);
6109       trans_rollback_stmt(thd);
6110     }
6111     else
6112     {
6113       /* If commit fails, we should be able to reset the OK status. */
6114       THD_STAGE_INFO(thd, stage_commit);
6115       thd->get_stmt_da()->set_overwrite_status(true);
6116       trans_commit_stmt(thd);
6117       thd->get_stmt_da()->set_overwrite_status(false);
6118     }
6119   }
6120 
6121   /* Free tables. Set stage 'closing tables' */
6122   close_thread_tables(thd);
6123 
6124 
6125 #ifndef DBUG_OFF
6126   if (lex->sql_command != SQLCOM_SET_OPTION && ! thd->in_sub_stmt)
6127     DEBUG_SYNC(thd, "execute_command_after_close_tables");
6128 #endif
6129   if (!(sql_command_flags[lex->sql_command] &
6130         (CF_CAN_GENERATE_ROW_EVENTS | CF_FORCE_ORIGINAL_BINLOG_FORMAT |
6131          CF_STATUS_COMMAND)))
6132     thd->set_binlog_format(orig_binlog_format,
6133                            orig_current_stmt_binlog_format);
6134 
6135   if (! thd->in_sub_stmt && thd->transaction_rollback_request)
6136   {
6137     /*
6138       We are not in sub-statement and transaction rollback was requested by
6139       one of storage engines (e.g. due to deadlock). Rollback transaction in
6140       all storage engines including binary log.
6141     */
6142     THD_STAGE_INFO(thd, stage_rollback_implicit);
6143     trans_rollback_implicit(thd);
6144     thd->release_transactional_locks();
6145   }
6146   else if (stmt_causes_implicit_commit(thd, CF_IMPLICIT_COMMIT_END))
6147   {
6148     /* No transaction control allowed in sub-statements. */
6149     DBUG_ASSERT(! thd->in_sub_stmt);
6150     if (!(thd->variables.option_bits & OPTION_GTID_BEGIN))
6151     {
6152       THD_STAGE_INFO(thd, stage_commit_implicit);
6153       /* If commit fails, we should be able to reset the OK status. */
6154       thd->get_stmt_da()->set_overwrite_status(true);
6155       /* Commit the normal transaction if one is active. */
6156       trans_commit_implicit(thd);
6157       thd->get_stmt_da()->set_overwrite_status(false);
6158       thd->release_transactional_locks();
6159     }
6160   }
6161   else if (! thd->in_sub_stmt && ! thd->in_multi_stmt_transaction_mode())
6162   {
6163     /*
6164       - If inside a multi-statement transaction,
6165       defer the release of metadata locks until the current
6166       transaction is either committed or rolled back. This prevents
6167       other statements from modifying the table for the entire
6168       duration of this transaction.  This provides commit ordering
6169       and guarantees serializability across multiple transactions.
6170       - If in autocommit mode, or outside a transactional context,
6171       automatically release metadata locks of the current statement.
6172     */
6173     thd->release_transactional_locks();
6174   }
6175   else if (! thd->in_sub_stmt)
6176   {
6177     thd->mdl_context.release_statement_locks();
6178   }
6179 
6180   THD_STAGE_INFO(thd, stage_starting_cleanup);
6181 
6182   TRANSACT_TRACKER(add_trx_state_from_thd(thd));
6183 
6184 #ifdef WITH_WSREP
6185   thd->wsrep_consistency_check= NO_CONSISTENCY_CHECK;
6186 
6187   WSREP_TO_ISOLATION_END;
6188   /*
6189     Force release of transactional locks if not in active MST and wsrep is on.
6190   */
6191   if (WSREP(thd) &&
6192       ! thd->in_sub_stmt &&
6193       ! thd->in_active_multi_stmt_transaction() &&
6194       thd->mdl_context.has_transactional_locks())
6195   {
6196     WSREP_DEBUG("Forcing release of transactional locks for thd: %lld",
6197                 (longlong) thd->thread_id);
6198     thd->release_transactional_locks();
6199   }
6200 
6201   /*
6202     Current command did not start multi STMT transaction and the command
6203     did not cause commit to happen (e.g. read only). Commit the wsrep
6204     transaction as empty.
6205   */
6206   if (!thd->in_active_multi_stmt_transaction() &&
6207       !thd->in_sub_stmt &&
6208       thd->wsrep_trx().active() &&
6209       thd->wsrep_trx().state() == wsrep::transaction::s_executing)
6210   {
6211     wsrep_commit_empty(thd, true);
6212   }
6213 
6214   /* assume PA safety for next transaction */
6215   thd->wsrep_PA_safe= true;
6216 #endif /* WITH_WSREP */
6217 
6218   DBUG_RETURN(res || thd->is_error());
6219  }
6220 
execute_sqlcom_select(THD * thd,TABLE_LIST * all_tables)6221 static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
6222 {
6223   LEX	*lex= thd->lex;
6224   select_result *result=lex->result;
6225   bool res;
6226   /* assign global limit variable if limit is not given */
6227   {
6228     SELECT_LEX *param= lex->unit.global_parameters();
6229     if (!param->explicit_limit)
6230       param->select_limit=
6231         new (thd->mem_root) Item_int(thd,
6232                                      (ulonglong) thd->variables.select_limit);
6233   }
6234 
6235   if (!(res= open_and_lock_tables(thd, all_tables, TRUE, 0)))
6236   {
6237     if (lex->describe)
6238     {
6239       /*
6240         We always use select_send for EXPLAIN, even if it's an EXPLAIN
6241         for SELECT ... INTO OUTFILE: a user application should be able
6242         to prepend EXPLAIN to any query and receive output for it,
6243         even if the query itself redirects the output.
6244       */
6245       if (unlikely(!(result= new (thd->mem_root) select_send(thd))))
6246         return 1;                               /* purecov: inspected */
6247       thd->send_explain_fields(result, lex->describe, lex->analyze_stmt);
6248 
6249       /*
6250         This will call optimize() for all parts of query. The query plan is
6251         printed out below.
6252       */
6253       res= mysql_explain_union(thd, &lex->unit, result);
6254 
6255       /* Print EXPLAIN only if we don't have an error */
6256       if (likely(!res))
6257       {
6258         /*
6259           Do like the original select_describe did: remove OFFSET from the
6260           top-level LIMIT
6261         */
6262         result->remove_offset_limit();
6263         if (lex->explain_json)
6264         {
6265           lex->explain->print_explain_json(result, lex->analyze_stmt);
6266         }
6267         else
6268         {
6269           lex->explain->print_explain(result, thd->lex->describe,
6270                                       thd->lex->analyze_stmt);
6271           if (lex->describe & DESCRIBE_EXTENDED)
6272           {
6273             char buff[1024];
6274             String str(buff,(uint32) sizeof(buff), system_charset_info);
6275             str.length(0);
6276             /*
6277               The warnings system requires input in utf8, @see
6278               mysqld_show_warnings().
6279             */
6280             lex->unit.print(&str, QT_EXPLAIN_EXTENDED);
6281             push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
6282                          ER_YES, str.c_ptr_safe());
6283           }
6284         }
6285       }
6286 
6287       if (res)
6288         result->abort_result_set();
6289       else
6290         result->send_eof();
6291       delete result;
6292     }
6293     else
6294     {
6295       Protocol *save_protocol= NULL;
6296       if (lex->analyze_stmt)
6297       {
6298         if (result && result->result_interceptor())
6299           result->result_interceptor()->disable_my_ok_calls();
6300         else
6301         {
6302           DBUG_ASSERT(thd->protocol);
6303           result= new (thd->mem_root) select_send_analyze(thd);
6304           save_protocol= thd->protocol;
6305           thd->protocol= new Protocol_discard(thd);
6306         }
6307       }
6308       else
6309       {
6310         if (!result && !(result= new (thd->mem_root) select_send(thd)))
6311           return 1;                               /* purecov: inspected */
6312       }
6313       query_cache_store_query(thd, all_tables);
6314       res= handle_select(thd, lex, result, 0);
6315       if (result != lex->result)
6316         delete result;
6317 
6318       if (lex->analyze_stmt)
6319       {
6320         if (save_protocol)
6321         {
6322           delete thd->protocol;
6323           thd->protocol= save_protocol;
6324         }
6325         if (!res)
6326           res= thd->lex->explain->send_explain(thd);
6327       }
6328     }
6329   }
6330   /* Count number of empty select queries */
6331   if (!thd->get_sent_row_count() && !res)
6332     status_var_increment(thd->status_var.empty_queries);
6333   else
6334     status_var_add(thd->status_var.rows_sent, thd->get_sent_row_count());
6335 
6336   return res;
6337 }
6338 
6339 
6340 /**
6341    SHOW STATUS
6342 
6343    Notes: This is noinline as we don't want to have system_status_var (> 3K)
6344    to be on the stack of mysql_execute_command()
6345 */
6346 
6347 static bool __attribute__ ((noinline))
execute_show_status(THD * thd,TABLE_LIST * all_tables)6348 execute_show_status(THD *thd, TABLE_LIST *all_tables)
6349 {
6350   bool res;
6351   system_status_var old_status_var= thd->status_var;
6352   thd->initial_status_var= &old_status_var;
6353   WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW);
6354   if (!(res= check_table_access(thd, SELECT_ACL, all_tables, FALSE,
6355                                 UINT_MAX, FALSE)))
6356     res= execute_sqlcom_select(thd, all_tables);
6357 
6358   thd->initial_status_var= NULL;
6359   /* Don't log SHOW STATUS commands to slow query log */
6360   thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED |
6361                          SERVER_QUERY_NO_GOOD_INDEX_USED);
6362   /*
6363     restore status variables, as we don't want 'show status' to cause
6364     changes
6365   */
6366   mysql_mutex_lock(&LOCK_status);
6367   add_diff_to_status(&global_status_var, &thd->status_var,
6368                      &old_status_var);
6369   memcpy(&thd->status_var, &old_status_var,
6370          offsetof(STATUS_VAR, last_cleared_system_status_var));
6371   mysql_mutex_unlock(&LOCK_status);
6372   return res;
6373 #ifdef WITH_WSREP
6374 wsrep_error_label: /* see WSREP_SYNC_WAIT() macro above */
6375   return true;
6376 #endif /* WITH_WSREP */
6377 }
6378 
6379 
6380 /*
6381   Find out if a table is a temporary table
6382 
6383   A table is a temporary table if it's a temporary table or
6384   there has been before a temporary table that has been renamed
6385   to the current name.
6386 
6387   Some examples:
6388   A->B          B is a temporary table if and only if A is a temp.
6389   A->B, B->C    Second B is temp if A is temp
6390   A->B, A->C    Second A can't be temp as if A was temp then B is temp
6391                 and Second A can only be a normal table. C is also not temp
6392 */
6393 
find_temporary_table_for_rename(THD * thd,TABLE_LIST * first_table,TABLE_LIST * cur_table)6394 static TABLE *find_temporary_table_for_rename(THD *thd,
6395                                               TABLE_LIST *first_table,
6396                                               TABLE_LIST *cur_table)
6397 {
6398   TABLE_LIST *table;
6399   TABLE *res= 0;
6400   bool found= 0;
6401   DBUG_ENTER("find_temporary_table_for_rename");
6402 
6403   /* Find last instance when cur_table is in TO part */
6404   for (table= first_table;
6405        table != cur_table;
6406        table= table->next_local->next_local)
6407   {
6408     TABLE_LIST *next= table->next_local;
6409 
6410     if (!strcmp(table->get_db_name(),   cur_table->get_db_name()) &&
6411         !strcmp(table->get_table_name(), cur_table->get_table_name()))
6412     {
6413       /* Table was moved away, can't be same as 'table' */
6414       found= 1;
6415       res= 0;                      // Table can't be a temporary table
6416     }
6417     if (!strcmp(next->get_db_name(),    cur_table->get_db_name()) &&
6418         !strcmp(next->get_table_name(), cur_table->get_table_name()))
6419     {
6420       /*
6421         Table has matching name with new name of this table. cur_table should
6422         have same temporary type as this table.
6423       */
6424       found= 1;
6425       res= table->table;
6426     }
6427   }
6428   if (!found)
6429     res= thd->find_temporary_table(table, THD::TMP_TABLE_ANY);
6430   DBUG_RETURN(res);
6431 }
6432 
6433 
6434 static bool __attribute__ ((noinline))
check_rename_table(THD * thd,TABLE_LIST * first_table,TABLE_LIST * all_tables)6435 check_rename_table(THD *thd, TABLE_LIST *first_table,
6436                    TABLE_LIST *all_tables)
6437 {
6438   DBUG_ASSERT(first_table == all_tables && first_table != 0);
6439   TABLE_LIST *table;
6440   for (table= first_table; table; table= table->next_local->next_local)
6441   {
6442     if (check_access(thd, ALTER_ACL | DROP_ACL, table->db.str,
6443                      &table->grant.privilege,
6444                      &table->grant.m_internal,
6445                      0, 0) ||
6446         check_access(thd, INSERT_ACL | CREATE_ACL, table->next_local->db.str,
6447                      &table->next_local->grant.privilege,
6448                      &table->next_local->grant.m_internal,
6449                      0, 0))
6450       return 1;
6451 
6452     /* check if these are referring to temporary tables */
6453     table->table= find_temporary_table_for_rename(thd, first_table, table);
6454     table->next_local->table= table->table;
6455 
6456     TABLE_LIST old_list, new_list;
6457     /*
6458       we do not need initialize old_list and new_list because we will
6459       copy table[0] and table->next[0] there
6460     */
6461     old_list= table[0];
6462     new_list= table->next_local[0];
6463 
6464     if (check_grant(thd, ALTER_ACL | DROP_ACL, &old_list, FALSE, 1, FALSE) ||
6465        (!test_all_bits(table->next_local->grant.privilege,
6466                        INSERT_ACL | CREATE_ACL) &&
6467         check_grant(thd, INSERT_ACL | CREATE_ACL, &new_list, FALSE, 1,
6468                     FALSE)))
6469       return 1;
6470   }
6471 
6472   return 0;
6473 }
6474 
6475 /*
6476   Generate an incident log event before writing the real event
6477   to the binary log.  We put this event is before the statement
6478   since that makes it simpler to check that the statement was
6479   not executed on the slave (since incidents usually stop the
6480   slave).
6481 
6482   Observe that any row events that are generated will be generated before.
6483 
6484   This is only for testing purposes and will not be present in a release build.
6485 */
6486 
6487 #ifndef DBUG_OFF
generate_incident_event(THD * thd)6488 static bool __attribute__ ((noinline)) generate_incident_event(THD *thd)
6489 {
6490   if (mysql_bin_log.is_open())
6491   {
6492 
6493     Incident incident= INCIDENT_NONE;
6494     DBUG_PRINT("debug", ("Just before generate_incident()"));
6495     DBUG_EXECUTE_IF("incident_database_resync_on_replace",
6496                     incident= INCIDENT_LOST_EVENTS;);
6497     if (incident)
6498     {
6499       Incident_log_event ev(thd, incident);
6500       (void) mysql_bin_log.write(&ev);        /* error is ignored */
6501       if (mysql_bin_log.rotate_and_purge(true))
6502         return 1;
6503     }
6504     DBUG_PRINT("debug", ("Just after generate_incident()"));
6505   }
6506   return 0;
6507 }
6508 #else
generate_incident_event(THD * thd)6509 static bool generate_incident_event(THD *thd)
6510 {
6511   return 0;
6512 }
6513 #endif
6514 
6515 
6516 static int __attribute__ ((noinline))
show_create_db(THD * thd,LEX * lex)6517 show_create_db(THD *thd, LEX *lex)
6518 {
6519   char db_name_buff[NAME_LEN+1];
6520   LEX_CSTRING db_name;
6521   DBUG_EXECUTE_IF("4x_server_emul",
6522                   my_error(ER_UNKNOWN_ERROR, MYF(0)); return 1;);
6523 
6524   db_name.str= db_name_buff;
6525   db_name.length= lex->name.length;
6526   strmov(db_name_buff, lex->name.str);
6527 
6528   if (check_db_name((LEX_STRING*) &db_name))
6529   {
6530     my_error(ER_WRONG_DB_NAME, MYF(0), db_name.str);
6531     return 1;
6532   }
6533   return mysqld_show_create_db(thd, &db_name, &lex->name, lex->create_info);
6534 }
6535 
6536 
6537 /**
6538    Called on SQLCOM_ALTER_PROCEDURE and SQLCOM_ALTER_FUNCTION
6539 */
6540 
6541 static bool __attribute__ ((noinline))
alter_routine(THD * thd,LEX * lex)6542 alter_routine(THD *thd, LEX *lex)
6543 {
6544   int sp_result;
6545   const Sp_handler *sph= Sp_handler::handler(lex->sql_command);
6546   if (check_routine_access(thd, ALTER_PROC_ACL, &lex->spname->m_db,
6547                            &lex->spname->m_name, sph, 0))
6548     return 1;
6549   /*
6550     Note that if you implement the capability of ALTER FUNCTION to
6551     alter the body of the function, this command should be made to
6552     follow the restrictions that log-bin-trust-function-creators=0
6553     already puts on CREATE FUNCTION.
6554   */
6555   /* Conditionally writes to binlog */
6556   sp_result= sph->sp_update_routine(thd, lex->spname, &lex->sp_chistics);
6557   switch (sp_result) {
6558   case SP_OK:
6559     my_ok(thd);
6560     return 0;
6561   case SP_KEY_NOT_FOUND:
6562     my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
6563              sph->type_str(), ErrConvDQName(lex->spname).ptr());
6564     return 1;
6565   default:
6566     my_error(ER_SP_CANT_ALTER, MYF(0),
6567              sph->type_str(), ErrConvDQName(lex->spname).ptr());
6568     return 1;
6569   }
6570   return 0;                                     /* purecov: deadcode */
6571 }
6572 
6573 
6574 static bool __attribute__ ((noinline))
drop_routine(THD * thd,LEX * lex)6575 drop_routine(THD *thd, LEX *lex)
6576 {
6577   int sp_result;
6578 #ifdef HAVE_DLOPEN
6579   if (lex->sql_command == SQLCOM_DROP_FUNCTION &&
6580       ! lex->spname->m_explicit_name)
6581   {
6582     /* DROP FUNCTION <non qualified name> */
6583     enum drop_udf_result rc= mysql_drop_function(thd, &lex->spname->m_name);
6584     switch (rc) {
6585     case UDF_DEL_RESULT_DELETED:
6586       my_ok(thd);
6587       return 0;
6588     case UDF_DEL_RESULT_ERROR:
6589       return 1;
6590     case UDF_DEL_RESULT_ABSENT:
6591       goto absent;
6592     }
6593 
6594     DBUG_ASSERT("wrong return code" == 0);
6595 absent:
6596     // If there was no current database, so it cannot be SP
6597     if (!lex->spname->m_db.str)
6598     {
6599       if (lex->if_exists())
6600       {
6601         push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
6602                             ER_SP_DOES_NOT_EXIST,
6603                             ER_THD(thd, ER_SP_DOES_NOT_EXIST),
6604                             "FUNCTION (UDF)", lex->spname->m_name.str);
6605         my_ok(thd);
6606         return 0;
6607       }
6608       my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
6609                "FUNCTION (UDF)", lex->spname->m_name.str);
6610       return 1;
6611     }
6612     /* Fall trough to test for a stored function */
6613   }
6614 #endif /* HAVE_DLOPEN */
6615 
6616   const Sp_handler *sph= Sp_handler::handler(lex->sql_command);
6617 
6618   if (check_routine_access(thd, ALTER_PROC_ACL, &lex->spname->m_db,
6619                            &lex->spname->m_name,
6620                            Sp_handler::handler(lex->sql_command), 0))
6621     return 1;
6622 
6623   WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
6624 
6625   /* Conditionally writes to binlog */
6626   sp_result= sph->sp_drop_routine(thd, lex->spname);
6627 
6628 #ifndef NO_EMBEDDED_ACCESS_CHECKS
6629   /*
6630     We're going to issue an implicit REVOKE statement so we close all
6631     open tables. We have to keep metadata locks as this ensures that
6632     this statement is atomic against concurent FLUSH TABLES WITH READ
6633     LOCK. Deadlocks which can arise due to fact that this implicit
6634     statement takes metadata locks should be detected by a deadlock
6635     detector in MDL subsystem and reported as errors.
6636 
6637     TODO: Long-term we should either ensure that implicit REVOKE statement
6638     is written into binary log as a separate statement or make both
6639     dropping of routine and implicit REVOKE parts of one fully atomic
6640     statement.
6641   */
6642   if (trans_commit_stmt(thd))
6643     sp_result= SP_INTERNAL_ERROR;
6644   close_thread_tables(thd);
6645 
6646   if (sp_result != SP_KEY_NOT_FOUND &&
6647       sp_automatic_privileges && !opt_noacl &&
6648       sp_revoke_privileges(thd, lex->spname->m_db.str, lex->spname->m_name.str,
6649                            Sp_handler::handler(lex->sql_command)))
6650   {
6651     push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
6652                  ER_PROC_AUTO_REVOKE_FAIL,
6653                  ER_THD(thd, ER_PROC_AUTO_REVOKE_FAIL));
6654     /* If this happens, an error should have been reported. */
6655     return 1;
6656   }
6657 #endif /* NO_EMBEDDED_ACCESS_CHECKS */
6658 
6659   switch (sp_result) {
6660   case SP_OK:
6661     my_ok(thd);
6662     return 0;
6663   case SP_KEY_NOT_FOUND:
6664     int res;
6665     if (lex->if_exists())
6666     {
6667       res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
6668       push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
6669                           ER_SP_DOES_NOT_EXIST,
6670                           ER_THD(thd, ER_SP_DOES_NOT_EXIST),
6671                           sph->type_str(),
6672                           ErrConvDQName(lex->spname).ptr());
6673       if (res)
6674         return 1;
6675       my_ok(thd);
6676       return 0;
6677     }
6678     my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
6679              sph->type_str(), ErrConvDQName(lex->spname).ptr());
6680     return 1;
6681   default:
6682     my_error(ER_SP_DROP_FAILED, MYF(0),
6683              sph->type_str(), ErrConvDQName(lex->spname).ptr());
6684     return 1;
6685   }
6686 
6687 #ifdef WITH_WSREP
6688 wsrep_error_label:
6689   return 1;
6690 #endif
6691 }
6692 
6693 /**
6694   @brief Compare requested privileges with the privileges acquired from the
6695     User- and Db-tables.
6696   @param thd          Thread handler
6697   @param want_access  The requested access privileges.
6698   @param db           A pointer to the Db name.
6699   @param[out] save_priv A pointer to the granted privileges will be stored.
6700   @param grant_internal_info A pointer to the internal grant cache.
6701   @param dont_check_global_grants True if no global grants are checked.
6702   @param no_error     True if no errors should be sent to the client.
6703 
6704   'save_priv' is used to save the User-table (global) and Db-table grants for
6705   the supplied db name. Note that we don't store db level grants if the global
6706   grants is enough to satisfy the request AND the global grants contains a
6707   SELECT grant.
6708 
6709   For internal databases (INFORMATION_SCHEMA, PERFORMANCE_SCHEMA),
6710   additional rules apply, see ACL_internal_schema_access.
6711 
6712   @see check_grant
6713 
6714   @return Status of denial of access by exclusive ACLs.
6715     @retval FALSE Access can't exclusively be denied by Db- and User-table
6716       access unless Column- and Table-grants are checked too.
6717     @retval TRUE Access denied.
6718 */
6719 
6720 bool
check_access(THD * thd,privilege_t want_access,const char * db,privilege_t * save_priv,GRANT_INTERNAL_INFO * grant_internal_info,bool dont_check_global_grants,bool no_errors)6721 check_access(THD *thd, privilege_t want_access,
6722              const char *db, privilege_t *save_priv,
6723              GRANT_INTERNAL_INFO *grant_internal_info,
6724              bool dont_check_global_grants, bool no_errors)
6725 {
6726 #ifdef NO_EMBEDDED_ACCESS_CHECKS
6727   if (save_priv)
6728     *save_priv= GLOBAL_ACLS;
6729   return false;
6730 #else
6731   Security_context *sctx= thd->security_ctx;
6732   privilege_t db_access(NO_ACL);
6733 
6734   /*
6735     GRANT command:
6736     In case of database level grant the database name may be a pattern,
6737     in case of table|column level grant the database name can not be a pattern.
6738     We use 'dont_check_global_grants' as a flag to determine
6739     if it's database level grant command
6740     (see SQLCOM_GRANT case, mysql_execute_command() function) and
6741     set db_is_pattern according to 'dont_check_global_grants' value.
6742   */
6743   bool  db_is_pattern= ((want_access & GRANT_ACL) && dont_check_global_grants);
6744   privilege_t dummy(NO_ACL);
6745   DBUG_ENTER("check_access");
6746   DBUG_PRINT("enter",("db: %s  want_access: %llx  master_access: %llx",
6747                       db ? db : "",
6748                       (longlong) want_access,
6749                       (longlong) sctx->master_access));
6750 
6751   if (save_priv)
6752     *save_priv= NO_ACL;
6753   else
6754   {
6755     save_priv= &dummy;
6756     dummy= NO_ACL;
6757   }
6758 
6759   /* check access may be called twice in a row. Don't change to same stage */
6760   if (thd->proc_info != stage_checking_permissions.m_name)
6761     THD_STAGE_INFO(thd, stage_checking_permissions);
6762   if (unlikely((!db || !db[0]) && !thd->db.str && !dont_check_global_grants))
6763   {
6764     DBUG_RETURN(FALSE); // CTE reference or an error later
6765   }
6766 
6767   if (likely((db != NULL) && (db != any_db)))
6768   {
6769     /*
6770       Check if this is reserved database, like information schema or
6771       performance schema
6772     */
6773     const ACL_internal_schema_access *access;
6774     access= get_cached_schema_access(grant_internal_info, db);
6775     if (access)
6776     {
6777       switch (access->check(want_access, save_priv))
6778       {
6779       case ACL_INTERNAL_ACCESS_GRANTED:
6780         /*
6781           All the privileges requested have been granted internally.
6782           [out] *save_privileges= Internal privileges.
6783         */
6784         DBUG_RETURN(FALSE);
6785       case ACL_INTERNAL_ACCESS_DENIED:
6786         if (! no_errors)
6787         {
6788           status_var_increment(thd->status_var.access_denied_errors);
6789           my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
6790                    sctx->priv_user, sctx->priv_host, db);
6791         }
6792         DBUG_RETURN(TRUE);
6793       case ACL_INTERNAL_ACCESS_CHECK_GRANT:
6794         /*
6795           Only some of the privilege requested have been granted internally,
6796           proceed with the remaining bits of the request (want_access).
6797         */
6798         want_access&= ~(*save_priv);
6799         break;
6800       }
6801     }
6802   }
6803 
6804   if ((sctx->master_access & want_access) == want_access)
6805   {
6806     /*
6807       1. If we don't have a global SELECT privilege, we have to get the
6808       database specific access rights to be able to handle queries of type
6809       UPDATE t1 SET a=1 WHERE b > 0
6810       2. Change db access if it isn't current db which is being addressed
6811     */
6812     if (!(sctx->master_access & SELECT_ACL))
6813     {
6814       if (db && (!thd->db.str || db_is_pattern || strcmp(db, thd->db.str)))
6815       {
6816         db_access= acl_get(sctx->host, sctx->ip, sctx->priv_user, db,
6817                            db_is_pattern);
6818         if (sctx->priv_role[0])
6819           db_access|= acl_get("", "", sctx->priv_role, db, db_is_pattern);
6820       }
6821       else
6822       {
6823         /* get access for current db */
6824         db_access= sctx->db_access;
6825       }
6826       /*
6827         The effective privileges are the union of the global privileges
6828         and the intersection of db- and host-privileges,
6829         plus the internal privileges.
6830       */
6831       *save_priv|= sctx->master_access | db_access;
6832     }
6833     else
6834       *save_priv|= sctx->master_access;
6835     DBUG_RETURN(FALSE);
6836   }
6837   if (unlikely(((want_access & ~sctx->master_access) & ~DB_ACLS) ||
6838                (! db && dont_check_global_grants)))
6839   {						// We can never grant this
6840     DBUG_PRINT("error",("No possible access"));
6841     if (!no_errors)
6842     {
6843       status_var_increment(thd->status_var.access_denied_errors);
6844       my_error(access_denied_error_code(thd->password), MYF(0),
6845                sctx->priv_user,
6846                sctx->priv_host,
6847                (thd->password ?
6848                 ER_THD(thd, ER_YES) :
6849                 ER_THD(thd, ER_NO)));                    /* purecov: tested */
6850     }
6851     DBUG_RETURN(TRUE);				/* purecov: tested */
6852   }
6853 
6854   if (unlikely(db == any_db))
6855   {
6856     /*
6857       Access granted; Allow select on *any* db.
6858       [out] *save_privileges= 0
6859     */
6860     DBUG_RETURN(FALSE);
6861   }
6862 
6863   if (db && (!thd->db.str || db_is_pattern || strcmp(db, thd->db.str)))
6864   {
6865     db_access= acl_get(sctx->host, sctx->ip, sctx->priv_user, db,
6866                        db_is_pattern);
6867     if (sctx->priv_role[0])
6868     {
6869       db_access|= acl_get("", "", sctx->priv_role, db, db_is_pattern);
6870     }
6871   }
6872   else
6873     db_access= sctx->db_access;
6874   DBUG_PRINT("info",("db_access: %llx  want_access: %llx",
6875                      (longlong) db_access, (longlong) want_access));
6876 
6877   /*
6878     Save the union of User-table and the intersection between Db-table and
6879     Host-table privileges, with the already saved internal privileges.
6880   */
6881   db_access= (db_access | sctx->master_access);
6882   *save_priv|= db_access;
6883 
6884   /*
6885     We need to investigate column- and table access if all requested privileges
6886     belongs to the bit set of .
6887   */
6888   bool need_table_or_column_check=
6889     (want_access & (TABLE_ACLS | PROC_ACLS | db_access)) == want_access;
6890 
6891   /*
6892     Grant access if the requested access is in the intersection of
6893     host- and db-privileges (as retrieved from the acl cache),
6894     also grant access if all the requested privileges are in the union of
6895     TABLES_ACLS and PROC_ACLS; see check_grant.
6896   */
6897   if ( (db_access & want_access) == want_access ||
6898       (!dont_check_global_grants &&
6899        need_table_or_column_check))
6900   {
6901     /*
6902        Ok; but need to check table- and column privileges.
6903        [out] *save_privileges is (User-priv | (Db-priv & Host-priv) | Internal-priv)
6904     */
6905     DBUG_RETURN(FALSE);
6906   }
6907 
6908   /*
6909     Access is denied;
6910     [out] *save_privileges is (User-priv | (Db-priv & Host-priv) | Internal-priv)
6911   */
6912   DBUG_PRINT("error",("Access denied"));
6913   if (!no_errors)
6914   {
6915     status_var_increment(thd->status_var.access_denied_errors);
6916     my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
6917              sctx->priv_user, sctx->priv_host,
6918              (db ? db : (thd->db.str ?
6919                          thd->db.str :
6920                          "unknown")));
6921   }
6922   DBUG_RETURN(TRUE);
6923 #endif // NO_EMBEDDED_ACCESS_CHECKS
6924 }
6925 
6926 
6927 #ifndef NO_EMBEDDED_ACCESS_CHECKS
6928 /**
6929   Check grants for commands which work only with one table.
6930 
6931   @param thd                    Thread handler
6932   @param privilege              requested privilege
6933   @param tables                 global table list of query
6934   @param no_errors              FALSE/TRUE - report/don't report error to
6935                             the client (using my_error() call).
6936 
6937   @retval
6938     0   OK
6939   @retval
6940     1   access denied, error is sent to client
6941 */
6942 
check_single_table_access(THD * thd,privilege_t privilege,TABLE_LIST * tables,bool no_errors)6943 bool check_single_table_access(THD *thd, privilege_t privilege,
6944                                TABLE_LIST *tables, bool no_errors)
6945 {
6946   if (tables->derived)
6947     return 0;
6948 
6949   Switch_to_definer_security_ctx backup_sctx(thd, tables);
6950 
6951   const char *db_name;
6952   if ((tables->view || tables->field_translation) && !tables->schema_table)
6953     db_name= tables->view_db.str;
6954   else
6955     db_name= tables->db.str;
6956 
6957   if (check_access(thd, privilege, db_name, &tables->grant.privilege,
6958                    &tables->grant.m_internal, 0, no_errors))
6959     return 1;
6960 
6961   /* Show only 1 table for check_grant */
6962   if (!(tables->belong_to_view &&
6963        (thd->lex->sql_command == SQLCOM_SHOW_FIELDS)) &&
6964       check_grant(thd, privilege, tables, FALSE, 1, no_errors))
6965     return 1;
6966 
6967   return 0;
6968 }
6969 
6970 /**
6971   Check grants for commands which work only with one table and all other
6972   tables belonging to subselects or implicitly opened tables.
6973 
6974   @param thd			Thread handler
6975   @param privilege		requested privilege
6976   @param all_tables		global table list of query
6977 
6978   @retval
6979     0   OK
6980   @retval
6981     1   access denied, error is sent to client
6982 */
6983 
check_one_table_access(THD * thd,privilege_t privilege,TABLE_LIST * all_tables)6984 bool check_one_table_access(THD *thd, privilege_t privilege,
6985                             TABLE_LIST *all_tables)
6986 {
6987   if (check_single_table_access (thd,privilege,all_tables, FALSE))
6988     return 1;
6989 
6990   /* Check rights on tables of subselects and implictly opened tables */
6991   TABLE_LIST *subselects_tables, *view= all_tables->view ? all_tables : 0;
6992   if ((subselects_tables= all_tables->next_global))
6993   {
6994     /*
6995       Access rights asked for the first table of a view should be the same
6996       as for the view
6997     */
6998     if (view && subselects_tables->belong_to_view == view)
6999     {
7000       if (check_single_table_access (thd, privilege, subselects_tables, FALSE))
7001         return 1;
7002       subselects_tables= subselects_tables->next_global;
7003     }
7004     if (subselects_tables &&
7005         (check_table_access(thd, SELECT_ACL, subselects_tables, FALSE,
7006                             UINT_MAX, FALSE)))
7007       return 1;
7008   }
7009   return 0;
7010 }
7011 
7012 
check_show_access(THD * thd,TABLE_LIST * table)7013 static bool check_show_access(THD *thd, TABLE_LIST *table)
7014 {
7015   /*
7016     This is a SHOW command using an INFORMATION_SCHEMA table.
7017     check_access() has not been called for 'table',
7018     and SELECT is currently always granted on the I_S, so we automatically
7019     grant SELECT on table here, to bypass a call to check_access().
7020     Note that not calling check_access(table) is an optimization,
7021     which needs to be revisited if the INFORMATION_SCHEMA does
7022     not always automatically grant SELECT but use the grant tables.
7023     See Bug#38837 need a way to disable information_schema for security
7024   */
7025   table->grant.privilege= SELECT_ACL;
7026 
7027   switch (get_schema_table_idx(table->schema_table)) {
7028   case SCH_SCHEMATA:
7029     return (specialflag & SPECIAL_SKIP_SHOW_DB) &&
7030       check_global_access(thd, SHOW_DB_ACL);
7031 
7032   case SCH_TABLE_NAMES:
7033   case SCH_TABLES:
7034   case SCH_VIEWS:
7035   case SCH_TRIGGERS:
7036   case SCH_EVENTS:
7037   {
7038     const char *dst_db_name= table->schema_select_lex->db.str;
7039 
7040     DBUG_ASSERT(dst_db_name);
7041 
7042     if (check_access(thd, SELECT_ACL, dst_db_name,
7043                      &thd->col_access, NULL, FALSE, FALSE))
7044       return TRUE;
7045 
7046     if (!thd->col_access && check_grant_db(thd, dst_db_name))
7047     {
7048       status_var_increment(thd->status_var.access_denied_errors);
7049       my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
7050                thd->security_ctx->priv_user,
7051                thd->security_ctx->priv_host,
7052                dst_db_name);
7053       return TRUE;
7054     }
7055 
7056     return FALSE;
7057   }
7058 
7059   case SCH_COLUMNS:
7060   case SCH_STATISTICS:
7061   {
7062     TABLE_LIST *dst_table;
7063     dst_table= table->schema_select_lex->table_list.first;
7064 
7065     DBUG_ASSERT(dst_table);
7066 
7067     /*
7068       Open temporary tables to be able to detect them during privilege check.
7069     */
7070     if (thd->open_temporary_tables(dst_table))
7071       return TRUE;
7072 
7073     if (check_access(thd, SELECT_ACL, dst_table->db.str,
7074                      &dst_table->grant.privilege,
7075                      &dst_table->grant.m_internal,
7076                      FALSE, FALSE))
7077           return TRUE; /* Access denied */
7078 
7079     /*
7080       Check_grant will grant access if there is any column privileges on
7081       all of the tables thanks to the fourth parameter (bool show_table).
7082     */
7083     if (check_grant(thd, SELECT_ACL, dst_table, TRUE, 1, FALSE))
7084       return TRUE; /* Access denied */
7085 
7086     close_thread_tables(thd);
7087     dst_table->table= NULL;
7088 
7089     /* Access granted */
7090     return FALSE;
7091   }
7092   default:
7093     break;
7094   }
7095 
7096   return FALSE;
7097 }
7098 
7099 
7100 
7101 /**
7102   @brief Check if the requested privileges exists in either User-, Host- or
7103     Db-tables.
7104   @param thd          Thread context
7105   @param want_access  Privileges requested
7106   @param tables       List of tables to be compared against
7107   @param no_errors    Don't report error to the client (using my_error() call).
7108   @param any_combination_of_privileges_will_do TRUE if any privileges on any
7109     column combination is enough.
7110   @param number       Only the first 'number' tables in the linked list are
7111                       relevant.
7112 
7113   The suppled table list contains cached privileges. This functions calls the
7114   help functions check_access and check_grant to verify the first three steps
7115   in the privileges check queue:
7116   1. Global privileges
7117   2. OR (db privileges AND host privileges)
7118   3. OR table privileges
7119   4. OR column privileges (not checked by this function!)
7120   5. OR routine privileges (not checked by this function!)
7121 
7122   @see check_access
7123   @see check_grant
7124 
7125   @note This functions assumes that table list used and
7126   thd->lex->query_tables_own_last value correspond to each other
7127   (the latter should be either 0 or point to next_global member
7128   of one of elements of this table list).
7129 
7130   @return
7131     @retval FALSE OK
7132     @retval TRUE  Access denied; But column or routine privileges might need to
7133       be checked also.
7134 */
7135 
7136 bool
check_table_access(THD * thd,privilege_t requirements,TABLE_LIST * tables,bool any_combination_of_privileges_will_do,uint number,bool no_errors)7137 check_table_access(THD *thd, privilege_t requirements, TABLE_LIST *tables,
7138 		   bool any_combination_of_privileges_will_do,
7139                    uint number, bool no_errors)
7140 {
7141   TABLE_LIST *org_tables= tables;
7142   TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table();
7143   uint i= 0;
7144   /*
7145     The check that first_not_own_table is not reached is for the case when
7146     the given table list refers to the list for prelocking (contains tables
7147     of other queries). For simple queries first_not_own_table is 0.
7148   */
7149   for (; i < number && tables != first_not_own_table && tables;
7150        tables= tables->next_global, i++)
7151   {
7152     TABLE_LIST *const table_ref= tables->correspondent_table ?
7153       tables->correspondent_table : tables;
7154     Switch_to_definer_security_ctx backup_ctx(thd, table_ref);
7155 
7156     privilege_t want_access(requirements);
7157 
7158     /*
7159        Register access for view underlying table.
7160        Remove SHOW_VIEW_ACL, because it will be checked during making view
7161      */
7162     table_ref->grant.orig_want_privilege= (want_access & ~SHOW_VIEW_ACL);
7163 
7164     if (table_ref->schema_table_reformed)
7165     {
7166       if (check_show_access(thd, table_ref))
7167         return 1;
7168       continue;
7169     }
7170 
7171     DBUG_PRINT("info", ("derived: %d  view: %d", table_ref->derived != 0,
7172                         table_ref->view != 0));
7173 
7174     if (table_ref->is_anonymous_derived_table())
7175       continue;
7176 
7177     if (table_ref->sequence)
7178     {
7179       /* We want to have either SELECT or INSERT rights to sequences depending
7180          on how they are accessed
7181       */
7182       want_access= ((table_ref->lock_type == TL_WRITE_ALLOW_WRITE) ?
7183                     INSERT_ACL : SELECT_ACL);
7184     }
7185 
7186     if (check_access(thd, want_access, table_ref->get_db_name(),
7187                      &table_ref->grant.privilege,
7188                      &table_ref->grant.m_internal,
7189                      0, no_errors))
7190       return 1;
7191   }
7192   return check_grant(thd,requirements,org_tables,
7193                      any_combination_of_privileges_will_do,
7194                      number, no_errors);
7195 }
7196 
7197 
7198 bool
check_routine_access(THD * thd,privilege_t want_access,const LEX_CSTRING * db,const LEX_CSTRING * name,const Sp_handler * sph,bool no_errors)7199 check_routine_access(THD *thd, privilege_t want_access, const LEX_CSTRING *db,
7200                      const LEX_CSTRING *name,
7201                      const Sp_handler *sph, bool no_errors)
7202 {
7203   TABLE_LIST tables[1];
7204 
7205   bzero((char *)tables, sizeof(TABLE_LIST));
7206   tables->db= *db;
7207   tables->table_name= tables->alias= *name;
7208 
7209   /*
7210     The following test is just a shortcut for check_access() (to avoid
7211     calculating db_access) under the assumption that it's common to
7212     give persons global right to execute all stored SP (but not
7213     necessary to create them).
7214     Note that this effectively bypasses the ACL_internal_schema_access checks
7215     that are implemented for the INFORMATION_SCHEMA and PERFORMANCE_SCHEMA,
7216     which are located in check_access().
7217     Since the I_S and P_S do not contain routines, this bypass is ok,
7218     as long as this code path is not abused to create routines.
7219     The assert enforce that.
7220   */
7221   DBUG_ASSERT((want_access & CREATE_PROC_ACL) == NO_ACL);
7222   if ((thd->security_ctx->master_access & want_access) == want_access)
7223     tables->grant.privilege= want_access;
7224   else if (check_access(thd, want_access, db->str,
7225                         &tables->grant.privilege,
7226                         &tables->grant.m_internal,
7227                         0, no_errors))
7228     return TRUE;
7229 
7230   return check_grant_routine(thd, want_access, tables, sph, no_errors);
7231 }
7232 
7233 
7234 /**
7235   Check if the routine has any of the routine privileges.
7236 
7237   @param thd	       Thread handler
7238   @param db           Database name
7239   @param name         Routine name
7240 
7241   @retval
7242     0            ok
7243   @retval
7244     1            error
7245 */
7246 
check_some_routine_access(THD * thd,const char * db,const char * name,const Sp_handler * sph)7247 bool check_some_routine_access(THD *thd, const char *db, const char *name,
7248                                const Sp_handler *sph)
7249 {
7250   privilege_t save_priv(NO_ACL);
7251   /*
7252     The following test is just a shortcut for check_access() (to avoid
7253     calculating db_access)
7254     Note that this effectively bypasses the ACL_internal_schema_access checks
7255     that are implemented for the INFORMATION_SCHEMA and PERFORMANCE_SCHEMA,
7256     which are located in check_access().
7257     Since the I_S and P_S do not contain routines, this bypass is ok,
7258     as it only opens SHOW_PROC_ACLS.
7259   */
7260   if (thd->security_ctx->master_access & SHOW_PROC_ACLS)
7261     return FALSE;
7262   if (!check_access(thd, SHOW_PROC_ACLS, db, &save_priv, NULL, 0, 1) ||
7263       (save_priv & SHOW_PROC_ACLS))
7264     return FALSE;
7265   return check_routine_level_acl(thd, db, name, sph);
7266 }
7267 
7268 
7269 /*
7270   Check if the given table has any of the asked privileges
7271 
7272   @param thd		 Thread handler
7273   @param want_access	 Bitmap of possible privileges to check for
7274 
7275   @retval
7276     0  ok
7277   @retval
7278     1  error
7279 */
7280 
check_some_access(THD * thd,privilege_t want_access,TABLE_LIST * table)7281 bool check_some_access(THD *thd, privilege_t want_access, TABLE_LIST *table)
7282 {
7283   DBUG_ENTER("check_some_access");
7284 
7285   for (ulonglong bit= 1; bit < (ulonglong) want_access ; bit<<= 1)
7286   {
7287     if (bit & want_access)
7288     {
7289       privilege_t access= ALL_KNOWN_ACL & bit;
7290       if (!check_access(thd, access, table->db.str,
7291                         &table->grant.privilege,
7292                         &table->grant.m_internal,
7293                         0, 1) &&
7294            !check_grant(thd, access, table, FALSE, 1, TRUE))
7295         DBUG_RETURN(0);
7296     }
7297   }
7298   DBUG_PRINT("exit",("no matching access rights"));
7299   DBUG_RETURN(1);
7300 }
7301 
7302 #endif /*NO_EMBEDDED_ACCESS_CHECKS*/
7303 
7304 
7305 /**
7306   check for global access and give descriptive error message if it fails.
7307 
7308   @param thd			Thread handler
7309   @param want_access		Use should have any of these global rights
7310 
7311   @warning
7312     Starting from 10.5.2 only one bit is allowed in want_access.
7313     Access denied error is returned if want_access has multiple bits set.
7314 
7315   @retval
7316     0	ok
7317   @retval
7318     1	Access denied.  In this case an error is sent to the client
7319 */
7320 
check_global_access(THD * thd,privilege_t want_access,bool no_errors)7321 bool check_global_access(THD *thd, privilege_t want_access, bool no_errors)
7322 {
7323 #ifndef NO_EMBEDDED_ACCESS_CHECKS
7324   char command[128];
7325   if (thd->security_ctx->master_access & want_access)
7326     return 0;
7327   if (unlikely(!no_errors))
7328   {
7329     get_privilege_desc(command, sizeof(command), want_access);
7330     my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command);
7331   }
7332   status_var_increment(thd->status_var.access_denied_errors);
7333   return 1;
7334 #else
7335   return 0;
7336 #endif
7337 }
7338 
7339 
7340 /**
7341   Checks foreign key's parent table access.
7342 
7343   @param thd	       [in]	Thread handler
7344   @param create_info   [in]     Create information (like MAX_ROWS, ENGINE or
7345                                 temporary table flag)
7346   @param alter_info    [in]     Initial list of columns and indexes for the
7347                                 table to be created
7348   @param create_db     [in]     Database of the created table
7349 
7350   @retval
7351    false  ok.
7352   @retval
7353    true	  error or access denied. Error is sent to client in this case.
7354 */
check_fk_parent_table_access(THD * thd,HA_CREATE_INFO * create_info,Alter_info * alter_info,const char * create_db)7355 bool check_fk_parent_table_access(THD *thd,
7356                                   HA_CREATE_INFO *create_info,
7357                                   Alter_info *alter_info,
7358                                   const char* create_db)
7359 {
7360   Key *key;
7361   List_iterator<Key> key_iterator(alter_info->key_list);
7362 
7363   while ((key= key_iterator++))
7364   {
7365     if (key->type == Key::FOREIGN_KEY)
7366     {
7367       TABLE_LIST parent_table;
7368       bool is_qualified_table_name;
7369       Foreign_key *fk_key= (Foreign_key *)key;
7370       LEX_CSTRING db_name;
7371       LEX_CSTRING table_name= { fk_key->ref_table.str,
7372                                fk_key->ref_table.length };
7373       const privilege_t privileges(COL_DML_ACLS | REFERENCES_ACL);
7374 
7375       // Check if tablename is valid or not.
7376       DBUG_ASSERT(table_name.str != NULL);
7377       if (check_table_name(table_name.str, table_name.length, false))
7378       {
7379         my_error(ER_WRONG_TABLE_NAME, MYF(0), table_name.str);
7380         return true;
7381       }
7382 
7383       if (fk_key->ref_db.str)
7384       {
7385         is_qualified_table_name= true;
7386         if (!(db_name.str= (char *) thd->memdup(fk_key->ref_db.str,
7387                                                 fk_key->ref_db.length+1)))
7388           return true;
7389         db_name.length= fk_key->ref_db.length;
7390 
7391         // Check if database name is valid or not.
7392         if (check_db_name((LEX_STRING*) &db_name))
7393         {
7394           my_error(ER_WRONG_DB_NAME, MYF(0), db_name.str);
7395           return true;
7396         }
7397       }
7398       else
7399       {
7400         if (!thd->db.str)
7401         {
7402           DBUG_ASSERT(create_db);
7403           db_name.length= strlen(create_db);
7404           if (!(db_name.str= (char *) thd->memdup(create_db,
7405                                                   db_name.length+1)))
7406             return true;
7407           is_qualified_table_name= true;
7408 
7409           if (check_db_name((LEX_STRING*) &db_name))
7410           {
7411             my_error(ER_WRONG_DB_NAME, MYF(0), db_name.str);
7412             return true;
7413           }
7414         }
7415         else
7416         {
7417           if (thd->lex->copy_db_to(&db_name))
7418             return true;
7419           else
7420            is_qualified_table_name= false;
7421         }
7422       }
7423 
7424       // if lower_case_table_names is set then convert tablename to lower case.
7425       if (lower_case_table_names)
7426       {
7427         char *name;
7428         table_name.str= name= (char *) thd->memdup(fk_key->ref_table.str,
7429                                                    fk_key->ref_table.length+1);
7430         table_name.length= my_casedn_str(files_charset_info, name);
7431         db_name.length= my_casedn_str(files_charset_info, (char*) db_name.str);
7432       }
7433 
7434       parent_table.init_one_table(&db_name, &table_name, 0, TL_IGNORE);
7435 
7436       /*
7437        Check if user has any of the "privileges" at table level on
7438        "parent_table".
7439        Having privilege on any of the parent_table column is not
7440        enough so checking whether user has any of the "privileges"
7441        at table level only here.
7442       */
7443       if (check_some_access(thd, privileges, &parent_table) ||
7444           parent_table.grant.want_privilege)
7445       {
7446         if (is_qualified_table_name)
7447         {
7448           const size_t qualified_table_name_len= NAME_LEN + 1 + NAME_LEN + 1;
7449           char *qualified_table_name= (char *) thd->alloc(qualified_table_name_len);
7450 
7451           my_snprintf(qualified_table_name, qualified_table_name_len, "%s.%s",
7452                       db_name.str, table_name.str);
7453           table_name.str= qualified_table_name;
7454         }
7455 
7456         my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
7457                  "REFERENCES",
7458                  thd->security_ctx->priv_user,
7459                  thd->security_ctx->host_or_ip,
7460                  table_name.str);
7461 
7462         return true;
7463       }
7464     }
7465   }
7466 
7467   return false;
7468 }
7469 
7470 
7471 /****************************************************************************
7472 	Check stack size; Send error if there isn't enough stack to continue
7473 ****************************************************************************/
7474 
7475 
7476 #ifndef DBUG_OFF
7477 long max_stack_used;
7478 #endif
7479 
7480 /**
7481   @note
7482   Note: The 'buf' parameter is necessary, even if it is unused here.
7483   - fix_fields functions has a "dummy" buffer large enough for the
7484     corresponding exec. (Thus we only have to check in fix_fields.)
7485   - Passing to check_stack_overrun() prevents the compiler from removing it.
7486 */
7487 
7488 bool
7489 #if defined __GNUC__ && !defined __clang__
7490 /*
7491   Do not optimize the function in order to preserve a stack variable creation.
7492   Otherwise, the variable pointed as "buf" can be removed due to a missing
7493   usage.
7494  */
7495 __attribute__((optimize("-O0")))
7496 #endif
check_stack_overrun(THD * thd,long margin,uchar * buf)7497 check_stack_overrun(THD *thd, long margin, uchar *buf __attribute__((unused)))
7498 {
7499   long stack_used;
7500   DBUG_ASSERT(thd == current_thd);
7501   if ((stack_used= available_stack_size(thd->thread_stack, &stack_used)) >=
7502       (long) (my_thread_stack_size - margin))
7503   {
7504     thd->is_fatal_error= 1;
7505     /*
7506       Do not use stack for the message buffer to ensure correct
7507       behaviour in cases we have close to no stack left.
7508     */
7509     char* ebuff= new char[MYSQL_ERRMSG_SIZE];
7510     if (ebuff) {
7511       my_snprintf(ebuff, MYSQL_ERRMSG_SIZE, ER_THD(thd, ER_STACK_OVERRUN_NEED_MORE),
7512                   stack_used, my_thread_stack_size, margin);
7513       my_message(ER_STACK_OVERRUN_NEED_MORE, ebuff, MYF(ME_FATAL));
7514       delete [] ebuff;
7515     }
7516     return 1;
7517   }
7518 #ifndef DBUG_OFF
7519   max_stack_used= MY_MAX(max_stack_used, stack_used);
7520 #endif
7521   return 0;
7522 }
7523 
7524 
7525 #define MY_YACC_INIT 1000			// Start with big alloc
7526 #define MY_YACC_MAX  32000			// Because of 'short'
7527 
my_yyoverflow(short ** yyss,YYSTYPE ** yyvs,size_t * yystacksize)7528 bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, size_t *yystacksize)
7529 {
7530   Yacc_state *state= & current_thd->m_parser_state->m_yacc;
7531   size_t old_info=0;
7532   DBUG_ASSERT(state);
7533   if ( *yystacksize >= MY_YACC_MAX)
7534     return 1;
7535   if (!state->yacc_yyvs)
7536     old_info= *yystacksize;
7537   *yystacksize= set_zone((int)(*yystacksize)*2,MY_YACC_INIT,MY_YACC_MAX);
7538   if (!(state->yacc_yyvs= (uchar*)
7539         my_realloc(key_memory_bison_stack, state->yacc_yyvs,
7540                    *yystacksize*sizeof(**yyvs),
7541                    MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))) ||
7542       !(state->yacc_yyss= (uchar*)
7543         my_realloc(key_memory_bison_stack, state->yacc_yyss,
7544                    *yystacksize*sizeof(**yyss),
7545                    MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))))
7546     return 1;
7547   if (old_info)
7548   {
7549     /*
7550       Only copy the old stack on the first call to my_yyoverflow(),
7551       when replacing a static stack (YYINITDEPTH) by a dynamic stack.
7552       For subsequent calls, my_realloc already did preserve the old stack.
7553     */
7554     memcpy(state->yacc_yyss, *yyss, old_info*sizeof(**yyss));
7555     memcpy(state->yacc_yyvs, *yyvs, old_info*sizeof(**yyvs));
7556   }
7557   *yyss= (short*) state->yacc_yyss;
7558   *yyvs= (YYSTYPE*) state->yacc_yyvs;
7559   return 0;
7560 }
7561 
7562 
7563 /**
7564   Reset the part of THD responsible for the state of command
7565   processing.
7566 
7567   @param do_clear_error  Set if we should clear errors
7568 
7569   This needs to be called before execution of every statement
7570   (prepared or conventional).  It is not called by substatements of
7571   routines.
7572 
7573   @todo Call it after we use THD for queries, not before.
7574 */
7575 
reset_for_next_command(bool do_clear_error)7576 void THD::reset_for_next_command(bool do_clear_error)
7577 {
7578   DBUG_ENTER("THD::reset_for_next_command");
7579   DBUG_ASSERT(!spcont); /* not for substatements of routines */
7580   DBUG_ASSERT(!in_sub_stmt);
7581   /*
7582     Table maps should have been reset after previous statement except in the
7583     case where we have locked tables
7584   */
7585   DBUG_ASSERT(binlog_table_maps == 0 ||
7586               locked_tables_mode == LTM_LOCK_TABLES);
7587 
7588   if (likely(do_clear_error))
7589   {
7590     clear_error(1);
7591     /*
7592       The following variable can't be reset in clear_error() as
7593       clear_error() is called during auto_repair of table
7594     */
7595     error_printed_to_log= 0;
7596   }
7597   free_list= 0;
7598   /*
7599     We also assign stmt_lex in lex_start(), but during bootstrap this
7600     code is executed first.
7601   */
7602   DBUG_ASSERT(lex == &main_lex);
7603   main_lex.stmt_lex= &main_lex; main_lex.current_select_number= 0;
7604   /*
7605     Those two lines below are theoretically unneeded as
7606     THD::cleanup_after_query() should take care of this already.
7607   */
7608   auto_inc_intervals_in_cur_stmt_for_binlog.empty();
7609   stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
7610 
7611 #ifdef WITH_WSREP
7612   /*
7613     Autoinc variables should be adjusted only for locally executed
7614     transactions. Appliers and replayers are either processing ROW
7615     events or get autoinc variable values from Query_log_event and
7616     mysql slave may be processing STATEMENT format events, but he should
7617     use autoinc values passed in binlog events, not the values forced by
7618     the cluster.
7619   */
7620   if (WSREP_NNULL(this) && wsrep_thd_is_local(this) &&
7621       !slave_thread && wsrep_auto_increment_control)
7622   {
7623     variables.auto_increment_offset=
7624       global_system_variables.auto_increment_offset;
7625     variables.auto_increment_increment=
7626       global_system_variables.auto_increment_increment;
7627   }
7628 #endif /* WITH_WSREP */
7629   query_start_sec_part_used= 0;
7630   is_fatal_error= time_zone_used= 0;
7631   log_current_statement= 0;
7632 
7633   /*
7634     Clear the status flag that are expected to be cleared at the
7635     beginning of each SQL statement.
7636   */
7637   server_status&= ~SERVER_STATUS_CLEAR_SET;
7638   /*
7639     If in autocommit mode and not in a transaction, reset
7640     OPTION_STATUS_NO_TRANS_UPDATE | OPTION_KEEP_LOG to not get warnings
7641     in ha_rollback_trans() about some tables couldn't be rolled back.
7642   */
7643   if (!in_multi_stmt_transaction_mode())
7644   {
7645     variables.option_bits&= ~OPTION_KEEP_LOG;
7646     transaction->all.reset();
7647   }
7648   DBUG_ASSERT(security_ctx== &main_security_ctx);
7649   thread_specific_used= FALSE;
7650 
7651   if (opt_bin_log)
7652     reset_dynamic(&user_var_events);
7653   DBUG_ASSERT(user_var_events_alloc == &main_mem_root);
7654   enable_slow_log= true;
7655   get_stmt_da()->reset_for_next_command();
7656   rand_used= 0;
7657   m_sent_row_count= m_examined_row_count= 0;
7658   accessed_rows_and_keys= 0;
7659 
7660   reset_slow_query_state();
7661 
7662   reset_current_stmt_binlog_format_row();
7663   binlog_unsafe_warning_flags= 0;
7664 
7665   save_prep_leaf_list= false;
7666 
7667 #ifdef WITH_WSREP
7668 #if !defined(DBUG_OFF)
7669   if (mysql_bin_log.is_open())
7670 #endif
7671 #endif
7672     DBUG_PRINT("debug",
7673                ("is_current_stmt_binlog_format_row(): %d",
7674                  is_current_stmt_binlog_format_row()));
7675 
7676   DBUG_VOID_RETURN;
7677 }
7678 
7679 
7680 /**
7681   Resets the lex->current_select object.
7682   @note It is assumed that lex->current_select != NULL
7683 
7684   This function is a wrapper around select_lex->init_select() with an added
7685   check for the special situation when using INTO OUTFILE and LOAD DATA.
7686 */
7687 
7688 void
mysql_init_select(LEX * lex)7689 mysql_init_select(LEX *lex)
7690 {
7691   lex->init_select();
7692 }
7693 
7694 
7695 /**
7696   Used to allocate a new SELECT_LEX object on the current thd mem_root and
7697   link it into the relevant lists.
7698 
7699   This function is always followed by mysql_init_select.
7700 
7701   @see mysql_init_select
7702 
7703   @retval TRUE An error occurred
7704   @retval FALSE The new SELECT_LEX was successfully allocated.
7705 */
7706 
7707 bool
mysql_new_select(LEX * lex,bool move_down,SELECT_LEX * select_lex)7708 mysql_new_select(LEX *lex, bool move_down, SELECT_LEX *select_lex)
7709 {
7710   THD *thd= lex->thd;
7711   bool new_select= select_lex == NULL;
7712   int old_nest_level= lex->current_select->nest_level;
7713   DBUG_ENTER("mysql_new_select");
7714 
7715   if (new_select)
7716   {
7717     if (!(select_lex= new (thd->mem_root) SELECT_LEX()))
7718       DBUG_RETURN(1);
7719     select_lex->select_number= ++thd->lex->stmt_lex->current_select_number;
7720     select_lex->parent_lex= lex; /* Used in init_query. */
7721     select_lex->init_query();
7722     select_lex->init_select();
7723   }
7724   select_lex->nest_level_base= &thd->lex->unit;
7725   if (move_down)
7726   {
7727     lex->nest_level++;
7728     if (select_lex->set_nest_level(old_nest_level + 1))
7729       DBUG_RETURN(1);
7730     SELECT_LEX_UNIT *unit;
7731     /* first select_lex of subselect or derived table */
7732     if (!(unit= lex->alloc_unit()))
7733       DBUG_RETURN(1);
7734 
7735     unit->include_down(lex->current_select);
7736     unit->return_to= lex->current_select;
7737     select_lex->include_down(unit);
7738     /*
7739       By default we assume that it is usual subselect and we have outer name
7740       resolution context, if no we will assign it to 0 later
7741     */
7742     select_lex->context.outer_context= &select_lex->outer_select()->context;
7743   }
7744   else
7745   {
7746     bool const outer_most= (lex->current_select->master_unit() == &lex->unit);
7747     if (outer_most && lex->result)
7748     {
7749       my_error(ER_WRONG_USAGE, MYF(0), "UNION", "INTO");
7750       DBUG_RETURN(TRUE);
7751     }
7752 
7753     /*
7754       This type of query is not possible in the grammar:
7755         SELECT 1 FROM t1 PROCEDURE ANALYSE() UNION ... ;
7756 
7757       But this type of query is still possible:
7758         (SELECT 1 FROM t1 PROCEDURE ANALYSE()) UNION ... ;
7759       and it's not easy to disallow this grammatically,
7760       because there can be any parenthesis nest level:
7761         (((SELECT 1 FROM t1 PROCEDURE ANALYSE()))) UNION ... ;
7762     */
7763     if (lex->proc_list.elements!=0)
7764     {
7765       my_error(ER_WRONG_USAGE, MYF(0), "UNION",
7766                "SELECT ... PROCEDURE ANALYSE()");
7767       DBUG_RETURN(TRUE);
7768     }
7769 
7770     SELECT_LEX_NODE *save_slave= select_lex->slave;
7771     select_lex->include_neighbour(lex->current_select);
7772     select_lex->slave= save_slave;
7773     SELECT_LEX_UNIT *unit= select_lex->master_unit();
7774     if (select_lex->set_nest_level(old_nest_level))
7775       DBUG_RETURN(1);
7776     if (!unit->fake_select_lex && unit->add_fake_select_lex(lex->thd))
7777       DBUG_RETURN(1);
7778     select_lex->context.outer_context=
7779                 unit->first_select()->context.outer_context;
7780   }
7781 
7782   if (new_select)
7783     select_lex->include_global((st_select_lex_node**)&lex->all_selects_list);
7784   lex->current_select= select_lex;
7785   /*
7786     in subquery is SELECT query and we allow resolution of names in SELECT
7787     list
7788   */
7789   select_lex->context.resolve_in_select_list= TRUE;
7790   DBUG_RETURN(0);
7791 }
7792 
7793 /**
7794   Create a select to return the same output as 'SELECT @@var_name'.
7795 
7796   Used for SHOW COUNT(*) [ WARNINGS | ERROR].
7797 
7798   This will crash with a core dump if the variable doesn't exists.
7799 
7800   @param var_name		Variable name
7801 */
7802 
create_select_for_variable(THD * thd,LEX_CSTRING * var_name)7803 void create_select_for_variable(THD *thd, LEX_CSTRING *var_name)
7804 {
7805   LEX *lex;
7806   Item *var;
7807   char buff[MAX_SYS_VAR_LENGTH*2+4+8], *end;
7808   DBUG_ENTER("create_select_for_variable");
7809 
7810   lex= thd->lex;
7811   mysql_init_select(lex);
7812   lex->sql_command= SQLCOM_SELECT;
7813   /*
7814     We set the name of Item to @@session.var_name because that then is used
7815     as the column name in the output.
7816   */
7817   if ((var= get_system_var(thd, OPT_SESSION, var_name, &null_clex_str)))
7818   {
7819     end= strxmov(buff, "@@session.", var_name->str, NullS);
7820     var->set_name(thd, buff, (uint)(end-buff), system_charset_info);
7821     add_item_to_list(thd, var);
7822   }
7823   DBUG_VOID_RETURN;
7824 }
7825 
7826 
mysql_init_multi_delete(LEX * lex)7827 void mysql_init_multi_delete(LEX *lex)
7828 {
7829   lex->sql_command=  SQLCOM_DELETE_MULTI;
7830   mysql_init_select(lex);
7831   lex->first_select_lex()->select_limit= 0;
7832   lex->unit.lim.set_unlimited();
7833   lex->first_select_lex()->table_list.
7834     save_and_clear(&lex->auxiliary_table_list);
7835   lex->query_tables= 0;
7836   lex->query_tables_last= &lex->query_tables;
7837 }
7838 
7839 #ifdef WITH_WSREP
wsrep_prepare_for_autocommit_retry(THD * thd,char * rawbuf,uint length,Parser_state * parser_state)7840 static void wsrep_prepare_for_autocommit_retry(THD* thd,
7841                                                char* rawbuf,
7842                                                uint length,
7843                                                Parser_state* parser_state)
7844 {
7845   thd->clear_error();
7846   close_thread_tables(thd);
7847   thd->wsrep_retry_counter++;            // grow
7848   wsrep_copy_query(thd);
7849   thd->set_time();
7850   parser_state->reset(rawbuf, length);
7851 
7852   /* PSI end */
7853   MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
7854   thd->m_statement_psi= NULL;
7855   thd->m_digest= NULL;
7856 
7857   /* DTRACE end */
7858   if (MYSQL_QUERY_DONE_ENABLED())
7859   {
7860     MYSQL_QUERY_DONE(thd->is_error());
7861   }
7862 
7863   /* SHOW PROFILE end */
7864 #if defined(ENABLED_PROFILING)
7865   thd->profiling.finish_current_query();
7866 #endif
7867 
7868   /* SHOW PROFILE begin */
7869 #if defined(ENABLED_PROFILING)
7870   thd->profiling.start_new_query("continuing");
7871   thd->profiling.set_query_source(rawbuf, length);
7872 #endif
7873 
7874   /* DTRACE begin */
7875   MYSQL_QUERY_START(rawbuf, thd->thread_id,
7876                     thd->get_db(),
7877                     &thd->security_ctx->priv_user[0],
7878                     (char *) thd->security_ctx->host_or_ip);
7879 
7880   /* Performance Schema Interface instrumentation, begin */
7881   thd->m_statement_psi= MYSQL_REFINE_STATEMENT(thd->m_statement_psi,
7882                                                com_statement_info[thd->get_command()].m_key);
7883   MYSQL_SET_STATEMENT_TEXT(thd->m_statement_psi, thd->query(),
7884                            thd->query_length());
7885 
7886   DBUG_ASSERT(thd->wsrep_trx().active() == false);
7887   thd->wsrep_cs().reset_error();
7888   thd->set_query_id(next_query_id());
7889 }
7890 
wsrep_mysql_parse(THD * thd,char * rawbuf,uint length,Parser_state * parser_state,bool is_com_multi,bool is_next_command)7891 static bool wsrep_mysql_parse(THD *thd, char *rawbuf, uint length,
7892                               Parser_state *parser_state,
7893                               bool is_com_multi,
7894                               bool is_next_command)
7895 {
7896   bool is_autocommit=
7897     !thd->in_multi_stmt_transaction_mode()                  &&
7898     wsrep_read_only_option(thd, thd->lex->query_tables);
7899   bool retry_autocommit;
7900   do
7901   {
7902     retry_autocommit= false;
7903     mysql_parse(thd, rawbuf, length, parser_state, is_com_multi, is_next_command);
7904 
7905     /*
7906       Convert all ER_QUERY_INTERRUPTED errors to ER_LOCK_DEADLOCK
7907       if the transaction was BF aborted. This can happen when the
7908       transaction is being BF aborted via thd->awake() while it is
7909       still executing.
7910 
7911       Note that this must be done before wsrep_after_statement() call
7912       since it clears the transaction for autocommit queries.
7913      */
7914     if (((thd->get_stmt_da()->is_error() &&
7915           thd->get_stmt_da()->sql_errno() == ER_QUERY_INTERRUPTED) ||
7916          !thd->get_stmt_da()->is_set()) &&
7917         thd->wsrep_trx().bf_aborted())
7918     {
7919       WSREP_DEBUG("overriding error: %d with DEADLOCK",
7920                   (thd->get_stmt_da()->is_error()) ?
7921                    thd->get_stmt_da()->sql_errno() : 0);
7922 
7923       thd->reset_kill_query();
7924       wsrep_override_error(thd, ER_LOCK_DEADLOCK);
7925     }
7926 
7927 #ifdef ENABLED_DEBUG_SYNC
7928     /* we need the test otherwise we get stuck in the "SET DEBUG_SYNC" itself */
7929     if (thd->lex->sql_command != SQLCOM_SET_OPTION)
7930       DEBUG_SYNC(thd, "wsrep_after_statement_enter");
7931 #endif
7932 
7933     if (wsrep_after_statement(thd) &&
7934         is_autocommit              &&
7935         thd_is_connection_alive(thd))
7936     {
7937       thd->reset_for_next_command();
7938       thd->reset_kill_query();
7939       if (is_autocommit                           &&
7940           thd->lex->sql_command != SQLCOM_SELECT  &&
7941           thd->wsrep_retry_counter < thd->variables.wsrep_retry_autocommit)
7942       {
7943 	DBUG_EXECUTE_IF("sync.wsrep_retry_autocommit",
7944                     {
7945                       const char act[]=
7946                         "now "
7947                         "SIGNAL wsrep_retry_autocommit_reached "
7948                         "WAIT_FOR wsrep_retry_autocommit_continue";
7949                       DBUG_ASSERT(!debug_sync_set_action(thd, STRING_WITH_LEN(act)));
7950                     });
7951         WSREP_DEBUG("wsrep retrying AC query: %lu  %s",
7952                     thd->wsrep_retry_counter, wsrep_thd_query(thd));
7953         wsrep_prepare_for_autocommit_retry(thd, rawbuf, length, parser_state);
7954         if (thd->lex->explain)
7955           delete_explain_query(thd->lex);
7956         retry_autocommit= true;
7957       }
7958       else
7959       {
7960         WSREP_DEBUG("%s, thd: %llu is_AC: %d, retry: %lu - %lu SQL: %s",
7961                     wsrep_thd_transaction_state_str(thd),
7962                     thd->thread_id,
7963                     is_autocommit,
7964                     thd->wsrep_retry_counter,
7965                     thd->variables.wsrep_retry_autocommit,
7966                     wsrep_thd_query(thd));
7967         my_error(ER_LOCK_DEADLOCK, MYF(0));
7968         thd->reset_kill_query();
7969         thd->wsrep_retry_counter= 0;             //  reset
7970       }
7971     }
7972     else
7973     {
7974       set_if_smaller(thd->wsrep_retry_counter, 0); // reset; eventually ok
7975     }
7976   }  while (retry_autocommit);
7977 
7978   if (thd->wsrep_retry_query)
7979   {
7980     WSREP_DEBUG("releasing retry_query: "
7981                 "conf %s sent %d kill %d  errno %d SQL %s",
7982                 wsrep_thd_transaction_state_str(thd),
7983                 thd->get_stmt_da()->is_sent(),
7984                 thd->killed,
7985                 thd->get_stmt_da()->is_error() ?
7986                 thd->get_stmt_da()->sql_errno() : 0,
7987                 thd->wsrep_retry_query);
7988     my_free(thd->wsrep_retry_query);
7989     thd->wsrep_retry_query      = NULL;
7990     thd->wsrep_retry_query_len  = 0;
7991     thd->wsrep_retry_command    = COM_CONNECT;
7992   }
7993   return false;
7994 }
7995 #endif /* WITH_WSREP */
7996 
7997 
7998 /*
7999   When you modify mysql_parse(), you may need to modify
8000   mysql_test_parse_for_slave() in this same file.
8001 */
8002 
8003 /**
8004   Parse a query.
8005 
8006   @param       thd     Current thread
8007   @param       rawbuf  Begining of the query text
8008   @param       length  Length of the query text
8009   @param[out]  found_semicolon For multi queries, position of the character of
8010                                the next query in the query text.
8011   @param is_next_command there will be more command in the COM_MULTI batch
8012 */
8013 
mysql_parse(THD * thd,char * rawbuf,uint length,Parser_state * parser_state,bool is_com_multi,bool is_next_command)8014 void mysql_parse(THD *thd, char *rawbuf, uint length,
8015                  Parser_state *parser_state,
8016                  bool is_com_multi,
8017                  bool is_next_command)
8018 {
8019   DBUG_ENTER("mysql_parse");
8020   DBUG_EXECUTE_IF("parser_debug", turn_parser_debug_on_MYSQLparse(););
8021   DBUG_EXECUTE_IF("parser_debug", turn_parser_debug_on_ORAparse(););
8022 
8023   /*
8024     Warning.
8025     The purpose of query_cache_send_result_to_client() is to lookup the
8026     query in the query cache first, to avoid parsing and executing it.
8027     So, the natural implementation would be to:
8028     - first, call query_cache_send_result_to_client,
8029     - second, if caching failed, initialise the lexical and syntactic parser.
8030     The problem is that the query cache depends on a clean initialization
8031     of (among others) lex->safe_to_cache_query and thd->server_status,
8032     which are reset respectively in
8033     - lex_start()
8034     - THD::reset_for_next_command()
8035     So, initializing the lexical analyser *before* using the query cache
8036     is required for the cache to work properly.
8037     FIXME: cleanup the dependencies in the code to simplify this.
8038   */
8039   lex_start(thd);
8040   thd->reset_for_next_command();
8041   if (is_next_command)
8042   {
8043     thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
8044     if (is_com_multi)
8045       thd->get_stmt_da()->set_skip_flush();
8046   }
8047 
8048   if (query_cache_send_result_to_client(thd, rawbuf, length) <= 0)
8049   {
8050     LEX *lex= thd->lex;
8051 
8052     bool err= parse_sql(thd, parser_state, NULL, true);
8053 
8054     if (likely(!err))
8055     {
8056       thd->m_statement_psi=
8057         MYSQL_REFINE_STATEMENT(thd->m_statement_psi,
8058                                sql_statement_info[thd->lex->sql_command].
8059                                m_key);
8060 #ifndef NO_EMBEDDED_ACCESS_CHECKS
8061       if (mqh_used && thd->user_connect &&
8062 	  check_mqh(thd, lex->sql_command))
8063       {
8064 	thd->net.error = 0;
8065       }
8066       else
8067 #endif
8068       {
8069 	if (likely(! thd->is_error()))
8070 	{
8071           const char *found_semicolon= parser_state->m_lip.found_semicolon;
8072           /*
8073             Binlog logs a string starting from thd->query and having length
8074             thd->query_length; so we set thd->query_length correctly (to not
8075             log several statements in one event, when we executed only first).
8076             We set it to not see the ';' (otherwise it would get into binlog
8077             and Query_log_event::print() would give ';;' output).
8078             This also helps display only the current query in SHOW
8079             PROCESSLIST.
8080           */
8081           if (found_semicolon && (ulong) (found_semicolon - thd->query()))
8082             thd->set_query(thd->query(),
8083                            (uint32) (found_semicolon - thd->query() - 1),
8084                            thd->charset());
8085           /* Actually execute the query */
8086           if (found_semicolon)
8087           {
8088             lex->safe_to_cache_query= 0;
8089             thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
8090           }
8091           lex->set_trg_event_type_for_tables();
8092           MYSQL_QUERY_EXEC_START(thd->query(),
8093                                  thd->thread_id,
8094                                  thd->get_db(),
8095                                  &thd->security_ctx->priv_user[0],
8096                                  (char *) thd->security_ctx->host_or_ip,
8097                                  0);
8098 
8099           int error __attribute__((unused));
8100           error= mysql_execute_command(thd);
8101           MYSQL_QUERY_EXEC_DONE(error);
8102 	}
8103       }
8104     }
8105     else
8106     {
8107       /* Instrument this broken statement as "statement/sql/error" */
8108       thd->m_statement_psi=
8109         MYSQL_REFINE_STATEMENT(thd->m_statement_psi,
8110                                sql_statement_info[SQLCOM_END].m_key);
8111       DBUG_ASSERT(thd->is_error());
8112       DBUG_PRINT("info",("Command aborted. Fatal_error: %d",
8113 			 thd->is_fatal_error));
8114 
8115       query_cache_abort(thd, &thd->query_cache_tls);
8116     }
8117     THD_STAGE_INFO(thd, stage_freeing_items);
8118     sp_cache_enforce_limit(thd->sp_proc_cache, stored_program_cache_size);
8119     sp_cache_enforce_limit(thd->sp_func_cache, stored_program_cache_size);
8120     sp_cache_enforce_limit(thd->sp_package_spec_cache, stored_program_cache_size);
8121     sp_cache_enforce_limit(thd->sp_package_body_cache, stored_program_cache_size);
8122     thd->end_statement();
8123     thd->Item_change_list::rollback_item_tree_changes();
8124     thd->cleanup_after_query();
8125   }
8126   else
8127   {
8128     /* Update statistics for getting the query from the cache */
8129     thd->lex->sql_command= SQLCOM_SELECT;
8130     thd->m_statement_psi=
8131       MYSQL_REFINE_STATEMENT(thd->m_statement_psi,
8132                              sql_statement_info[SQLCOM_SELECT].m_key);
8133     status_var_increment(thd->status_var.com_stat[SQLCOM_SELECT]);
8134     thd->update_stats();
8135 #ifdef WITH_WSREP
8136     if (WSREP_CLIENT(thd))
8137     {
8138       thd->wsrep_sync_wait_gtid= WSREP_GTID_UNDEFINED;
8139     }
8140 #endif /* WITH_WSREP */
8141   }
8142   DBUG_VOID_RETURN;
8143 }
8144 
8145 
8146 #ifdef HAVE_REPLICATION
8147 /*
8148   Usable by the replication SQL thread only: just parse a query to know if it
8149   can be ignored because of replicate-*-table rules.
8150 
8151   @retval
8152     0	cannot be ignored
8153   @retval
8154     1	can be ignored
8155 */
8156 
mysql_test_parse_for_slave(THD * thd,char * rawbuf,uint length)8157 bool mysql_test_parse_for_slave(THD *thd, char *rawbuf, uint length)
8158 {
8159   LEX *lex= thd->lex;
8160   bool error= 0;
8161   DBUG_ENTER("mysql_test_parse_for_slave");
8162 
8163   Parser_state parser_state;
8164   if (likely(!(error= parser_state.init(thd, rawbuf, length))))
8165   {
8166     lex_start(thd);
8167     thd->reset_for_next_command();
8168 
8169     if (!parse_sql(thd, & parser_state, NULL, true) &&
8170         all_tables_not_ok(thd, lex->first_select_lex()->table_list.first))
8171       error= 1;                  /* Ignore question */
8172     thd->end_statement();
8173   }
8174   thd->cleanup_after_query();
8175   DBUG_RETURN(error);
8176 }
8177 #endif
8178 
8179 
8180 bool
add_proc_to_list(THD * thd,Item * item)8181 add_proc_to_list(THD* thd, Item *item)
8182 {
8183   ORDER *order;
8184   Item	**item_ptr;
8185 
8186   if (unlikely(!(order = (ORDER *) thd->alloc(sizeof(ORDER)+sizeof(Item*)))))
8187     return 1;
8188   item_ptr = (Item**) (order+1);
8189   *item_ptr= item;
8190   order->item=item_ptr;
8191   thd->lex->proc_list.link_in_list(order, &order->next);
8192   return 0;
8193 }
8194 
8195 
8196 /**
8197   save order by and tables in own lists.
8198 */
8199 
add_to_list(THD * thd,SQL_I_List<ORDER> & list,Item * item,bool asc)8200 bool add_to_list(THD *thd, SQL_I_List<ORDER> &list, Item *item,bool asc)
8201 {
8202   ORDER *order;
8203   DBUG_ENTER("add_to_list");
8204   if (unlikely(!(order = (ORDER *) thd->alloc(sizeof(ORDER)))))
8205     DBUG_RETURN(1);
8206   order->item_ptr= item;
8207   order->item= &order->item_ptr;
8208   order->direction= (asc ? ORDER::ORDER_ASC : ORDER::ORDER_DESC);
8209   order->used=0;
8210   order->counter_used= 0;
8211   order->fast_field_copier_setup= 0;
8212   list.link_in_list(order, &order->next);
8213   DBUG_RETURN(0);
8214 }
8215 
8216 
8217 /**
8218   Add a table to list of used tables.
8219 
8220   @param table		Table to add
8221   @param alias		alias for table (or null if no alias)
8222   @param table_options	A set of the following bits:
8223                          - TL_OPTION_UPDATING : Table will be updated
8224                          - TL_OPTION_FORCE_INDEX : Force usage of index
8225                          - TL_OPTION_ALIAS : an alias in multi table DELETE
8226   @param lock_type	How table should be locked
8227   @param mdl_type       Type of metadata lock to acquire on the table.
8228   @param use_index	List of indexed used in USE INDEX
8229   @param ignore_index	List of indexed used in IGNORE INDEX
8230 
8231   @retval
8232       0		Error
8233   @retval
8234     \#	Pointer to TABLE_LIST element added to the total table list
8235 */
8236 
add_table_to_list(THD * thd,Table_ident * table,LEX_CSTRING * alias,ulong table_options,thr_lock_type lock_type,enum_mdl_type mdl_type,List<Index_hint> * index_hints_arg,List<String> * partition_names,LEX_STRING * option)8237 TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
8238 					     Table_ident *table,
8239 					     LEX_CSTRING *alias,
8240 					     ulong table_options,
8241 					     thr_lock_type lock_type,
8242 					     enum_mdl_type mdl_type,
8243 					     List<Index_hint> *index_hints_arg,
8244                                              List<String> *partition_names,
8245                                              LEX_STRING *option)
8246 {
8247   TABLE_LIST *ptr;
8248   TABLE_LIST *UNINIT_VAR(previous_table_ref); /* The table preceding the current one. */
8249   LEX_CSTRING alias_str;
8250   LEX *lex= thd->lex;
8251   DBUG_ENTER("add_table_to_list");
8252   DBUG_PRINT("enter", ("Table '%s' (%p)  Select %p (%u)",
8253                         (alias ? alias->str : table->table.str),
8254                         table,
8255                         this, select_number));
8256   DBUG_ASSERT(!is_service_select  || (table_options & TL_OPTION_SEQUENCE));
8257 
8258   if (unlikely(!table))
8259     DBUG_RETURN(0);				// End of memory
8260   alias_str= alias ? *alias : table->table;
8261   DBUG_ASSERT(alias_str.str);
8262   if (!MY_TEST(table_options & TL_OPTION_ALIAS) &&
8263       unlikely(check_table_name(table->table.str, table->table.length, FALSE)))
8264   {
8265     my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
8266     DBUG_RETURN(0);
8267   }
8268 
8269   if (unlikely(table->is_derived_table() == FALSE && table->db.str &&
8270                check_db_name((LEX_STRING*) &table->db)))
8271   {
8272     my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str);
8273     DBUG_RETURN(0);
8274   }
8275 
8276   if (!alias)                            /* Alias is case sensitive */
8277   {
8278     if (unlikely(table->sel))
8279     {
8280       my_message(ER_DERIVED_MUST_HAVE_ALIAS,
8281                  ER_THD(thd, ER_DERIVED_MUST_HAVE_ALIAS), MYF(0));
8282       DBUG_RETURN(0);
8283     }
8284     /* alias_str points to table->table;  Let's make a copy */
8285     if (unlikely(!(alias_str.str= (char*) thd->memdup(alias_str.str, alias_str.length+1))))
8286       DBUG_RETURN(0);
8287   }
8288   if (unlikely(!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST)))))
8289     DBUG_RETURN(0);				/* purecov: inspected */
8290   if (table->db.str)
8291   {
8292     ptr->is_fqtn= TRUE;
8293     ptr->db= table->db;
8294   }
8295   else if (!lex->with_cte_resolution && lex->copy_db_to(&ptr->db))
8296     DBUG_RETURN(0);
8297   else
8298     ptr->is_fqtn= FALSE;
8299 
8300   ptr->alias= alias_str;
8301   ptr->is_alias= alias ? TRUE : FALSE;
8302   if (lower_case_table_names)
8303   {
8304     if (table->table.length)
8305       table->table.length= my_casedn_str(files_charset_info,
8306                                          (char*) table->table.str);
8307     if (ptr->db.length && ptr->db.str != any_db)
8308       ptr->db.length= my_casedn_str(files_charset_info, (char*) ptr->db.str);
8309   }
8310 
8311   ptr->table_name= table->table;
8312   ptr->lock_type= lock_type;
8313   ptr->mdl_type= mdl_type;
8314   ptr->table_options= table_options;
8315   ptr->updating=    MY_TEST(table_options & TL_OPTION_UPDATING);
8316   /* TODO: remove TL_OPTION_FORCE_INDEX as it looks like it's not used */
8317   ptr->force_index= MY_TEST(table_options & TL_OPTION_FORCE_INDEX);
8318   ptr->ignore_leaves= MY_TEST(table_options & TL_OPTION_IGNORE_LEAVES);
8319   ptr->sequence=      MY_TEST(table_options & TL_OPTION_SEQUENCE);
8320   ptr->derived=	    table->sel;
8321   if (!ptr->derived && is_infoschema_db(&ptr->db))
8322   {
8323     if (ptr->updating &&
8324         /* Special cases which are processed by commands itself */
8325         lex->sql_command != SQLCOM_CHECK &&
8326         lex->sql_command != SQLCOM_CHECKSUM)
8327     {
8328       my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
8329                thd->security_ctx->priv_user,
8330                thd->security_ctx->priv_host,
8331                INFORMATION_SCHEMA_NAME.str);
8332       DBUG_RETURN(0);
8333     }
8334     ST_SCHEMA_TABLE *schema_table;
8335     schema_table= find_schema_table(thd, &ptr->table_name);
8336     ptr->schema_table_name= ptr->table_name;
8337     ptr->schema_table= schema_table;
8338   }
8339   ptr->select_lex= this;
8340   /*
8341     We can't cache internal temporary tables between prepares as the
8342     table may be deleted before next exection.
8343  */
8344   ptr->cacheable_table= !table->is_derived_table();
8345   ptr->index_hints= index_hints_arg;
8346   ptr->option= option ? option->str : 0;
8347   /* check that used name is unique. Sequences are ignored */
8348   if (lock_type != TL_IGNORE && !ptr->sequence)
8349   {
8350     TABLE_LIST *first_table= table_list.first;
8351     if (lex->sql_command == SQLCOM_CREATE_VIEW)
8352       first_table= first_table ? first_table->next_local : NULL;
8353     for (TABLE_LIST *tables= first_table ;
8354 	 tables ;
8355 	 tables=tables->next_local)
8356     {
8357       if (unlikely(!my_strcasecmp(table_alias_charset, alias_str.str,
8358                                   tables->alias.str) &&
8359                    !cmp(&ptr->db, &tables->db) && ! tables->sequence))
8360       {
8361 	my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str.str); /* purecov: tested */
8362 	DBUG_RETURN(0);				/* purecov: tested */
8363       }
8364     }
8365   }
8366   /* Store the table reference preceding the current one. */
8367   if (table_list.elements > 0 && likely(!ptr->sequence))
8368   {
8369     /*
8370       table_list.next points to the last inserted TABLE_LIST->next_local'
8371       element
8372       We don't use the offsetof() macro here to avoid warnings from gcc
8373     */
8374     previous_table_ref= (TABLE_LIST*) ((char*) table_list.next -
8375                                        ((char*) &(ptr->next_local) -
8376                                         (char*) ptr));
8377     /*
8378       Set next_name_resolution_table of the previous table reference to point
8379       to the current table reference. In effect the list
8380       TABLE_LIST::next_name_resolution_table coincides with
8381       TABLE_LIST::next_local. Later this may be changed in
8382       store_top_level_join_columns() for NATURAL/USING joins.
8383     */
8384     previous_table_ref->next_name_resolution_table= ptr;
8385   }
8386 
8387   /*
8388     Link the current table reference in a local list (list for current select).
8389     Notice that as a side effect here we set the next_local field of the
8390     previous table reference to 'ptr'. Here we also add one element to the
8391     list 'table_list'.
8392     We don't store sequences into the local list to hide them from INSERT
8393     and SELECT.
8394   */
8395   if (likely(!ptr->sequence))
8396     table_list.link_in_list(ptr, &ptr->next_local);
8397   ptr->next_name_resolution_table= NULL;
8398 #ifdef WITH_PARTITION_STORAGE_ENGINE
8399   ptr->partition_names= partition_names;
8400 #endif /* WITH_PARTITION_STORAGE_ENGINE */
8401   /* Link table in global list (all used tables) */
8402   lex->add_to_query_tables(ptr);
8403 
8404   // Pure table aliases do not need to be locked:
8405   if (ptr->db.str && !(table_options & TL_OPTION_ALIAS))
8406   {
8407     MDL_REQUEST_INIT(&ptr->mdl_request, MDL_key::TABLE, ptr->db.str,
8408                      ptr->table_name.str, mdl_type, MDL_TRANSACTION);
8409   }
8410   DBUG_RETURN(ptr);
8411 }
8412 
8413 
8414 /**
8415   Initialize a new table list for a nested join.
8416 
8417     The function initializes a structure of the TABLE_LIST type
8418     for a nested join. It sets up its nested join list as empty.
8419     The created structure is added to the front of the current
8420     join list in the st_select_lex object. Then the function
8421     changes the current nest level for joins to refer to the newly
8422     created empty list after having saved the info on the old level
8423     in the initialized structure.
8424 
8425   @param thd         current thread
8426 
8427   @retval
8428     0   if success
8429   @retval
8430     1   otherwise
8431 */
8432 
init_nested_join(THD * thd)8433 bool st_select_lex::init_nested_join(THD *thd)
8434 {
8435   TABLE_LIST *ptr;
8436   NESTED_JOIN *nested_join;
8437   DBUG_ENTER("init_nested_join");
8438 
8439   if (unlikely(!(ptr= (TABLE_LIST*) thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST))+
8440                                                 sizeof(NESTED_JOIN)))))
8441     DBUG_RETURN(1);
8442   nested_join= ptr->nested_join=
8443     ((NESTED_JOIN*) ((uchar*) ptr + ALIGN_SIZE(sizeof(TABLE_LIST))));
8444 
8445   ptr->embedding= embedding;
8446   ptr->join_list= join_list;
8447   ptr->alias.str="(nested_join)";
8448   ptr->alias.length= sizeof("(nested_join)")-1;
8449   embedding= ptr;
8450   join_list= &nested_join->join_list;
8451   join_list->empty();
8452   DBUG_RETURN(0);
8453 }
8454 
8455 
8456 /**
8457   End a nested join table list.
8458 
8459     The function returns to the previous join nest level.
8460     If the current level contains only one member, the function
8461     moves it one level up, eliminating the nest.
8462 
8463   @param thd         current thread
8464 
8465   @return
8466     - Pointer to TABLE_LIST element added to the total table list, if success
8467     - 0, otherwise
8468 */
8469 
end_nested_join(THD * thd)8470 TABLE_LIST *st_select_lex::end_nested_join(THD *thd)
8471 {
8472   TABLE_LIST *ptr;
8473   NESTED_JOIN *nested_join;
8474   DBUG_ENTER("end_nested_join");
8475 
8476   DBUG_ASSERT(embedding);
8477   ptr= embedding;
8478   join_list= ptr->join_list;
8479   embedding= ptr->embedding;
8480   nested_join= ptr->nested_join;
8481   if (nested_join->join_list.elements == 1)
8482   {
8483     TABLE_LIST *embedded= nested_join->join_list.head();
8484     join_list->pop();
8485     embedded->join_list= join_list;
8486     embedded->embedding= embedding;
8487     join_list->push_front(embedded, thd->mem_root);
8488     ptr= embedded;
8489     embedded->lifted= 1;
8490   }
8491   else if (nested_join->join_list.elements == 0)
8492   {
8493     join_list->pop();
8494     ptr= 0;                                     // return value
8495   }
8496   DBUG_RETURN(ptr);
8497 }
8498 
8499 
8500 /**
8501   Nest last join operation.
8502 
8503     The function nest last join operation as if it was enclosed in braces.
8504 
8505   @param thd         current thread
8506 
8507   @retval
8508     0  Error
8509   @retval
8510     \#  Pointer to TABLE_LIST element created for the new nested join
8511 */
8512 
nest_last_join(THD * thd)8513 TABLE_LIST *st_select_lex::nest_last_join(THD *thd)
8514 {
8515   TABLE_LIST *ptr;
8516   NESTED_JOIN *nested_join;
8517   List<TABLE_LIST> *embedded_list;
8518   DBUG_ENTER("nest_last_join");
8519 
8520   TABLE_LIST *head= join_list->head();
8521   if (head->nested_join && (head->nested_join->nest_type & REBALANCED_NEST))
8522   {
8523     head= join_list->pop();
8524     DBUG_RETURN(head);
8525   }
8526 
8527   if (unlikely(!(ptr= (TABLE_LIST*) thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST))+
8528                                                 sizeof(NESTED_JOIN)))))
8529     DBUG_RETURN(0);
8530   nested_join= ptr->nested_join=
8531     ((NESTED_JOIN*) ((uchar*) ptr + ALIGN_SIZE(sizeof(TABLE_LIST))));
8532 
8533   ptr->embedding= embedding;
8534   ptr->join_list= join_list;
8535   ptr->alias.str= "(nest_last_join)";
8536   ptr->alias.length= sizeof("(nest_last_join)")-1;
8537   embedded_list= &nested_join->join_list;
8538   embedded_list->empty();
8539   nested_join->nest_type= JOIN_OP_NEST;
8540 
8541   for (uint i=0; i < 2; i++)
8542   {
8543     TABLE_LIST *table= join_list->pop();
8544     if (unlikely(!table))
8545       DBUG_RETURN(NULL);
8546     table->join_list= embedded_list;
8547     table->embedding= ptr;
8548     embedded_list->push_back(table);
8549     if (table->natural_join)
8550     {
8551       ptr->is_natural_join= TRUE;
8552       /*
8553         If this is a JOIN ... USING, move the list of joined fields to the
8554         table reference that describes the join.
8555       */
8556       if (prev_join_using)
8557         ptr->join_using_fields= prev_join_using;
8558     }
8559   }
8560   nested_join->used_tables= nested_join->not_null_tables= (table_map) 0;
8561   DBUG_RETURN(ptr);
8562 }
8563 
8564 
8565 /**
8566   Add a table to the current join list.
8567 
8568     The function puts a table in front of the current join list
8569     of st_select_lex object.
8570     Thus, joined tables are put into this list in the reverse order
8571     (the most outer join operation follows first).
8572 
8573   @param table       the table to add
8574 
8575   @return
8576     None
8577 */
8578 
add_joined_table(TABLE_LIST * table)8579 void st_select_lex::add_joined_table(TABLE_LIST *table)
8580 {
8581   DBUG_ENTER("add_joined_table");
8582   join_list->push_front(table, parent_lex->thd->mem_root);
8583   table->join_list= join_list;
8584   table->embedding= embedding;
8585   DBUG_VOID_RETURN;
8586 }
8587 
8588 
8589 /**
8590   @brief
8591     Create a node for JOIN/INNER JOIN/CROSS JOIN/STRAIGHT_JOIN operation
8592 
8593   @param left_op     the node for the left operand constructed by the parser
8594   @param right_op    the node for the right operand constructed by the parser
8595   @param straight_fl TRUE if STRAIGHT_JOIN is used
8596 
8597   @retval
8598     false on success
8599     true  otherwise
8600 
8601   @details
8602 
8603     JOIN operator can be left-associative with other join operators in one
8604     context and right-associative in another context.
8605 
8606     In this query
8607       SELECT * FROM t1 JOIN t2 LEFT JOIN t3 ON t2.a=t3.a  (Q1)
8608     JOIN is left-associative and the query Q1 is interpreted as
8609       SELECT * FROM (t1 JOIN t2) LEFT JOIN t3 ON t2.a=t3.a.
8610     While in this query
8611       SELECT * FROM t1 JOIN t2 LEFT JOIN t3 ON t2.a=t3.a ON t1.b=t2.b (Q2)
8612     JOIN is right-associative and the query Q2 is interpreted as
8613       SELECT * FROM t1 JOIN (t2 LEFT JOIN t3 ON t2.a=t3.a) ON t1.b=t2.b
8614 
8615     JOIN is right-associative if it is used with ON clause or with USING clause.
8616     Otherwise it is left-associative.
8617     When parsing a join expression with JOIN operator we can't determine
8618     whether this operation left or right associative until either we read the
8619     corresponding ON clause or we reach the end of the expression. This creates
8620     a problem for the parser to build a proper internal representation of the
8621     used join expression.
8622 
8623     For Q1 and Q2 the trees representing the used join expressions look like
8624 
8625             LJ - ON                   J - ON
8626            /  \                      / \
8627           J    t3   (TQ1)          t1   LJ - ON      (TQ2)
8628          / \                           /  \
8629        t1   t2                       t2    t3
8630 
8631     To build TQ1 the parser has to reduce the expression for JOIN right after
8632     it has read the reference to t2. To build TQ2 the parser reduces JOIN
8633     when he has read the whole join expression. There is no way to determine
8634     whether an early reduction is needed until the whole join expression is
8635     read.
8636     A solution here is always to do a late reduction. In this case the parser
8637     first builds an incorrect tree TQ1* that has to be rebalanced right after
8638     it has been constructed.
8639 
8640              J                               LJ - ON
8641             / \                             /  \
8642           t1   LJ - ON    (TQ1*)    =>     J    t3
8643               /  \                        / \
8644             t2    t3                    t1   t2
8645 
8646     Actually the transformation is performed over the nodes t1 and LJ before the
8647     node for J is created in the function st_select_lex::add_cross_joined_table.
8648     The function creates a node for J which replaces the node t2. Then it
8649     attaches the nodes t1 and t2 to this newly created node. The node LJ becomes
8650     the top node of the tree.
8651 
8652     For the query
8653       SELECT * FROM t1 JOIN t2 RIGHT JOIN t3 ON t2.a=t3.a  (Q3)
8654     the transformation looks slightly differently because the parser
8655     replaces the RIGHT JOIN tree for an equivalent LEFT JOIN tree.
8656 
8657              J                               LJ - ON
8658             / \                             /  \
8659           t1   LJ - ON    (TQ3*)    =>    t3    J
8660               /  \                             / \
8661             t3    t2                         t1   t2
8662 
8663     With several left associative JOINs
8664       SELECT * FROM t1 JOIN t2 JOIN t3 LEFT JOIN t4 ON t3.a=t4.a (Q4)
8665     the newly created node for JOIN replaces the left most node of the tree:
8666 
8667           J1                         LJ - ON
8668          /  \                       /  \
8669        t1    J2                    J2   t4
8670             /  \          =>      /  \
8671            t2  LJ - ON          J1    t3
8672               /  \             /  \
8673             t3   t4          t1    t2
8674 
8675     Here's another example:
8676       SELECT *
8677       FROM t1 JOIN t2 LEFT JOIN t3 JOIN t4 ON t3.a=t4.a ON t2.b=t3.b (Q5)
8678 
8679           J                       LJ - ON
8680          / \                     /   \
8681        t1   LJ - ON             J     J - ON
8682            /  \          =>    / \   / \
8683          t2    J - ON         t1 t2 t3 t4
8684               / \
8685             t3   t4
8686 
8687     If the transformed nested join node node is a natural join node like in
8688     the following query
8689       SELECT * FROM t1 JOIN t2 LEFT JOIN t3 USING(a)  (Q6)
8690     the transformation additionally has to take care about setting proper
8691     references in the field natural_join for both operands of the natural
8692     join operation.
8693 
8694     The queries that combine comma syntax for join operation with
8695     JOIN expression require a special care. Consider the query
8696       SELECT * FROM t1, t2 JOIN t3 LEFT JOIN t4 ON t3.a=t4.a (Q7)
8697     This query is equivalent to the query
8698       SELECT * FROM (t1, t2) JOIN t3 LEFT JOIN t4 ON t3.a=t4.a
8699     The latter is transformed in the same way as query Q1
8700 
8701              J                               LJ - ON
8702             / \                             /  \
8703       (t1,t2)  LJ - ON      =>             J    t4
8704               /  \                        / \
8705             t3    t4                (t1,t2)   t3
8706 
8707     A transformation similar to the transformation for Q3 is done for
8708     the following query with RIGHT JOIN
8709       SELECT * FROM t1, t2 JOIN t3 RIGHT JOIN t4 ON t3.a=t4.a (Q8)
8710 
8711              J                               LJ - ON
8712             / \                             /  \
8713           t3   LJ - ON      =>            t4    J
8714               /  \                             / \
8715             t4   (t1,t2)                 (t1,t2)  t3
8716 
8717     The function also has to change the name resolution context for ON
8718     expressions used in the transformed join expression to take into
8719     account the tables of the left_op node.
8720 
8721   TODO:
8722     A more elegant solution would be to implement the transformation that
8723     eliminates nests for cross join operations. For Q7 it would work like this:
8724 
8725              J                               LJ - ON
8726             / \                             /  \
8727       (t1,t2)  LJ - ON      =>     (t1,t2,t3)   t4
8728               /  \
8729             t3    t4
8730 
8731     For Q8 with RIGHT JOIN the transformation would work similarly:
8732 
8733              J                               LJ - ON
8734             / \                             /  \
8735           t3   LJ - ON      =>            t4   (t1,t2,t3)
8736               /  \
8737             t4   (t1,t2)
8738 
8739 */
8740 
add_cross_joined_table(TABLE_LIST * left_op,TABLE_LIST * right_op,bool straight_fl)8741 bool st_select_lex::add_cross_joined_table(TABLE_LIST *left_op,
8742                                            TABLE_LIST *right_op,
8743                                            bool straight_fl)
8744 {
8745   DBUG_ENTER("add_cross_joined_table");
8746   THD *thd= parent_lex->thd;
8747   if (!(right_op->nested_join &&
8748 	(right_op->nested_join->nest_type & JOIN_OP_NEST)))
8749   {
8750     /*
8751       This handles the cases when the right operand is not a nested join.
8752       like in queries
8753         SELECT * FROM t1 JOIN t2;
8754         SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.a JOIN t3
8755     */
8756     add_joined_table(left_op);
8757     add_joined_table(right_op);
8758     right_op->straight= straight_fl;
8759     DBUG_RETURN(false);
8760   }
8761 
8762   TABLE_LIST *tbl;
8763   List<TABLE_LIST> *right_op_jl= right_op->join_list;
8764   TABLE_LIST *cj_nest;
8765 
8766   /*
8767     Create the node NJ for a new nested join for the future inclusion
8768     of left_op in it. Initially the nest is empty.
8769   */
8770   if (unlikely(!(cj_nest=
8771                  (TABLE_LIST*) thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST))+
8772                                            sizeof(NESTED_JOIN)))))
8773     DBUG_RETURN(true);
8774   cj_nest->nested_join=
8775     ((NESTED_JOIN*) ((uchar*) cj_nest + ALIGN_SIZE(sizeof(TABLE_LIST))));
8776   cj_nest->nested_join->nest_type= JOIN_OP_NEST;
8777   List<TABLE_LIST> *cjl=  &cj_nest->nested_join->join_list;
8778   cjl->empty();
8779 
8780   List<TABLE_LIST> *jl= &right_op->nested_join->join_list;
8781   DBUG_ASSERT(jl->elements == 2);
8782   /* Look for the left most node tbl of the right_op tree */
8783   for ( ; ; )
8784   {
8785     TABLE_LIST *pair_tbl= 0;  /* useful only for operands of natural joins */
8786 
8787     List_iterator<TABLE_LIST> li(*jl);
8788     tbl= li++;
8789 
8790     /* Expand name resolution context */
8791     Name_resolution_context *on_context;
8792     if ((on_context= tbl->on_context))
8793     {
8794       on_context->first_name_resolution_table=
8795         left_op->first_leaf_for_name_resolution();
8796     }
8797 
8798     if (!(tbl->outer_join & JOIN_TYPE_RIGHT))
8799     {
8800       pair_tbl= tbl;
8801       tbl= li++;
8802     }
8803     if (tbl->nested_join &&
8804         tbl->nested_join->nest_type & JOIN_OP_NEST)
8805     {
8806       jl= &tbl->nested_join->join_list;
8807       continue;
8808     }
8809 
8810     /* Replace the tbl node in the tree for the newly created NJ node */
8811     cj_nest->outer_join= tbl->outer_join;
8812     cj_nest->on_expr= tbl->on_expr;
8813     cj_nest->embedding= tbl->embedding;
8814     cj_nest->join_list= jl;
8815     cj_nest->alias.str= "(nest_last_join)";
8816     cj_nest->alias.length= sizeof("(nest_last_join)")-1;
8817     li.replace(cj_nest);
8818 
8819     /*
8820       If tbl is an operand of a natural join set properly the references
8821       in the fields natural_join for both operands of the operation.
8822     */
8823     if(tbl->embedding && tbl->embedding->is_natural_join)
8824     {
8825       if (!pair_tbl)
8826         pair_tbl= li++;
8827       pair_tbl->natural_join= cj_nest;
8828       cj_nest->natural_join= pair_tbl;
8829     }
8830     break;
8831   }
8832 
8833   /* Attach tbl as the right operand of NJ */
8834   if (unlikely(cjl->push_back(tbl, thd->mem_root)))
8835     DBUG_RETURN(true);
8836   tbl->outer_join= 0;
8837   tbl->on_expr= 0;
8838   tbl->straight= straight_fl;
8839   tbl->natural_join= 0;
8840   tbl->embedding= cj_nest;
8841   tbl->join_list= cjl;
8842 
8843   /* Add left_op as the left operand of NJ */
8844   if (unlikely(cjl->push_back(left_op, thd->mem_root)))
8845     DBUG_RETURN(true);
8846   left_op->embedding= cj_nest;
8847   left_op->join_list= cjl;
8848 
8849   /*
8850     Mark right_op as a rebalanced nested join in order not to
8851     create a new top level nested join node.
8852   */
8853   right_op->nested_join->nest_type|= REBALANCED_NEST;
8854   if (unlikely(right_op_jl->push_front(right_op)))
8855     DBUG_RETURN(true);
8856   DBUG_RETURN(false);
8857 }
8858 
8859 
8860 /**
8861   Convert a right join into equivalent left join.
8862 
8863     The function takes the current join list t[0],t[1] ... and
8864     effectively converts it into the list t[1],t[0] ...
8865     Although the outer_join flag for the new nested table contains
8866     JOIN_TYPE_RIGHT, it will be handled as the inner table of a left join
8867     operation.
8868 
8869   EXAMPLES
8870   @verbatim
8871     SELECT * FROM t1 RIGHT JOIN t2 ON on_expr =>
8872       SELECT * FROM t2 LEFT JOIN t1 ON on_expr
8873 
8874     SELECT * FROM t1,t2 RIGHT JOIN t3 ON on_expr =>
8875       SELECT * FROM t1,t3 LEFT JOIN t2 ON on_expr
8876 
8877     SELECT * FROM t1,t2 RIGHT JOIN (t3,t4) ON on_expr =>
8878       SELECT * FROM t1,(t3,t4) LEFT JOIN t2 ON on_expr
8879 
8880     SELECT * FROM t1 LEFT JOIN t2 ON on_expr1 RIGHT JOIN t3  ON on_expr2 =>
8881       SELECT * FROM t3 LEFT JOIN (t1 LEFT JOIN t2 ON on_expr2) ON on_expr1
8882    @endverbatim
8883 
8884   @param thd         current thread
8885 
8886   @return
8887     - Pointer to the table representing the inner table, if success
8888     - 0, otherwise
8889 */
8890 
convert_right_join()8891 TABLE_LIST *st_select_lex::convert_right_join()
8892 {
8893   TABLE_LIST *tab2= join_list->pop();
8894   TABLE_LIST *tab1= join_list->pop();
8895   DBUG_ENTER("convert_right_join");
8896 
8897   join_list->push_front(tab2, parent_lex->thd->mem_root);
8898   join_list->push_front(tab1, parent_lex->thd->mem_root);
8899   tab1->outer_join|= JOIN_TYPE_RIGHT;
8900 
8901   DBUG_RETURN(tab1);
8902 }
8903 
8904 
prepare_add_window_spec(THD * thd)8905 void st_select_lex::prepare_add_window_spec(THD *thd)
8906 {
8907   LEX *lex= thd->lex;
8908   lex->save_group_list= group_list;
8909   lex->save_order_list= order_list;
8910   lex->win_ref= NULL;
8911   lex->win_frame= NULL;
8912   lex->frame_top_bound= NULL;
8913   lex->frame_bottom_bound= NULL;
8914   group_list.empty();
8915   order_list.empty();
8916 }
8917 
add_window_def(THD * thd,LEX_CSTRING * win_name,LEX_CSTRING * win_ref,SQL_I_List<ORDER> win_partition_list,SQL_I_List<ORDER> win_order_list,Window_frame * win_frame)8918 bool st_select_lex::add_window_def(THD *thd,
8919                                    LEX_CSTRING *win_name,
8920                                    LEX_CSTRING *win_ref,
8921                                    SQL_I_List<ORDER> win_partition_list,
8922                                    SQL_I_List<ORDER> win_order_list,
8923                                    Window_frame *win_frame)
8924 {
8925   SQL_I_List<ORDER> *win_part_list_ptr=
8926     new (thd->mem_root) SQL_I_List<ORDER> (win_partition_list);
8927   SQL_I_List<ORDER> *win_order_list_ptr=
8928     new (thd->mem_root) SQL_I_List<ORDER> (win_order_list);
8929   if (!(win_part_list_ptr && win_order_list_ptr))
8930     return true;
8931   Window_def *win_def= new (thd->mem_root) Window_def(win_name,
8932                                                       win_ref,
8933                                                       win_part_list_ptr,
8934                                                       win_order_list_ptr,
8935                                                       win_frame);
8936   group_list= thd->lex->save_group_list;
8937   order_list= thd->lex->save_order_list;
8938   if (parsing_place != SELECT_LIST)
8939   {
8940     fields_in_window_functions+= win_part_list_ptr->elements +
8941                                  win_order_list_ptr->elements;
8942   }
8943   return (win_def == NULL || window_specs.push_back(win_def));
8944 }
8945 
add_window_spec(THD * thd,LEX_CSTRING * win_ref,SQL_I_List<ORDER> win_partition_list,SQL_I_List<ORDER> win_order_list,Window_frame * win_frame)8946 bool st_select_lex::add_window_spec(THD *thd,
8947                                     LEX_CSTRING *win_ref,
8948                                     SQL_I_List<ORDER> win_partition_list,
8949                                     SQL_I_List<ORDER> win_order_list,
8950                                     Window_frame *win_frame)
8951 {
8952   SQL_I_List<ORDER> *win_part_list_ptr=
8953     new (thd->mem_root) SQL_I_List<ORDER> (win_partition_list);
8954   SQL_I_List<ORDER> *win_order_list_ptr=
8955     new (thd->mem_root) SQL_I_List<ORDER> (win_order_list);
8956   if (!(win_part_list_ptr && win_order_list_ptr))
8957     return true;
8958   Window_spec *win_spec= new (thd->mem_root) Window_spec(win_ref,
8959                                                          win_part_list_ptr,
8960                                                          win_order_list_ptr,
8961                                                          win_frame);
8962   group_list= thd->lex->save_group_list;
8963   order_list= thd->lex->save_order_list;
8964   if (parsing_place != SELECT_LIST)
8965   {
8966     fields_in_window_functions+= win_part_list_ptr->elements +
8967                                  win_order_list_ptr->elements;
8968   }
8969   thd->lex->win_spec= win_spec;
8970   return (win_spec == NULL || window_specs.push_back(win_spec));
8971 }
8972 
8973 /**
8974   Set lock for all tables in current select level.
8975 
8976   @param lock_type			Lock to set for tables
8977 
8978   @note
8979     If lock is a write lock, then tables->updating is set 1
8980     This is to get tables_ok to know that the table is updated by the
8981     query
8982 */
8983 
set_lock_for_tables(thr_lock_type lock_type,bool for_update)8984 void st_select_lex::set_lock_for_tables(thr_lock_type lock_type, bool for_update)
8985 {
8986   DBUG_ENTER("set_lock_for_tables");
8987   DBUG_PRINT("enter", ("lock_type: %d  for_update: %d", lock_type,
8988 		       for_update));
8989   for (TABLE_LIST *tables= table_list.first;
8990        tables;
8991        tables= tables->next_local)
8992   {
8993     tables->lock_type= lock_type;
8994     tables->updating=  for_update;
8995 
8996     if (tables->db.length)
8997       tables->mdl_request.set_type((lock_type >= TL_WRITE_ALLOW_WRITE) ?
8998                                    MDL_SHARED_WRITE : MDL_SHARED_READ);
8999   }
9000   DBUG_VOID_RETURN;
9001 }
9002 
9003 
9004 /**
9005   Create a fake SELECT_LEX for a unit.
9006 
9007     The method create a fake SELECT_LEX object for a unit.
9008     This object is created for any union construct containing a union
9009     operation and also for any single select union construct of the form
9010     @verbatim
9011     (SELECT ... ORDER BY order_list [LIMIT n]) ORDER BY ...
9012     @endvarbatim
9013     or of the form
9014     @varbatim
9015     (SELECT ... ORDER BY LIMIT n) ORDER BY ...
9016     @endvarbatim
9017 
9018   @param thd_arg		   thread handle
9019 
9020   @note
9021     The object is used to retrieve rows from the temporary table
9022     where the result on the union is obtained.
9023 
9024   @retval
9025     1     on failure to create the object
9026   @retval
9027     0     on success
9028 */
9029 
add_fake_select_lex(THD * thd_arg)9030 bool st_select_lex_unit::add_fake_select_lex(THD *thd_arg)
9031 {
9032   SELECT_LEX *first_sl= first_select();
9033   DBUG_ENTER("st_select_lex_unit::add_fake_select_lex");
9034   DBUG_ASSERT(!fake_select_lex);
9035 
9036   if (!(fake_select_lex= new (thd_arg->mem_root) SELECT_LEX()))
9037       DBUG_RETURN(1);
9038   fake_select_lex->include_standalone(this,
9039                                       (SELECT_LEX_NODE**)&fake_select_lex);
9040   fake_select_lex->select_number= INT_MAX;
9041   fake_select_lex->parent_lex= thd_arg->lex; /* Used in init_query. */
9042   fake_select_lex->make_empty_select();
9043   fake_select_lex->set_linkage(GLOBAL_OPTIONS_TYPE);
9044   fake_select_lex->select_limit= 0;
9045 
9046   fake_select_lex->no_table_names_allowed= 1;
9047 
9048   fake_select_lex->context.outer_context=first_sl->context.outer_context;
9049   /* allow item list resolving in fake select for ORDER BY */
9050   fake_select_lex->context.resolve_in_select_list= TRUE;
9051   fake_select_lex->context.select_lex= fake_select_lex;
9052 
9053   fake_select_lex->nest_level_base= first_select()->nest_level_base;
9054   if (fake_select_lex->set_nest_level(first_select()->nest_level))
9055     DBUG_RETURN(1);
9056 
9057   if (!is_unit_op())
9058   {
9059     /*
9060       This works only for
9061       (SELECT ... ORDER BY list [LIMIT n]) ORDER BY order_list [LIMIT m],
9062       (SELECT ... LIMIT n) ORDER BY order_list [LIMIT m]
9063       just before the parser starts processing order_list
9064     */
9065     fake_select_lex->no_table_names_allowed= 1;
9066     thd_arg->lex->current_select= fake_select_lex;
9067   }
9068   //thd_arg->lex->pop_context("add fake");
9069   DBUG_RETURN(0);
9070 }
9071 
9072 
9073 /**
9074   Push a new name resolution context for a JOIN ... ON clause to the
9075   context stack of a query block.
9076 
9077     Create a new name resolution context for a JOIN ... ON clause,
9078     set the first and last leaves of the list of table references
9079     to be used for name resolution, and push the newly created
9080     context to the stack of contexts of the query.
9081 
9082   @param thd       pointer to current thread
9083   @param left_op   left  operand of the JOIN
9084   @param right_op  rigth operand of the JOIN
9085 
9086   @retval
9087     FALSE  if all is OK
9088   @retval
9089     TRUE   if a memory allocation error occurred
9090 */
9091 
9092 bool
push_new_name_resolution_context(THD * thd,TABLE_LIST * left_op,TABLE_LIST * right_op)9093 push_new_name_resolution_context(THD *thd,
9094                                  TABLE_LIST *left_op, TABLE_LIST *right_op)
9095 {
9096   Name_resolution_context *on_context;
9097   if (!(on_context= new (thd->mem_root) Name_resolution_context))
9098     return TRUE;
9099   on_context->init();
9100   on_context->first_name_resolution_table=
9101     left_op->first_leaf_for_name_resolution();
9102   on_context->last_name_resolution_table=
9103     right_op->last_leaf_for_name_resolution();
9104   LEX *lex= thd->lex;
9105   on_context->select_lex = lex->current_select;
9106   st_select_lex *curr_select= lex->pop_select();
9107   st_select_lex *outer_sel= lex->select_stack_head();
9108   lex->push_select(curr_select);
9109   on_context->outer_context = outer_sel ? &outer_sel->context : 0;
9110   return lex->push_context(on_context);
9111 }
9112 
9113 
9114 /**
9115   Fix condition which contains only field (f turns to  f <> 0 )
9116 
9117   @param cond            The condition to fix
9118 
9119   @return fixed condition
9120 */
9121 
normalize_cond(THD * thd,Item * cond)9122 Item *normalize_cond(THD *thd, Item *cond)
9123 {
9124   if (cond)
9125   {
9126     Item::Type type= cond->type();
9127     if (type == Item::FIELD_ITEM || type == Item::REF_ITEM)
9128     {
9129       cond= new (thd->mem_root) Item_func_ne(thd, cond, new (thd->mem_root) Item_int(thd, 0));
9130     }
9131   }
9132   return cond;
9133 }
9134 
9135 
9136 /**
9137   Add an ON condition to the second operand of a JOIN ... ON.
9138 
9139     Add an ON condition to the right operand of a JOIN ... ON clause.
9140 
9141   @param b     the second operand of a JOIN ... ON
9142   @param expr  the condition to be added to the ON clause
9143 
9144   @retval
9145     FALSE  if there was some error
9146   @retval
9147     TRUE   if all is OK
9148 */
9149 
add_join_on(THD * thd,TABLE_LIST * b,Item * expr)9150 void add_join_on(THD *thd, TABLE_LIST *b, Item *expr)
9151 {
9152   if (expr)
9153   {
9154     expr= normalize_cond(thd, expr);
9155     if (!b->on_expr)
9156       b->on_expr= expr;
9157     else
9158     {
9159       /*
9160         If called from the parser, this happens if you have both a
9161         right and left join. If called later, it happens if we add more
9162         than one condition to the ON clause.
9163       */
9164       b->on_expr= new (thd->mem_root) Item_cond_and(thd, b->on_expr,expr);
9165     }
9166     b->on_expr->top_level_item();
9167   }
9168 }
9169 
9170 
9171 /**
9172   Mark that there is a NATURAL JOIN or JOIN ... USING between two
9173   tables.
9174 
9175     This function marks that table b should be joined with a either via
9176     a NATURAL JOIN or via JOIN ... USING. Both join types are special
9177     cases of each other, so we treat them together. The function
9178     setup_conds() creates a list of equal condition between all fields
9179     of the same name for NATURAL JOIN or the fields in 'using_fields'
9180     for JOIN ... USING. The list of equality conditions is stored
9181     either in b->on_expr, or in JOIN::conds, depending on whether there
9182     was an outer join.
9183 
9184   EXAMPLE
9185   @verbatim
9186     SELECT * FROM t1 NATURAL LEFT JOIN t2
9187      <=>
9188     SELECT * FROM t1 LEFT JOIN t2 ON (t1.i=t2.i and t1.j=t2.j ... )
9189 
9190     SELECT * FROM t1 NATURAL JOIN t2 WHERE <some_cond>
9191      <=>
9192     SELECT * FROM t1, t2 WHERE (t1.i=t2.i and t1.j=t2.j and <some_cond>)
9193 
9194     SELECT * FROM t1 JOIN t2 USING(j) WHERE <some_cond>
9195      <=>
9196     SELECT * FROM t1, t2 WHERE (t1.j=t2.j and <some_cond>)
9197    @endverbatim
9198 
9199   @param a		  Left join argumentex
9200   @param b		  Right join argument
9201   @param using_fields    Field names from USING clause
9202 */
9203 
add_join_natural(TABLE_LIST * a,TABLE_LIST * b,List<String> * using_fields,SELECT_LEX * lex)9204 void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List<String> *using_fields,
9205                       SELECT_LEX *lex)
9206 {
9207   b->natural_join= a;
9208   lex->prev_join_using= using_fields;
9209 }
9210 
9211 
9212 /**
9213   Find a thread by id and return it, locking it LOCK_thd_kill
9214 
9215   @param id  Identifier of the thread we're looking for
9216   @param query_id If true, search by query_id instead of thread_id
9217 
9218   @return NULL    - not found
9219           pointer - thread found, and its LOCK_thd_kill is locked.
9220 */
9221 
9222 struct find_thread_callback_arg
9223 {
find_thread_callback_argfind_thread_callback_arg9224   find_thread_callback_arg(longlong id_arg, bool query_id_arg):
9225     thd(0), id(id_arg), query_id(query_id_arg) {}
9226   THD *thd;
9227   longlong id;
9228   bool query_id;
9229 };
9230 
9231 
find_thread_callback(THD * thd,find_thread_callback_arg * arg)9232 static my_bool find_thread_callback(THD *thd, find_thread_callback_arg *arg)
9233 {
9234   if (arg->id == (arg->query_id ? thd->query_id : (longlong) thd->thread_id))
9235   {
9236     mysql_mutex_lock(&thd->LOCK_thd_kill);    // Lock from delete
9237     arg->thd= thd;
9238     return 1;
9239   }
9240   return 0;
9241 }
9242 
9243 
find_thread_by_id(longlong id,bool query_id)9244 THD *find_thread_by_id(longlong id, bool query_id)
9245 {
9246   find_thread_callback_arg arg(id, query_id);
9247   server_threads.iterate(find_thread_callback, &arg);
9248   return arg.thd;
9249 }
9250 
9251 
9252 /**
9253   kill one thread.
9254 
9255   @param thd			Thread class
9256   @param id                     Thread id or query id
9257   @param kill_signal            Should it kill the query or the connection
9258   @param type                   Type of id: thread id or query id
9259 */
9260 
9261 uint
kill_one_thread(THD * thd,longlong id,killed_state kill_signal,killed_type type)9262 kill_one_thread(THD *thd, longlong id, killed_state kill_signal, killed_type type)
9263 {
9264   THD *tmp;
9265   uint error= (type == KILL_TYPE_QUERY ? ER_NO_SUCH_QUERY : ER_NO_SUCH_THREAD);
9266   DBUG_ENTER("kill_one_thread");
9267   DBUG_PRINT("enter", ("id: %lld  signal: %u", id, (uint) kill_signal));
9268   tmp= find_thread_by_id(id, type == KILL_TYPE_QUERY);
9269   if (!tmp)
9270     DBUG_RETURN(error);
9271 
9272   if (tmp->get_command() != COM_DAEMON)
9273   {
9274     /*
9275       If we're SUPER, we can KILL anything, including system-threads.
9276       No further checks.
9277 
9278       KILLer: thd->security_ctx->user could in theory be NULL while
9279       we're still in "unauthenticated" state. This is a theoretical
9280       case (the code suggests this could happen, so we play it safe).
9281 
9282       KILLee: tmp->security_ctx->user will be NULL for system threads.
9283       We need to check so Jane Random User doesn't crash the server
9284       when trying to kill a) system threads or b) unauthenticated users'
9285       threads (Bug#43748).
9286 
9287       If user of both killer and killee are non-NULL, proceed with
9288       slayage if both are string-equal.
9289 
9290       It's ok to also kill DELAYED threads with KILL_CONNECTION instead of
9291       KILL_SYSTEM_THREAD; The difference is that KILL_CONNECTION may be
9292       faster and do a harder kill than KILL_SYSTEM_THREAD;
9293     */
9294 
9295     mysql_mutex_lock(&tmp->LOCK_thd_data); // Lock from concurrent usage
9296 
9297 #ifdef WITH_WSREP
9298     if (((thd->security_ctx->master_access & PRIV_KILL_OTHER_USER_PROCESS) ||
9299         thd->security_ctx->user_matches(tmp->security_ctx)) &&
9300         !wsrep_thd_is_BF(tmp, false) && !tmp->wsrep_applier)
9301 #else
9302     if ((thd->security_ctx->master_access & PRIV_KILL_OTHER_USER_PROCESS) ||
9303         thd->security_ctx->user_matches(tmp->security_ctx))
9304 #endif /* WITH_WSREP */
9305     {
9306 #ifdef WITH_WSREP
9307       DEBUG_SYNC(thd, "before_awake_no_mutex");
9308       if (tmp->wsrep_aborter && tmp->wsrep_aborter != thd->thread_id)
9309       {
9310         /* victim is in hit list already, bail out */
9311 	WSREP_DEBUG("victim %llu has wsrep aborter: %lu, skipping awake()",
9312 		    id, tmp->wsrep_aborter);
9313         error= 0;
9314       }
9315       else
9316 #endif /* WITH_WSREP */
9317       {
9318         WSREP_DEBUG("kill_one_thread victim: %llu wsrep_aborter %lu by signal %d",
9319                     id, tmp->wsrep_aborter, kill_signal);
9320         tmp->awake_no_mutex(kill_signal);
9321         error= 0;
9322       }
9323     }
9324     else
9325       error= (type == KILL_TYPE_QUERY ? ER_KILL_QUERY_DENIED_ERROR :
9326                                         ER_KILL_DENIED_ERROR);
9327 
9328     mysql_mutex_unlock(&tmp->LOCK_thd_data);
9329   }
9330   mysql_mutex_unlock(&tmp->LOCK_thd_kill);
9331   DBUG_PRINT("exit", ("%d", error));
9332   DBUG_RETURN(error);
9333 }
9334 
9335 
9336 /**
9337   kill all threads from one user
9338 
9339   @param thd			Thread class
9340   @param user_name		User name for threads we should kill
9341   @param only_kill_query        Should it kill the query or the connection
9342 
9343   @note
9344     If we can't kill all threads because of security issues, no threads
9345     are killed.
9346 */
9347 
9348 struct kill_threads_callback_arg
9349 {
kill_threads_callback_argkill_threads_callback_arg9350   kill_threads_callback_arg(THD *thd_arg, LEX_USER *user_arg):
9351     thd(thd_arg), user(user_arg) {}
9352   THD *thd;
9353   LEX_USER *user;
9354   List<THD> threads_to_kill;
9355 };
9356 
9357 
kill_threads_callback(THD * thd,kill_threads_callback_arg * arg)9358 static my_bool kill_threads_callback(THD *thd, kill_threads_callback_arg *arg)
9359 {
9360   if (thd->security_ctx->user)
9361   {
9362     /*
9363       Check that hostname (if given) and user name matches.
9364 
9365       host.str[0] == '%' means that host name was not given. See sql_yacc.yy
9366     */
9367     if (((arg->user->host.str[0] == '%' && !arg->user->host.str[1]) ||
9368          !strcmp(thd->security_ctx->host_or_ip, arg->user->host.str)) &&
9369         !strcmp(thd->security_ctx->user, arg->user->user.str))
9370     {
9371       if (!(arg->thd->security_ctx->master_access &
9372             PRIV_KILL_OTHER_USER_PROCESS) &&
9373           !arg->thd->security_ctx->user_matches(thd->security_ctx))
9374         return 1;
9375       if (!arg->threads_to_kill.push_back(thd, arg->thd->mem_root))
9376       {
9377         mysql_mutex_lock(&thd->LOCK_thd_kill); // Lock from delete
9378         mysql_mutex_lock(&thd->LOCK_thd_data);
9379       }
9380     }
9381   }
9382   return 0;
9383 }
9384 
9385 
kill_threads_for_user(THD * thd,LEX_USER * user,killed_state kill_signal,ha_rows * rows)9386 static uint kill_threads_for_user(THD *thd, LEX_USER *user,
9387                                   killed_state kill_signal, ha_rows *rows)
9388 {
9389   kill_threads_callback_arg arg(thd, user);
9390   DBUG_ENTER("kill_threads_for_user");
9391 
9392   *rows= 0;
9393 
9394   if (unlikely(thd->is_fatal_error))        // If we run out of memory
9395     DBUG_RETURN(ER_OUT_OF_RESOURCES);
9396 
9397   DBUG_PRINT("enter", ("user: %s  signal: %u", user->user.str,
9398                        (uint) kill_signal));
9399 
9400   if (server_threads.iterate(kill_threads_callback, &arg))
9401     DBUG_RETURN(ER_KILL_DENIED_ERROR);
9402 
9403   if (!arg.threads_to_kill.is_empty())
9404   {
9405     List_iterator_fast<THD> it2(arg.threads_to_kill);
9406     THD *next_ptr;
9407     THD *ptr= it2++;
9408     do
9409     {
9410       ptr->awake_no_mutex(kill_signal);
9411       /*
9412         Careful here: The list nodes are allocated on the memroots of the
9413         THDs to be awakened.
9414         But those THDs may be terminated and deleted as soon as we release
9415         LOCK_thd_kill, which will make the list nodes invalid.
9416         Since the operation "it++" dereferences the "next" pointer of the
9417         previous list node, we need to do this while holding LOCK_thd_kill.
9418       */
9419       next_ptr= it2++;
9420       mysql_mutex_unlock(&ptr->LOCK_thd_kill);
9421       mysql_mutex_unlock(&ptr->LOCK_thd_data);
9422       (*rows)++;
9423     } while ((ptr= next_ptr));
9424   }
9425   DBUG_RETURN(0);
9426 }
9427 
9428 
9429 /**
9430   kills a thread and sends response.
9431 
9432   @param thd                    Thread class
9433   @param id                     Thread id or query id
9434   @param state                  Should it kill the query or the connection
9435   @param type                   Type of id: thread id or query id
9436 */
9437 
9438 static
sql_kill(THD * thd,longlong id,killed_state state,killed_type type)9439 void sql_kill(THD *thd, longlong id, killed_state state, killed_type type)
9440 {
9441   uint error;
9442 #ifdef WITH_WSREP
9443   if (WSREP(thd))
9444   {
9445     WSREP_DEBUG("sql_kill called");
9446     if (thd->wsrep_applier)
9447     {
9448       WSREP_DEBUG("KILL in applying, bailing out here");
9449       return;
9450     }
9451     WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
9452   }
9453 #endif /* WITH_WSREP */
9454   if (likely(!(error= kill_one_thread(thd, id, state, type))))
9455   {
9456     if (!thd->killed)
9457       my_ok(thd);
9458     else
9459       thd->send_kill_message();
9460   }
9461   else
9462     my_error(error, MYF(0), id);
9463 #ifdef WITH_WSREP
9464   return;
9465  wsrep_error_label:
9466   error= (type == KILL_TYPE_QUERY ? ER_KILL_QUERY_DENIED_ERROR :
9467                                     ER_KILL_DENIED_ERROR);
9468   my_error(error, MYF(0), id);
9469 #endif /* WITH_WSREP */
9470 }
9471 
9472 
9473 static void __attribute__ ((noinline))
sql_kill_user(THD * thd,LEX_USER * user,killed_state state)9474 sql_kill_user(THD *thd, LEX_USER *user, killed_state state)
9475 {
9476   uint error;
9477   ha_rows rows;
9478 #ifdef WITH_WSREP
9479   if (WSREP(thd))
9480   {
9481     WSREP_DEBUG("sql_kill_user called");
9482     if (thd->wsrep_applier)
9483     {
9484       WSREP_DEBUG("KILL in applying, bailing out here");
9485       return;
9486     }
9487     WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
9488   }
9489 #endif /* WITH_WSREP */
9490   if (likely(!(error= kill_threads_for_user(thd, user, state, &rows))))
9491     my_ok(thd, rows);
9492   else
9493   {
9494     /*
9495       This is probably ER_OUT_OF_RESOURCES, but in the future we may
9496       want to write the name of the user we tried to kill
9497     */
9498     my_error(error, MYF(0), user->host.str, user->user.str);
9499   }
9500 #ifdef WITH_WSREP
9501   return;
9502  wsrep_error_label:
9503   my_error(ER_CANNOT_USER, MYF(0), user ? user->user.str : "NULL");
9504 #endif /* WITH_WSREP */
9505 }
9506 
9507 
9508 /** If pointer is not a null pointer, append filename to it. */
9509 
append_file_to_dir(THD * thd,const char ** filename_ptr,const LEX_CSTRING * table_name)9510 bool append_file_to_dir(THD *thd, const char **filename_ptr,
9511                         const LEX_CSTRING *table_name)
9512 {
9513   char buff[FN_REFLEN],*ptr, *end;
9514   if (!*filename_ptr)
9515     return 0;					// nothing to do
9516 
9517   /* Check that the filename is not too long and it's a hard path */
9518   if (strlen(*filename_ptr)+table_name->length >= FN_REFLEN-1 ||
9519       !test_if_hard_path(*filename_ptr))
9520   {
9521     my_error(ER_WRONG_TABLE_NAME, MYF(0), *filename_ptr);
9522     return 1;
9523   }
9524   /* Fix is using unix filename format on dos */
9525   strmov(buff,*filename_ptr);
9526   end=convert_dirname(buff, *filename_ptr, NullS);
9527   if (unlikely(!(ptr= (char*) thd->alloc((size_t) (end-buff) +
9528                                          table_name->length + 1))))
9529     return 1;					// End of memory
9530   *filename_ptr=ptr;
9531   strxmov(ptr,buff,table_name->str,NullS);
9532   return 0;
9533 }
9534 
9535 
comp_eq_creator(bool invert)9536 Comp_creator *comp_eq_creator(bool invert)
9537 {
9538   return invert?(Comp_creator *)&ne_creator:(Comp_creator *)&eq_creator;
9539 }
9540 
9541 
comp_ge_creator(bool invert)9542 Comp_creator *comp_ge_creator(bool invert)
9543 {
9544   return invert?(Comp_creator *)&lt_creator:(Comp_creator *)&ge_creator;
9545 }
9546 
9547 
comp_gt_creator(bool invert)9548 Comp_creator *comp_gt_creator(bool invert)
9549 {
9550   return invert?(Comp_creator *)&le_creator:(Comp_creator *)&gt_creator;
9551 }
9552 
9553 
comp_le_creator(bool invert)9554 Comp_creator *comp_le_creator(bool invert)
9555 {
9556   return invert?(Comp_creator *)&gt_creator:(Comp_creator *)&le_creator;
9557 }
9558 
9559 
comp_lt_creator(bool invert)9560 Comp_creator *comp_lt_creator(bool invert)
9561 {
9562   return invert?(Comp_creator *)&ge_creator:(Comp_creator *)&lt_creator;
9563 }
9564 
9565 
comp_ne_creator(bool invert)9566 Comp_creator *comp_ne_creator(bool invert)
9567 {
9568   return invert?(Comp_creator *)&eq_creator:(Comp_creator *)&ne_creator;
9569 }
9570 
9571 
9572 /**
9573   Construct ALL/ANY/SOME subquery Item.
9574 
9575   @param left_expr   pointer to left expression
9576   @param cmp         compare function creator
9577   @param all         true if we create ALL subquery
9578   @param select_lex  pointer on parsed subquery structure
9579 
9580   @return
9581     constructed Item (or 0 if out of memory)
9582 */
all_any_subquery_creator(THD * thd,Item * left_expr,chooser_compare_func_creator cmp,bool all,SELECT_LEX * select_lex)9583 Item * all_any_subquery_creator(THD *thd, Item *left_expr,
9584 				chooser_compare_func_creator cmp,
9585 				bool all,
9586 				SELECT_LEX *select_lex)
9587 {
9588   if ((cmp == &comp_eq_creator) && !all)       //  = ANY <=> IN
9589     return new (thd->mem_root) Item_in_subselect(thd, left_expr, select_lex);
9590 
9591   if ((cmp == &comp_ne_creator) && all)        // <> ALL <=> NOT IN
9592     return new (thd->mem_root) Item_func_not(thd,
9593              new (thd->mem_root) Item_in_subselect(thd, left_expr, select_lex));
9594 
9595   Item_allany_subselect *it=
9596     new (thd->mem_root) Item_allany_subselect(thd, left_expr, cmp, select_lex,
9597                                               all);
9598   if (all) /* ALL */
9599     return it->upper_item= new (thd->mem_root) Item_func_not_all(thd, it);
9600 
9601   /* ANY/SOME */
9602   return it->upper_item= new (thd->mem_root) Item_func_nop_all(thd, it);
9603 }
9604 
9605 
9606 /**
9607   Multi update query pre-check.
9608 
9609   @param thd		Thread handler
9610   @param tables	Global/local table list (have to be the same)
9611 
9612   @retval
9613     FALSE OK
9614   @retval
9615     TRUE  Error
9616 */
9617 
multi_update_precheck(THD * thd,TABLE_LIST * tables)9618 bool multi_update_precheck(THD *thd, TABLE_LIST *tables)
9619 {
9620   TABLE_LIST *table;
9621   LEX *lex= thd->lex;
9622   SELECT_LEX *select_lex= lex->first_select_lex();
9623   DBUG_ENTER("multi_update_precheck");
9624 
9625   if (select_lex->item_list.elements != lex->value_list.elements)
9626   {
9627     my_message(ER_WRONG_VALUE_COUNT, ER_THD(thd, ER_WRONG_VALUE_COUNT), MYF(0));
9628     DBUG_RETURN(TRUE);
9629   }
9630   /*
9631     Ensure that we have UPDATE or SELECT privilege for each table
9632     The exact privilege is checked in mysql_multi_update()
9633   */
9634   for (table= tables; table; table= table->next_local)
9635   {
9636     if (table->is_jtbm())
9637       continue;
9638     if (table->derived)
9639       table->grant.privilege= SELECT_ACL;
9640     else if ((check_access(thd, UPDATE_ACL, table->db.str,
9641                            &table->grant.privilege,
9642                            &table->grant.m_internal,
9643                            0, 1) ||
9644               check_grant(thd, UPDATE_ACL, table, FALSE, 1, TRUE)) &&
9645              (check_access(thd, SELECT_ACL, table->db.str,
9646                            &table->grant.privilege,
9647                            &table->grant.m_internal,
9648                            0, 0) ||
9649               check_grant(thd, SELECT_ACL, table, FALSE, 1, FALSE)))
9650       DBUG_RETURN(TRUE);
9651 
9652     table->grant.orig_want_privilege= NO_ACL;
9653     table->table_in_first_from_clause= 1;
9654   }
9655   /*
9656     Is there tables of subqueries?
9657   */
9658   if (lex->first_select_lex() != lex->all_selects_list)
9659   {
9660     DBUG_PRINT("info",("Checking sub query list"));
9661     for (table= tables; table; table= table->next_global)
9662     {
9663       if (!table->table_in_first_from_clause)
9664       {
9665 	if (check_access(thd, SELECT_ACL, table->db.str,
9666                          &table->grant.privilege,
9667                          &table->grant.m_internal,
9668                          0, 0) ||
9669 	    check_grant(thd, SELECT_ACL, table, FALSE, 1, FALSE))
9670 	  DBUG_RETURN(TRUE);
9671       }
9672     }
9673   }
9674 
9675   DBUG_RETURN(FALSE);
9676 }
9677 
9678 /**
9679   Multi delete query pre-check.
9680 
9681   @param thd			Thread handler
9682   @param tables		Global/local table list
9683 
9684   @retval
9685     FALSE OK
9686   @retval
9687     TRUE  error
9688 */
9689 
multi_delete_precheck(THD * thd,TABLE_LIST * tables)9690 bool multi_delete_precheck(THD *thd, TABLE_LIST *tables)
9691 {
9692   SELECT_LEX *select_lex= thd->lex->first_select_lex();
9693   TABLE_LIST *aux_tables= thd->lex->auxiliary_table_list.first;
9694   TABLE_LIST **save_query_tables_own_last= thd->lex->query_tables_own_last;
9695   DBUG_ENTER("multi_delete_precheck");
9696 
9697   /*
9698     Temporary tables are pre-opened in 'tables' list only. Here we need to
9699     initialize TABLE instances in 'aux_tables' list.
9700   */
9701   for (TABLE_LIST *tl= aux_tables; tl; tl= tl->next_global)
9702   {
9703     if (tl->table)
9704       continue;
9705 
9706     if (tl->correspondent_table)
9707       tl->table= tl->correspondent_table->table;
9708   }
9709 
9710   /* sql_yacc guarantees that tables and aux_tables are not zero */
9711   DBUG_ASSERT(aux_tables != 0);
9712   if (check_table_access(thd, SELECT_ACL, tables, FALSE, UINT_MAX, FALSE))
9713     DBUG_RETURN(TRUE);
9714 
9715   /*
9716     Since aux_tables list is not part of LEX::query_tables list we
9717     have to juggle with LEX::query_tables_own_last value to be able
9718     call check_table_access() safely.
9719   */
9720   thd->lex->query_tables_own_last= 0;
9721   if (check_table_access(thd, DELETE_ACL, aux_tables, FALSE, UINT_MAX, FALSE))
9722   {
9723     thd->lex->query_tables_own_last= save_query_tables_own_last;
9724     DBUG_RETURN(TRUE);
9725   }
9726   thd->lex->query_tables_own_last= save_query_tables_own_last;
9727 
9728   if ((thd->variables.option_bits & OPTION_SAFE_UPDATES) && !select_lex->where)
9729   {
9730     my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
9731                ER_THD(thd, ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
9732     DBUG_RETURN(TRUE);
9733   }
9734   DBUG_RETURN(FALSE);
9735 }
9736 
9737 
9738 /*
9739   Given a table in the source list, find a correspondent table in the
9740   table references list.
9741 
9742   @param lex Pointer to LEX representing multi-delete.
9743   @param src Source table to match.
9744   @param ref Table references list.
9745 
9746   @remark The source table list (tables listed before the FROM clause
9747   or tables listed in the FROM clause before the USING clause) may
9748   contain table names or aliases that must match unambiguously one,
9749   and only one, table in the target table list (table references list,
9750   after FROM/USING clause).
9751 
9752   @return Matching table, NULL otherwise.
9753 */
9754 
multi_delete_table_match(LEX * lex,TABLE_LIST * tbl,TABLE_LIST * tables)9755 static TABLE_LIST *multi_delete_table_match(LEX *lex, TABLE_LIST *tbl,
9756                                             TABLE_LIST *tables)
9757 {
9758   TABLE_LIST *match= NULL;
9759   DBUG_ENTER("multi_delete_table_match");
9760 
9761   for (TABLE_LIST *elem= tables; elem; elem= elem->next_local)
9762   {
9763     int res;
9764 
9765     if (tbl->is_fqtn && elem->is_alias)
9766       continue; /* no match */
9767     if (tbl->is_fqtn && elem->is_fqtn)
9768       res= (my_strcasecmp(table_alias_charset, tbl->table_name.str, elem->table_name.str) ||
9769             cmp(&tbl->db, &elem->db));
9770     else if (elem->is_alias)
9771       res= my_strcasecmp(table_alias_charset, tbl->alias.str, elem->alias.str);
9772     else
9773       res= (my_strcasecmp(table_alias_charset, tbl->table_name.str, elem->table_name.str) ||
9774             cmp(&tbl->db, &elem->db));
9775 
9776     if (res)
9777       continue;
9778 
9779     if (match)
9780     {
9781       my_error(ER_NONUNIQ_TABLE, MYF(0), elem->alias.str);
9782       DBUG_RETURN(NULL);
9783     }
9784 
9785     match= elem;
9786   }
9787 
9788   if (!match)
9789     my_error(ER_UNKNOWN_TABLE, MYF(0), tbl->table_name.str, "MULTI DELETE");
9790 
9791   DBUG_RETURN(match);
9792 }
9793 
9794 
9795 /**
9796   Link tables in auxilary table list of multi-delete with corresponding
9797   elements in main table list, and set proper locks for them.
9798 
9799   @param lex   pointer to LEX representing multi-delete
9800 
9801   @retval
9802     FALSE   success
9803   @retval
9804     TRUE    error
9805 */
9806 
multi_delete_set_locks_and_link_aux_tables(LEX * lex)9807 bool multi_delete_set_locks_and_link_aux_tables(LEX *lex)
9808 {
9809   TABLE_LIST *tables= lex->first_select_lex()->table_list.first;
9810   TABLE_LIST *target_tbl;
9811   DBUG_ENTER("multi_delete_set_locks_and_link_aux_tables");
9812 
9813   lex->table_count= 0;
9814 
9815   for (target_tbl= lex->auxiliary_table_list.first;
9816        target_tbl; target_tbl= target_tbl->next_local)
9817   {
9818     lex->table_count++;
9819     /* All tables in aux_tables must be found in FROM PART */
9820     TABLE_LIST *walk= multi_delete_table_match(lex, target_tbl, tables);
9821     if (!walk)
9822       DBUG_RETURN(TRUE);
9823     if (!walk->derived)
9824       target_tbl->table_name= walk->table_name;
9825     walk->updating= target_tbl->updating;
9826     walk->lock_type= target_tbl->lock_type;
9827     /* We can assume that tables to be deleted from are locked for write. */
9828     DBUG_ASSERT(walk->lock_type >= TL_WRITE_ALLOW_WRITE);
9829     walk->mdl_request.set_type(MDL_SHARED_WRITE);
9830     target_tbl->correspondent_table= walk;	// Remember corresponding table
9831   }
9832   DBUG_RETURN(FALSE);
9833 }
9834 
9835 
9836 /**
9837   simple UPDATE query pre-check.
9838 
9839   @param thd		Thread handler
9840   @param tables	Global table list
9841 
9842   @retval
9843     FALSE OK
9844   @retval
9845     TRUE  Error
9846 */
9847 
update_precheck(THD * thd,TABLE_LIST * tables)9848 bool update_precheck(THD *thd, TABLE_LIST *tables)
9849 {
9850   DBUG_ENTER("update_precheck");
9851   if (thd->lex->first_select_lex()->item_list.elements !=
9852       thd->lex->value_list.elements)
9853   {
9854     my_message(ER_WRONG_VALUE_COUNT, ER_THD(thd, ER_WRONG_VALUE_COUNT), MYF(0));
9855     DBUG_RETURN(TRUE);
9856   }
9857   DBUG_RETURN(check_one_table_access(thd, UPDATE_ACL, tables));
9858 }
9859 
9860 
9861 /**
9862   simple DELETE query pre-check.
9863 
9864   @param thd		Thread handler
9865   @param tables	Global table list
9866 
9867   @retval
9868     FALSE  OK
9869   @retval
9870     TRUE   error
9871 */
9872 
delete_precheck(THD * thd,TABLE_LIST * tables)9873 bool delete_precheck(THD *thd, TABLE_LIST *tables)
9874 {
9875   DBUG_ENTER("delete_precheck");
9876   if (tables->vers_conditions.delete_history)
9877   {
9878     if (check_one_table_access(thd, DELETE_HISTORY_ACL, tables))
9879       DBUG_RETURN(TRUE);
9880   }
9881   else
9882   {
9883     if (check_one_table_access(thd, DELETE_ACL, tables))
9884       DBUG_RETURN(TRUE);
9885     /* Set privilege for the WHERE clause */
9886     tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege);
9887   }
9888   DBUG_RETURN(FALSE);
9889 }
9890 
9891 
9892 /**
9893   simple INSERT query pre-check.
9894 
9895   @param thd		Thread handler
9896   @param tables	Global table list
9897 
9898   @retval
9899     FALSE  OK
9900   @retval
9901     TRUE   error
9902 */
9903 
insert_precheck(THD * thd,TABLE_LIST * tables)9904 bool insert_precheck(THD *thd, TABLE_LIST *tables)
9905 {
9906   LEX *lex= thd->lex;
9907   DBUG_ENTER("insert_precheck");
9908 
9909   /*
9910     Check that we have modify privileges for the first table and
9911     select privileges for the rest
9912   */
9913   privilege_t privilege= (INSERT_ACL |
9914                     (lex->duplicates == DUP_REPLACE ? DELETE_ACL : NO_ACL) |
9915                     (lex->value_list.elements ? UPDATE_ACL : NO_ACL));
9916 
9917   if (check_one_table_access(thd, privilege, tables))
9918     DBUG_RETURN(TRUE);
9919 
9920   if (lex->update_list.elements != lex->value_list.elements)
9921   {
9922     my_message(ER_WRONG_VALUE_COUNT, ER_THD(thd, ER_WRONG_VALUE_COUNT), MYF(0));
9923     DBUG_RETURN(TRUE);
9924   }
9925   DBUG_RETURN(FALSE);
9926 }
9927 
9928 
9929 /**
9930    Set proper open mode and table type for element representing target table
9931    of CREATE TABLE statement, also adjust statement table list if necessary.
9932 */
9933 
create_table_set_open_action_and_adjust_tables(LEX * lex)9934 void create_table_set_open_action_and_adjust_tables(LEX *lex)
9935 {
9936   TABLE_LIST *create_table= lex->query_tables;
9937 
9938   if (lex->tmp_table())
9939     create_table->open_type= OT_TEMPORARY_ONLY;
9940   else
9941     create_table->open_type= OT_BASE_ONLY;
9942 
9943   if (!lex->first_select_lex()->item_list.elements)
9944   {
9945     /*
9946       Avoid opening and locking target table for ordinary CREATE TABLE
9947       or CREATE TABLE LIKE for write (unlike in CREATE ... SELECT we
9948       won't do any insertions in it anyway). Not doing this causes
9949       problems when running CREATE TABLE IF NOT EXISTS for already
9950       existing log table.
9951     */
9952     create_table->lock_type= TL_READ;
9953   }
9954 }
9955 
9956 
9957 /**
9958   CREATE TABLE query pre-check.
9959 
9960   @param thd			Thread handler
9961   @param tables		Global table list
9962   @param create_table	        Table which will be created
9963 
9964   @retval
9965     FALSE   OK
9966   @retval
9967     TRUE   Error
9968 */
9969 
create_table_precheck(THD * thd,TABLE_LIST * tables,TABLE_LIST * create_table)9970 bool create_table_precheck(THD *thd, TABLE_LIST *tables,
9971                            TABLE_LIST *create_table)
9972 {
9973   LEX *lex= thd->lex;
9974   SELECT_LEX *select_lex= lex->first_select_lex();
9975   privilege_t want_priv(NO_ACL);
9976   bool error= TRUE;                                 // Error message is given
9977   DBUG_ENTER("create_table_precheck");
9978 
9979   /*
9980     Require CREATE [TEMPORARY] privilege on new table; for
9981     CREATE TABLE ... SELECT, also require INSERT.
9982   */
9983 
9984   want_priv= lex->tmp_table() ? CREATE_TMP_ACL :
9985              (CREATE_ACL | (select_lex->item_list.elements ? INSERT_ACL : NO_ACL));
9986 
9987   /* CREATE OR REPLACE on not temporary tables require DROP_ACL */
9988   if (lex->create_info.or_replace() && !lex->tmp_table())
9989     want_priv|= DROP_ACL;
9990 
9991   if (check_access(thd, want_priv, create_table->db.str,
9992                    &create_table->grant.privilege,
9993                    &create_table->grant.m_internal,
9994                    0, 0))
9995     goto err;
9996 
9997   /* If it is a merge table, check privileges for merge children. */
9998   if (lex->create_info.merge_list)
9999   {
10000     /*
10001       The user must have (SELECT_ACL | UPDATE_ACL | DELETE_ACL) on the
10002       underlying base tables, even if there are temporary tables with the same
10003       names.
10004 
10005       From user's point of view, it might look as if the user must have these
10006       privileges on temporary tables to create a merge table over them. This is
10007       one of two cases when a set of privileges is required for operations on
10008       temporary tables (see also CREATE TABLE).
10009 
10010       The reason for this behavior stems from the following facts:
10011 
10012         - For merge tables, the underlying table privileges are checked only
10013           at CREATE TABLE / ALTER TABLE time.
10014 
10015           In other words, once a merge table is created, the privileges of
10016           the underlying tables can be revoked, but the user will still have
10017           access to the merge table (provided that the user has privileges on
10018           the merge table itself).
10019 
10020         - Temporary tables shadow base tables.
10021 
10022           I.e. there might be temporary and base tables with the same name, and
10023           the temporary table takes the precedence in all operations.
10024 
10025         - For temporary MERGE tables we do not track if their child tables are
10026           base or temporary. As result we can't guarantee that privilege check
10027           which was done in presence of temporary child will stay relevant
10028           later as this temporary table might be removed.
10029 
10030       If SELECT_ACL | UPDATE_ACL | DELETE_ACL privileges were not checked for
10031       the underlying *base* tables, it would create a security breach as in
10032       Bug#12771903.
10033     */
10034 
10035     if (check_table_access(thd, SELECT_ACL | UPDATE_ACL | DELETE_ACL,
10036                            lex->create_info.merge_list, FALSE, UINT_MAX, FALSE))
10037       goto err;
10038   }
10039 
10040   if (want_priv != CREATE_TMP_ACL &&
10041       check_grant(thd, want_priv, create_table, FALSE, 1, FALSE))
10042     goto err;
10043 
10044   if (select_lex->item_list.elements)
10045   {
10046     /* Check permissions for used tables in CREATE TABLE ... SELECT */
10047     if (tables && check_table_access(thd, SELECT_ACL, tables, FALSE,
10048                                      UINT_MAX, FALSE))
10049       goto err;
10050   }
10051   else if (lex->create_info.like())
10052   {
10053     if (check_table_access(thd, SELECT_ACL, tables, FALSE, UINT_MAX, FALSE))
10054       goto err;
10055   }
10056 
10057   if (check_fk_parent_table_access(thd, &lex->create_info, &lex->alter_info,
10058                                    create_table->db.str))
10059     goto err;
10060 
10061   error= FALSE;
10062 
10063 err:
10064   DBUG_RETURN(error);
10065 }
10066 
10067 
10068 /**
10069   Check privileges for LOCK TABLES statement.
10070 
10071   @param thd     Thread context.
10072   @param tables  List of tables to be locked.
10073 
10074   @retval FALSE - Success.
10075   @retval TRUE  - Failure.
10076 */
10077 
lock_tables_precheck(THD * thd,TABLE_LIST * tables)10078 static bool lock_tables_precheck(THD *thd, TABLE_LIST *tables)
10079 {
10080   TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table();
10081 
10082   for (TABLE_LIST *table= tables; table != first_not_own_table && table;
10083        table= table->next_global)
10084   {
10085     if (is_temporary_table(table))
10086       continue;
10087 
10088     if (check_table_access(thd, PRIV_LOCK_TABLES, table,
10089                            FALSE, 1, FALSE))
10090       return TRUE;
10091   }
10092 
10093   return FALSE;
10094 }
10095 
10096 
10097 /**
10098   negate given expression.
10099 
10100   @param thd  thread handler
10101   @param expr expression for negation
10102 
10103   @return
10104     negated expression
10105 */
10106 
negate_expression(THD * thd,Item * expr)10107 Item *negate_expression(THD *thd, Item *expr)
10108 {
10109   Item *negated;
10110   if (expr->type() == Item::FUNC_ITEM &&
10111       ((Item_func *) expr)->functype() == Item_func::NOT_FUNC)
10112   {
10113     /* it is NOT(NOT( ... )) */
10114     Item *arg= ((Item_func *) expr)->arguments()[0];
10115     const Type_handler *fh= arg->fixed_type_handler();
10116     enum_parsing_place place= thd->lex->current_select->parsing_place;
10117     if ((fh && fh->is_bool_type()) || place == IN_WHERE || place == IN_HAVING)
10118       return arg;
10119     /*
10120       if it is not boolean function then we have to emulate value of
10121       not(not(a)), it will be a != 0
10122     */
10123     return new (thd->mem_root) Item_func_ne(thd, arg, new (thd->mem_root) Item_int(thd, (char*) "0", 0, 1));
10124   }
10125 
10126   if ((negated= expr->neg_transformer(thd)) != 0)
10127     return negated;
10128   return new (thd->mem_root) Item_func_not(thd, expr);
10129 }
10130 
10131 /**
10132   Set the specified definer to the default value, which is the
10133   current user in the thread.
10134 
10135   @param[in]  thd       thread handler
10136   @param[out] definer   definer
10137 */
10138 
get_default_definer(THD * thd,LEX_USER * definer,bool role)10139 void get_default_definer(THD *thd, LEX_USER *definer, bool role)
10140 {
10141   const Security_context *sctx= thd->security_ctx;
10142 
10143   if (role)
10144   {
10145     definer->user.str= const_cast<char*>(sctx->priv_role);
10146     definer->host= empty_clex_str;
10147   }
10148   else
10149   {
10150     definer->user.str= const_cast<char*>(sctx->priv_user);
10151     definer->host.str= const_cast<char*>(sctx->priv_host);
10152     definer->host.length= strlen(definer->host.str);
10153   }
10154   definer->user.length= strlen(definer->user.str);
10155   definer->auth= NULL;
10156 }
10157 
10158 
10159 /**
10160   Create default definer for the specified THD.
10161 
10162   @param[in] thd         thread handler
10163 
10164   @return
10165     - On success, return a valid pointer to the created and initialized
10166     LEX_USER, which contains definer information.
10167     - On error, return 0.
10168 */
10169 
create_default_definer(THD * thd,bool role)10170 LEX_USER *create_default_definer(THD *thd, bool role)
10171 {
10172   LEX_USER *definer;
10173 
10174   if (unlikely(! (definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER)))))
10175     return 0;
10176 
10177   thd->get_definer(definer, role);
10178 
10179   if (role && definer->user.length == 0)
10180   {
10181     my_error(ER_MALFORMED_DEFINER, MYF(0));
10182     return 0;
10183   }
10184   else
10185     return definer;
10186 }
10187 
10188 
10189 /**
10190   Create definer with the given user and host names.
10191 
10192   @param[in] thd          thread handler
10193   @param[in] user_name    user name
10194   @param[in] host_name    host name
10195 
10196   @return
10197     - On success, return a valid pointer to the created and initialized
10198     LEX_USER, which contains definer information.
10199     - On error, return 0.
10200 */
10201 
create_definer(THD * thd,LEX_CSTRING * user_name,LEX_CSTRING * host_name)10202 LEX_USER *create_definer(THD *thd, LEX_CSTRING *user_name,
10203                          LEX_CSTRING *host_name)
10204 {
10205   LEX_USER *definer;
10206 
10207   /* Create and initialize. */
10208 
10209   if (unlikely(!(definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER)))))
10210     return 0;
10211 
10212   definer->user= *user_name;
10213   definer->host= *host_name;
10214   definer->auth= NULL;
10215 
10216   return definer;
10217 }
10218 
10219 
10220 /**
10221   Check that byte length of a string does not exceed some limit.
10222 
10223   @param str         string to be checked
10224   @param err_msg     Number of error message to be displayed if the string
10225 		     is too long.  0 if empty error message.
10226   @param max_length  max length
10227 
10228   @retval
10229     FALSE   the passed string is not longer than max_length
10230   @retval
10231     TRUE    the passed string is longer than max_length
10232 
10233   NOTE
10234     The function is not used in existing code but can be useful later?
10235 */
10236 
check_string_byte_length(const LEX_CSTRING * str,uint err_msg,size_t max_byte_length)10237 bool check_string_byte_length(const LEX_CSTRING *str, uint err_msg,
10238                               size_t max_byte_length)
10239 {
10240   if (str->length <= max_byte_length)
10241     return FALSE;
10242 
10243   my_error(ER_WRONG_STRING_LENGTH, MYF(0), str->str,
10244            err_msg ? ER(err_msg) : "", max_byte_length);
10245 
10246   return TRUE;
10247 }
10248 
10249 
10250 /*
10251   Check that char length of a string does not exceed some limit.
10252 
10253   SYNOPSIS
10254   check_string_char_length()
10255       str              string to be checked
10256       err_msg          Number of error message to be displayed if the string
10257 		       is too long.  0 if empty error message.
10258       max_char_length  max length in symbols
10259       cs               string charset
10260 
10261   RETURN
10262     FALSE   the passed string is not longer than max_char_length
10263     TRUE    the passed string is longer than max_char_length
10264 */
10265 
10266 
check_string_char_length(const LEX_CSTRING * str,uint err_msg,size_t max_char_length,CHARSET_INFO * cs,bool no_error)10267 bool check_string_char_length(const LEX_CSTRING *str, uint err_msg,
10268                               size_t max_char_length, CHARSET_INFO *cs,
10269                               bool no_error)
10270 {
10271   Well_formed_prefix prefix(cs, str->str, str->length, max_char_length);
10272   if (likely(!prefix.well_formed_error_pos() &&
10273              str->length == prefix.length()))
10274     return FALSE;
10275 
10276   if (!no_error)
10277   {
10278     ErrConvString err(str->str, str->length, cs);
10279     my_error(ER_WRONG_STRING_LENGTH, MYF(0), err.ptr(),
10280              err_msg ? ER(err_msg) : "",
10281              max_char_length);
10282   }
10283   return TRUE;
10284 }
10285 
10286 
check_ident_length(const LEX_CSTRING * ident)10287 bool check_ident_length(const LEX_CSTRING *ident)
10288 {
10289   if (check_string_char_length(ident, 0, NAME_CHAR_LEN, system_charset_info, 1))
10290   {
10291     my_error(ER_TOO_LONG_IDENT, MYF(0), ident->str);
10292     return 1;
10293   }
10294   return 0;
10295 }
10296 
10297 
10298 /*
10299   Check if path does not contain mysql data home directory
10300 
10301   SYNOPSIS
10302     path_starts_from_data_home_dir()
10303     dir                     directory, with all symlinks resolved
10304 
10305   RETURN VALUES
10306     0	ok
10307     1	error ;  Given path contains data directory
10308 */
10309 extern "C" {
10310 
path_starts_from_data_home_dir(const char * path)10311 int path_starts_from_data_home_dir(const char *path)
10312 {
10313   size_t dir_len= strlen(path);
10314   DBUG_ENTER("path_starts_from_data_home_dir");
10315 
10316   if (mysql_unpacked_real_data_home_len<= dir_len)
10317   {
10318     if (dir_len > mysql_unpacked_real_data_home_len &&
10319         path[mysql_unpacked_real_data_home_len] != FN_LIBCHAR)
10320       DBUG_RETURN(0);
10321 
10322     if (lower_case_file_system)
10323     {
10324       if (!default_charset_info->strnncoll(path,
10325                                            mysql_unpacked_real_data_home_len,
10326                                            mysql_unpacked_real_data_home,
10327                                            mysql_unpacked_real_data_home_len))
10328       {
10329         DBUG_PRINT("error", ("Path is part of mysql_real_data_home"));
10330         DBUG_RETURN(1);
10331       }
10332     }
10333     else if (!memcmp(path, mysql_unpacked_real_data_home,
10334                      mysql_unpacked_real_data_home_len))
10335     {
10336       DBUG_PRINT("error", ("Path is part of mysql_real_data_home"));
10337       DBUG_RETURN(1);
10338     }
10339   }
10340   DBUG_RETURN(0);
10341 }
10342 
10343 }
10344 
10345 /*
10346   Check if path does not contain mysql data home directory
10347 
10348   SYNOPSIS
10349     test_if_data_home_dir()
10350     dir                     directory
10351 
10352   RETURN VALUES
10353     0	ok
10354     1	error ;  Given path contains data directory
10355 */
10356 
test_if_data_home_dir(const char * dir)10357 int test_if_data_home_dir(const char *dir)
10358 {
10359   char path[FN_REFLEN];
10360   DBUG_ENTER("test_if_data_home_dir");
10361 
10362   if (!dir)
10363     DBUG_RETURN(0);
10364 
10365   (void) fn_format(path, dir, "", "", MY_RETURN_REAL_PATH);
10366   DBUG_RETURN(path_starts_from_data_home_dir(path));
10367 }
10368 
10369 
error_if_data_home_dir(const char * path,const char * what)10370 int error_if_data_home_dir(const char *path, const char *what)
10371 {
10372   size_t dirlen;
10373   char   dirpath[FN_REFLEN];
10374   if (path)
10375   {
10376     dirname_part(dirpath, path, &dirlen);
10377     if (test_if_data_home_dir(dirpath))
10378     {
10379       my_error(ER_WRONG_ARGUMENTS, MYF(0), what);
10380       return 1;
10381     }
10382   }
10383   return 0;
10384 }
10385 
10386 /**
10387   Check that host name string is valid.
10388 
10389   @param[in] str string to be checked
10390 
10391   @return             Operation status
10392     @retval  FALSE    host name is ok
10393     @retval  TRUE     host name string is longer than max_length or
10394                       has invalid symbols
10395 */
10396 
check_host_name(LEX_CSTRING * str)10397 bool check_host_name(LEX_CSTRING *str)
10398 {
10399   const char *name= str->str;
10400   const char *end= str->str + str->length;
10401   if (check_string_byte_length(str, ER_HOSTNAME, HOSTNAME_LENGTH))
10402     return TRUE;
10403 
10404   while (name != end)
10405   {
10406     if (*name == '@')
10407     {
10408       my_printf_error(ER_UNKNOWN_ERROR,
10409                       "Malformed hostname (illegal symbol: '%c')", MYF(0),
10410                       *name);
10411       return TRUE;
10412     }
10413     name++;
10414   }
10415   return FALSE;
10416 }
10417 
10418 
10419 extern int MYSQLparse(THD *thd); // from yy_mariadb.cc
10420 extern int ORAparse(THD *thd);   // from yy_oracle.cc
10421 
10422 
10423 /**
10424   This is a wrapper of MYSQLparse(). All the code should call parse_sql()
10425   instead of MYSQLparse().
10426 
10427   @param thd Thread context.
10428   @param parser_state Parser state.
10429   @param creation_ctx Object creation context.
10430 
10431   @return Error status.
10432     @retval FALSE on success.
10433     @retval TRUE on parsing error.
10434 */
10435 
parse_sql(THD * thd,Parser_state * parser_state,Object_creation_ctx * creation_ctx,bool do_pfs_digest)10436 bool parse_sql(THD *thd, Parser_state *parser_state,
10437                Object_creation_ctx *creation_ctx, bool do_pfs_digest)
10438 {
10439   bool ret_value;
10440   DBUG_ENTER("parse_sql");
10441   DBUG_ASSERT(thd->m_parser_state == NULL);
10442   DBUG_ASSERT(thd->lex->m_sql_cmd == NULL);
10443 
10444   MYSQL_QUERY_PARSE_START(thd->query());
10445   /* Backup creation context. */
10446 
10447   Object_creation_ctx *backup_ctx= NULL;
10448 
10449   if (creation_ctx)
10450     backup_ctx= creation_ctx->set_n_backup(thd);
10451 
10452   /* Set parser state. */
10453 
10454   thd->m_parser_state= parser_state;
10455 
10456   parser_state->m_digest_psi= NULL;
10457   parser_state->m_lip.m_digest= NULL;
10458 
10459   if (do_pfs_digest)
10460   {
10461     /* Start Digest */
10462     parser_state->m_digest_psi= MYSQL_DIGEST_START(thd->m_statement_psi);
10463 
10464     if (parser_state->m_digest_psi != NULL)
10465     {
10466       /*
10467         If either:
10468         - the caller wants to compute a digest
10469         - the performance schema wants to compute a digest
10470         set the digest listener in the lexer.
10471       */
10472       parser_state->m_lip.m_digest= thd->m_digest;
10473       parser_state->m_lip.m_digest->m_digest_storage.m_charset_number= thd->charset()->number;
10474     }
10475   }
10476 
10477   /* Parse the query. */
10478 
10479   bool mysql_parse_status=
10480          ((thd->variables.sql_mode & MODE_ORACLE) ?
10481           ORAparse(thd) :
10482           MYSQLparse(thd)) != 0;
10483   DBUG_ASSERT(opt_bootstrap || mysql_parse_status ||
10484               thd->lex->select_stack_top == 0);
10485   thd->lex->current_select= thd->lex->first_select_lex();
10486 
10487   /*
10488     Check that if MYSQLparse() failed either thd->is_error() is set, or an
10489     internal error handler is set.
10490 
10491     The assert will not catch a situation where parsing fails without an
10492     error reported if an error handler exists. The problem is that the
10493     error handler might have intercepted the error, so thd->is_error() is
10494     not set. However, there is no way to be 100% sure here (the error
10495     handler might be for other errors than parsing one).
10496   */
10497 
10498   DBUG_ASSERT(!mysql_parse_status ||
10499               thd->is_error() ||
10500               thd->get_internal_handler());
10501 
10502   /* Reset parser state. */
10503 
10504   thd->m_parser_state= NULL;
10505 
10506   /* Restore creation context. */
10507 
10508   if (creation_ctx)
10509     creation_ctx->restore_env(thd, backup_ctx);
10510 
10511   /* That's it. */
10512 
10513   ret_value= mysql_parse_status || thd->is_fatal_error;
10514 
10515   if ((ret_value == 0) && (parser_state->m_digest_psi != NULL))
10516   {
10517     /*
10518       On parsing success, record the digest in the performance schema.
10519     */
10520     DBUG_ASSERT(do_pfs_digest);
10521     DBUG_ASSERT(thd->m_digest != NULL);
10522     MYSQL_DIGEST_END(parser_state->m_digest_psi,
10523                      & thd->m_digest->m_digest_storage);
10524   }
10525 
10526   MYSQL_QUERY_PARSE_DONE(ret_value);
10527   DBUG_RETURN(ret_value);
10528 }
10529 
10530 /**
10531   @} (end of group Runtime_Environment)
10532 */
10533 
10534 
10535 
10536 /**
10537   Check and merge "CHARACTER SET cs [ COLLATE cl ]" clause
10538 
10539   @param cs character set pointer.
10540   @param cl collation pointer.
10541 
10542   Check if collation "cl" is applicable to character set "cs".
10543 
10544   If "cl" is NULL (e.g. when COLLATE clause is not specified),
10545   then simply "cs" is returned.
10546 
10547   @return Error status.
10548     @retval NULL, if "cl" is not applicable to "cs".
10549     @retval pointer to merged CHARSET_INFO on success.
10550 */
10551 
10552 
10553 CHARSET_INFO*
merge_charset_and_collation(CHARSET_INFO * cs,CHARSET_INFO * cl)10554 merge_charset_and_collation(CHARSET_INFO *cs, CHARSET_INFO *cl)
10555 {
10556   if (cl)
10557   {
10558     if (!my_charset_same(cs, cl))
10559     {
10560       my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), cl->name, cs->csname);
10561       return NULL;
10562     }
10563     return cl;
10564   }
10565   return cs;
10566 }
10567 
10568 /** find a collation with binary comparison rules
10569 */
find_bin_collation(CHARSET_INFO * cs)10570 CHARSET_INFO *find_bin_collation(CHARSET_INFO *cs)
10571 {
10572   const char *csname= cs->csname;
10573   cs= get_charset_by_csname(csname, MY_CS_BINSORT, MYF(0));
10574   if (!cs)
10575   {
10576     char tmp[65];
10577     strxnmov(tmp, sizeof(tmp)-1, csname, "_bin", NULL);
10578     my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp);
10579   }
10580   return cs;
10581 }
10582 
mark_first_table_as_inserting()10583 void LEX::mark_first_table_as_inserting()
10584 {
10585   TABLE_LIST *t= first_select_lex()->table_list.first;
10586   DBUG_ENTER("Query_tables_list::mark_tables_with_important_flags");
10587   DBUG_ASSERT(sql_command_flags[sql_command] & CF_INSERTS_DATA);
10588   t->for_insert_data= TRUE;
10589   DBUG_PRINT("info", ("table_list: %p  name: %s  db: %s  command: %u",
10590                       t, t->table_name.str,t->db.str, sql_command));
10591   DBUG_VOID_RETURN;
10592 }
10593