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