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