1 /* Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23 /**
24 @file
25
26 This file contains the implementation of prepared statements.
27
28 When one prepares a statement:
29
30 - Server gets the query from client with command 'COM_STMT_PREPARE';
31 in the following format:
32 [COM_STMT_PREPARE:1] [query]
33 - Parse the query and recognize any parameter markers '?' and
34 store its information list in lex->param_list
35 - Allocate a new statement for this prepare; and keep this in
36 'thd->stmt_map'.
37 - Without executing the query, return back to client the total
38 number of parameters along with result-set metadata information
39 (if any) in the following format:
40 @verbatim
41 [STMT_ID:4]
42 [Column_count:2]
43 [Param_count:2]
44 [Params meta info (stubs only for now)] (if Param_count > 0)
45 [Columns meta info] (if Column_count > 0)
46 @endverbatim
47
48 During prepare the tables used in a statement are opened, but no
49 locks are acquired. Table opening will block any DDL during the
50 operation, and we do not need any locks as we neither read nor
51 modify any data during prepare. Tables are closed after prepare
52 finishes.
53
54 When one executes a statement:
55
56 - Server gets the command 'COM_STMT_EXECUTE' to execute the
57 previously prepared query. If there are any parameter markers, then the
58 client will send the data in the following format:
59 @verbatim
60 [COM_STMT_EXECUTE:1]
61 [STMT_ID:4]
62 [NULL_BITS:(param_count+7)/8)]
63 [TYPES_SUPPLIED_BY_CLIENT(0/1):1]
64 [[length]data]
65 [[length]data] .. [[length]data].
66 @endverbatim
67 (Note: Except for string/binary types; all other types will not be
68 supplied with length field)
69 - If it is a first execute or types of parameters were altered by client,
70 then setup the conversion routines.
71 - Assign parameter items from the supplied data.
72 - Execute the query without re-parsing and send back the results
73 to client
74
75 During execution of prepared statement tables are opened and locked
76 the same way they would for normal (non-prepared) statement
77 execution. Tables are unlocked and closed after the execution.
78
79 When one supplies long data for a placeholder:
80
81 - Server gets the long data in pieces with command type
82 'COM_STMT_SEND_LONG_DATA'.
83 - The packet received will have the format as:
84 [COM_STMT_SEND_LONG_DATA:1][STMT_ID:4][parameter_number:2][data]
85 - data from the packet is appended to the long data value buffer for this
86 placeholder.
87 - It's up to the client to stop supplying data chunks at any point. The
88 server doesn't care; also, the server doesn't notify the client whether
89 it got the data or not; if there is any error, then it will be returned
90 at statement execute.
91 */
92
93 #include "sql/sql_prepare.h"
94
95 #include "my_config.h"
96
97 #include <limits.h>
98 #include <stdint.h>
99 #include <stdio.h>
100 #include <string.h>
101 #include <algorithm>
102 #include <limits>
103 #include <memory>
104 #include <unordered_map>
105 #include <utility>
106
107 #include "decimal.h"
108 #include "field_types.h"
109 #include "m_ctype.h"
110 #include "m_string.h"
111 #include "map_helpers.h"
112 #include "my_alloc.h"
113 #include "my_byteorder.h"
114 #include "my_command.h"
115 #include "my_compiler.h"
116 #include "my_dbug.h"
117 #include "my_sqlcommand.h"
118 #include "my_sys.h"
119 #include "my_time.h"
120 #include "mysql/com_data.h"
121 #include "mysql/components/services/log_shared.h"
122 #include "mysql/plugin_audit.h"
123 #include "mysql/psi/mysql_mutex.h"
124 #include "mysql/psi/mysql_ps.h" // MYSQL_EXECUTE_PS
125 #include "mysql/udf_registration_types.h"
126 #include "mysql_com.h"
127 #include "mysql_time.h"
128 #include "mysqld_error.h"
129 #include "scope_guard.h"
130 #include "sql/auth/auth_acls.h"
131 #include "sql/auth/auth_common.h" // check_table_access
132 #include "sql/auth/sql_security_ctx.h"
133 #include "sql/binlog.h"
134 #include "sql/debug_sync.h"
135 #include "sql/derror.h" // ER_THD
136 #include "sql/field.h"
137 #include "sql/handler.h"
138 #include "sql/item.h"
139 #include "sql/item_func.h" // user_var_entry
140 #include "sql/log.h" // query_logger
141 #include "sql/mdl.h"
142 #include "sql/my_decimal.h"
143 #include "sql/mysqld.h" // opt_general_log
144 #include "sql/opt_trace.h" // Opt_trace_array
145 #include "sql/protocol.h"
146 #include "sql/protocol_classic.h"
147 #include "sql/psi_memory_key.h"
148 #include "sql/query_options.h"
149 #include "sql/query_result.h"
150 #include "sql/resourcegroups/resource_group_basic_types.h"
151 #include "sql/resourcegroups/resource_group_mgr.h"
152 #include "sql/session_tracker.h"
153 #include "sql/set_var.h" // set_var_base
154 #include "sql/sp_cache.h" // sp_cache_enforce_limit
155 #include "sql/sql_audit.h" // mysql_global_audit_mask
156 #include "sql/sql_base.h" // open_tables_for_query, open_temporary_table
157 #include "sql/sql_class.h"
158 #include "sql/sql_cmd.h"
159 #include "sql/sql_cmd_ddl_table.h"
160 #include "sql/sql_const.h"
161 #include "sql/sql_cursor.h" // Server_side_cursor
162 #include "sql/sql_db.h" // mysql_change_db
163 #include "sql/sql_digest_stream.h"
164 #include "sql/sql_handler.h" // mysql_ha_rm_tables
165 #include "sql/sql_lex.h"
166 #include "sql/sql_list.h"
167 #include "sql/sql_parse.h" // sql_command_flags
168 #include "sql/sql_profile.h"
169 #include "sql/sql_query_rewrite.h"
170 #include "sql/sql_rewrite.h" // mysql_rewrite_query
171 #include "sql/sql_view.h" // create_view_precheck
172 #include "sql/system_variables.h"
173 #include "sql/table.h"
174 #include "sql/thr_malloc.h"
175 #include "sql/transaction.h" // trans_rollback_implicit
176 #include "sql/window.h"
177 #include "sql_string.h"
178 #include "violite.h"
179
180 namespace resourcegroups {
181 class Resource_group;
182 } // namespace resourcegroups
183
184 using std::max;
185 using std::min;
186
187 /****************************************************************************/
188
189 namespace {
190
191 /**
192 Execute one SQL statement in an isolated context.
193 */
194
195 class Execute_sql_statement : public Server_runnable {
196 public:
197 Execute_sql_statement(LEX_STRING sql_text);
198 virtual bool execute_server_code(THD *thd);
199
200 private:
201 LEX_STRING m_sql_text;
202 };
203
204 /**
205 A result class used to send cursor rows using the binary protocol.
206 */
207
208 class Query_fetch_protocol_binary final : public Query_result_send {
209 Protocol_binary protocol;
210
211 public:
Query_fetch_protocol_binary(THD * thd)212 explicit Query_fetch_protocol_binary(THD *thd)
213 : Query_result_send(), protocol(thd) {}
214 bool send_result_set_metadata(THD *thd, List<Item> &list,
215 uint flags) override;
216 bool send_data(THD *thd, List<Item> &items) override;
217 bool send_eof(THD *thd) override;
218 };
219
220 } // namespace
221
222 /**
223 Protocol_local: a helper class to intercept the result
224 of the data written to the network.
225
226 At the start of every result set, start_result_metadata allocates m_rset to
227 prepare for the results. The metadata is stored on m_current_row which will
228 be transfered to m_fields in end_result_metadata. The memory for the
229 metadata is allocated on m_rset_root.
230
231 Then, for every row of the result recieved, each of the fields is stored in
232 m_current_row. Then the row is moved to m_rset and m_current_row is cleared
233 to recieve the next row. The memory for all the results are also stored in
234 m_rset_root.
235
236 Finally, at the end of the result set, a new instance of Ed_result_set is
237 created on m_rset_root and the result set (m_rset and m_fields) is moved into
238 this instance. The ownership of MEM_ROOT m_rset_root is also transfered to
239 this instance. So, at the end we have a fresh MEM_ROOT, cleared m_rset and
240 m_fields to accept the next result set.
241 */
242
243 class Protocol_local final : public Protocol {
244 public:
245 Protocol_local(THD *thd, Ed_connection *ed_connection);
~Protocol_local()246 ~Protocol_local() override { free_root(&m_rset_root, MYF(0)); }
247
248 int read_packet() override;
249
250 int get_command(COM_DATA *com_data, enum_server_command *cmd) override;
251 ulong get_client_capabilities() override;
252 bool has_client_capability(unsigned long client_capability) override;
253 void end_partial_result_set() override;
254 int shutdown(bool server_shutdown = false) override;
255 bool connection_alive() const override;
256 void start_row() override;
257 bool end_row() override;
abort_row()258 void abort_row() override {}
259 uint get_rw_status() override;
260 bool get_compression() override;
261
262 char *get_compression_algorithm() override;
263 uint get_compression_level() override;
264
265 bool start_result_metadata(uint num_cols, uint flags,
266 const CHARSET_INFO *resultcs) override;
267 bool end_result_metadata() override;
268 bool send_field_metadata(Send_field *field,
269 const CHARSET_INFO *charset) override;
flush()270 bool flush() override { return true; }
send_parameters(List<Item_param> *,bool)271 bool send_parameters(List<Item_param> *, bool) override { return false; }
store_ps_status(ulong,uint,uint,ulong)272 bool store_ps_status(ulong, uint, uint, ulong) override { return false; }
273
274 protected:
275 bool store_null() override;
276 bool store_tiny(longlong from, uint32) override;
277 bool store_short(longlong from, uint32) override;
278 bool store_long(longlong from, uint32) override;
279 bool store_longlong(longlong from, bool unsigned_flag, uint32) override;
280 bool store_decimal(const my_decimal *, uint, uint) override;
281 bool store_string(const char *from, size_t length,
282 const CHARSET_INFO *cs) override;
283 bool store_datetime(const MYSQL_TIME &time, uint precision) override;
284 bool store_date(const MYSQL_TIME &time) override;
285 bool store_time(const MYSQL_TIME &time, uint precision) override;
286 bool store_float(float value, uint32 decimals, uint32 zerofill) override;
287 bool store_double(double value, uint32 decimals, uint32 zerofill) override;
288 bool store_field(const Field *field) override;
289
type() const290 enum enum_protocol_type type() const override { return PROTOCOL_LOCAL; }
connection_type() const291 enum enum_vio_type connection_type() const override { return VIO_TYPE_LOCAL; }
292
293 bool send_ok(uint server_status, uint statement_warn_count,
294 ulonglong affected_rows, ulonglong last_insert_id,
295 const char *message) override;
296
297 bool send_eof(uint server_status, uint statement_warn_count) override;
298 bool send_error(uint sql_errno, const char *err_msg,
299 const char *sqlstate) override;
300
301 private:
302 bool store_string(const char *str, size_t length, const CHARSET_INFO *src_cs,
303 const CHARSET_INFO *dst_cs);
304
305 bool store_column(const void *data, size_t length);
306 void opt_add_row_to_rset();
307
308 private:
309 Ed_connection *m_connection;
310 MEM_ROOT m_rset_root;
311 List<Ed_row> *m_rset;
312 size_t m_column_count;
313 Ed_column *m_current_row;
314 Ed_column *m_current_column;
315 Ed_row *m_fields;
316 bool m_send_metadata;
317 THD *m_thd;
318 };
319
320 /******************************************************************************
321 Implementation
322 ******************************************************************************/
323
324 /**
325 Rewrite the current query (to obfuscate passwords etc.) if needed
326 (i.e. only if we'll be writing the query to any of our logs).
327
328 Side-effect: thd->rewritten_query() may be populated with a rewritten
329 query. If the query is not of a rewritable type,
330 thd->rewritten_query() will be empty.
331
332 @param thd thread handle
333 */
rewrite_query_if_needed(THD * thd)334 static inline void rewrite_query_if_needed(THD *thd) {
335 bool general =
336 (opt_general_log && !(opt_general_log_raw || thd->slave_thread));
337
338 if ((thd->sp_runtime_ctx == nullptr) &&
339 (general || opt_slow_log || opt_bin_log)) {
340 /*
341 thd->m_rewritten_query may already contain "PREPARE stmt FROM ..."
342 at this point, so we reset it here so mysql_rewrite_query()
343 won't complain.
344 */
345 thd->reset_rewritten_query();
346 /*
347 Now replace the "PREPARE ..." with the obfuscated version of the
348 actual query were prepare.
349 */
350 mysql_rewrite_query(thd);
351 }
352 }
353
354 /**
355 Unless we're doing dynamic SQL, write the current query to the
356 general query log if it's open. If we have a rewritten version
357 of the query, use that instead of the "raw" one.
358
359 Side-effect: query may be written to general log if it's open.
360
361 @param thd thread handle
362 */
log_execute_line(THD * thd)363 static inline void log_execute_line(THD *thd) {
364 /*
365 Do not print anything if this is an SQL prepared statement and
366 we're inside a stored procedure (also called Dynamic SQL) --
367 sub-statements inside stored procedures are not logged into
368 the general log.
369 */
370 if (thd->sp_runtime_ctx != nullptr) return;
371
372 if (thd->rewritten_query().length())
373 query_logger.general_log_write(thd, COM_STMT_EXECUTE,
374 thd->rewritten_query().ptr(),
375 thd->rewritten_query().length());
376 else
377 query_logger.general_log_write(thd, COM_STMT_EXECUTE, thd->query().str,
378 thd->query().length);
379 }
380
381 class Statement_backup {
382 LEX *m_lex;
383 LEX_CSTRING m_query_string;
384 String m_rewritten_query;
385
386 public:
lex() const387 LEX *lex() const { return m_lex; }
388
389 /**
390 Prepared the THD to execute the prepared statement.
391 Save the current THD statement state.
392 */
set_thd_to_ps(THD * thd,Prepared_statement * stmt)393 void set_thd_to_ps(THD *thd, Prepared_statement *stmt) {
394 DBUG_TRACE;
395
396 mysql_mutex_lock(&thd->LOCK_thd_data);
397 m_lex = thd->lex;
398 thd->lex = stmt->lex;
399 mysql_mutex_unlock(&thd->LOCK_thd_data);
400
401 m_query_string = thd->query();
402 thd->set_query(stmt->m_query_string);
403
404 return;
405 }
406
407 /**
408 Restore the THD statement state after the prepared
409 statement has finished executing.
410 */
restore_thd(THD * thd,Prepared_statement * stmt)411 void restore_thd(THD *thd, Prepared_statement *stmt) {
412 DBUG_TRACE;
413
414 mysql_mutex_lock(&thd->LOCK_thd_data);
415 stmt->lex = thd->lex;
416 thd->lex = m_lex;
417 mysql_mutex_unlock(&thd->LOCK_thd_data);
418
419 stmt->m_query_string = thd->query();
420 thd->set_query(m_query_string);
421
422 return;
423 }
424
425 /**
426 Save the current rewritten query prior to
427 rewriting the prepared statement.
428 */
save_rlb(THD * thd)429 void save_rlb(THD *thd) {
430 DBUG_TRACE;
431
432 if (thd->rewritten_query().length() > 0) {
433 /* Duplicate the original rewritten query. */
434 m_rewritten_query.copy(thd->rewritten_query());
435 /* Swap the duplicate with the original. */
436 thd->swap_rewritten_query(m_rewritten_query);
437 }
438
439 return;
440 }
441
442 /**
443 Restore the rewritten query after the prepared
444 statement has finished executing.
445 */
restore_rlb(THD * thd)446 void restore_rlb(THD *thd) {
447 DBUG_TRACE;
448
449 if (m_rewritten_query.length() > 0) {
450 /* Restore with swap() instead of '='. */
451 thd->swap_rewritten_query(m_rewritten_query);
452 /* Free the rewritten prepared statement. */
453 m_rewritten_query.mem_free();
454 }
455
456 return;
457 }
458 };
459
460 static bool send_statement(THD *thd, const Prepared_statement *stmt,
461 uint no_columns, Query_result *result,
462 List<Item> *types);
463
464 /**
465 Data conversion routines.
466
467 All these functions read the data from pos, convert it to requested
468 type and assign to param; pos is advanced to predefined length.
469
470 Make a note that the NULL handling is examined at first execution
471 (i.e. when input types altered) and for all subsequent executions
472 we don't read any values for this.
473
474 @param param parameter item
475 @param pos input data buffer
476 @param len length of data in the buffer
477 */
478
set_param_tiny(Item_param * param,uchar ** pos,ulong len)479 static void set_param_tiny(Item_param *param, uchar **pos, ulong len) {
480 if (len < 1) return;
481 int8 value = (int8) * *pos;
482 param->set_int(
483 param->unsigned_flag ? (longlong)((uint8)value) : (longlong)value, 4);
484 }
485
set_param_short(Item_param * param,uchar ** pos,ulong len)486 static void set_param_short(Item_param *param, uchar **pos, ulong len) {
487 int16 value;
488 if (len < 2) return;
489 value = sint2korr(*pos);
490 param->set_int(
491 param->unsigned_flag ? (longlong)((uint16)value) : (longlong)value, 6);
492 }
493
set_param_int32(Item_param * param,uchar ** pos,ulong len)494 static void set_param_int32(Item_param *param, uchar **pos, ulong len) {
495 int32 value;
496 if (len < 4) return;
497 value = sint4korr(*pos);
498 param->set_int(
499 param->unsigned_flag ? (longlong)((uint32)value) : (longlong)value, 11);
500 }
501
set_param_int64(Item_param * param,uchar ** pos,ulong len)502 static void set_param_int64(Item_param *param, uchar **pos, ulong len) {
503 longlong value;
504 if (len < 8) return;
505 value = sint8korr(*pos);
506 param->set_int(value, 21);
507 }
508
set_param_float(Item_param * param,uchar ** pos,ulong len)509 static void set_param_float(Item_param *param, uchar **pos, ulong len) {
510 if (len < 4) return;
511 float data = float4get(*pos);
512 param->set_double((double)data);
513 }
514
set_param_double(Item_param * param,uchar ** pos,ulong len)515 static void set_param_double(Item_param *param, uchar **pos, ulong len) {
516 if (len < 8) return;
517 double data = float8get(*pos);
518 param->set_double(data);
519 }
520
set_param_decimal(Item_param * param,uchar ** pos,ulong len)521 static void set_param_decimal(Item_param *param, uchar **pos, ulong len) {
522 param->set_decimal((char *)*pos, len);
523 }
524
525 /*
526 Read date/time/datetime parameter values from network (binary
527 protocol). See writing counterparts of these functions in
528 libmysql.c (store_param_{time,date,datetime}).
529 */
530
531 /**
532 @todo
533 Add warning 'Data truncated' here
534 */
set_param_time(Item_param * param,uchar ** pos,ulong len)535 static void set_param_time(Item_param *param, uchar **pos, ulong len) {
536 MYSQL_TIME tm;
537
538 if (len >= 8) {
539 uchar *to = *pos;
540 uint day;
541
542 tm.neg = (bool)to[0];
543 day = (uint)sint4korr(to + 1);
544 tm.hour = (uint)to[5] + day * 24;
545 tm.minute = (uint)to[6];
546 tm.second = (uint)to[7];
547 tm.second_part = (len > 8) ? (ulong)sint4korr(to + 8) : 0;
548 if (tm.hour > 838) {
549 /* TODO: add warning 'Data truncated' here */
550 tm.hour = 838;
551 tm.minute = 59;
552 tm.second = 59;
553 }
554 tm.day = tm.year = tm.month = 0;
555 } else
556 set_zero_time(&tm, MYSQL_TIMESTAMP_TIME);
557 param->set_time(&tm, MYSQL_TIMESTAMP_TIME,
558 MAX_TIME_FULL_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
559 }
560
set_param_datetime(Item_param * param,uchar ** pos,ulong len)561 static void set_param_datetime(Item_param *param, uchar **pos, ulong len) {
562 MYSQL_TIME tm;
563 enum_mysql_timestamp_type type = MYSQL_TIMESTAMP_DATETIME;
564 uchar *to = *pos;
565
566 DBUG_ASSERT(len == 0 || len == 4 || len == 7 || len == 11 || len == 13);
567 if (len < 4) {
568 set_zero_time(&tm, MYSQL_TIMESTAMP_DATETIME);
569 } else {
570 tm.neg = false;
571 tm.year = (uint)sint2korr(to);
572 tm.month = (uint)to[2];
573 tm.day = (uint)to[3];
574 }
575 if (len >= 7) {
576 tm.hour = (uint)to[4];
577 tm.minute = (uint)to[5];
578 tm.second = (uint)to[6];
579 } else // len == 4
580 tm.hour = tm.minute = tm.second = 0;
581
582 tm.second_part =
583 (len >= 11) ? static_cast<std::uint64_t>(sint4korr(to + 7)) : 0;
584
585 if (len >= 13) {
586 tm.time_zone_displacement = sint2korr(to + 11) * SECS_PER_MIN;
587 type = MYSQL_TIMESTAMP_DATETIME_TZ;
588 }
589 param->set_time(&tm, type,
590 MAX_DATETIME_FULL_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
591 }
592
set_param_date(Item_param * param,uchar ** pos,ulong len)593 static void set_param_date(Item_param *param, uchar **pos, ulong len) {
594 MYSQL_TIME tm;
595
596 if (len >= 4) {
597 uchar *to = *pos;
598
599 tm.year = (uint)sint2korr(to);
600 tm.month = (uint)to[2];
601 tm.day = (uint)to[3];
602
603 tm.hour = tm.minute = tm.second = 0;
604 tm.second_part = 0;
605 tm.neg = false;
606 } else
607 set_zero_time(&tm, MYSQL_TIMESTAMP_DATE);
608 param->set_time(&tm, MYSQL_TIMESTAMP_DATE,
609 MAX_DATE_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
610 }
611
set_param_str(Item_param * param,uchar ** pos,ulong len)612 static void set_param_str(Item_param *param, uchar **pos, ulong len) {
613 param->set_str((const char *)*pos, len);
614 }
615
setup_one_conversion_function(THD * thd,Item_param * param,enum enum_field_types param_type)616 static bool setup_one_conversion_function(THD *thd, Item_param *param,
617 enum enum_field_types param_type) {
618 switch (param_type) {
619 case MYSQL_TYPE_TINY:
620 param->set_param_func = set_param_tiny;
621 param->item_type = Item::INT_ITEM;
622 param->item_result_type = INT_RESULT;
623 break;
624 case MYSQL_TYPE_SHORT:
625 param->set_param_func = set_param_short;
626 param->item_type = Item::INT_ITEM;
627 param->item_result_type = INT_RESULT;
628 break;
629 case MYSQL_TYPE_LONG:
630 param->set_param_func = set_param_int32;
631 param->item_type = Item::INT_ITEM;
632 param->item_result_type = INT_RESULT;
633 break;
634 case MYSQL_TYPE_LONGLONG:
635 param->set_param_func = set_param_int64;
636 param->item_type = Item::INT_ITEM;
637 param->item_result_type = INT_RESULT;
638 break;
639 case MYSQL_TYPE_FLOAT:
640 param->set_param_func = set_param_float;
641 param->item_type = Item::REAL_ITEM;
642 param->item_result_type = REAL_RESULT;
643 break;
644 case MYSQL_TYPE_DOUBLE:
645 param->set_param_func = set_param_double;
646 param->item_type = Item::REAL_ITEM;
647 param->item_result_type = REAL_RESULT;
648 break;
649 case MYSQL_TYPE_DECIMAL:
650 case MYSQL_TYPE_NEWDECIMAL:
651 param->set_param_func = set_param_decimal;
652 param->item_type = Item::DECIMAL_ITEM;
653 param->item_result_type = DECIMAL_RESULT;
654 break;
655 case MYSQL_TYPE_TIME:
656 param->set_param_func = set_param_time;
657 param->item_type = Item::STRING_ITEM;
658 param->item_result_type = STRING_RESULT;
659 break;
660 case MYSQL_TYPE_DATE:
661 param->set_param_func = set_param_date;
662 param->item_type = Item::STRING_ITEM;
663 param->item_result_type = STRING_RESULT;
664 break;
665 case MYSQL_TYPE_DATETIME:
666 case MYSQL_TYPE_TIMESTAMP:
667 param->set_param_func = set_param_datetime;
668 param->item_type = Item::STRING_ITEM;
669 param->item_result_type = STRING_RESULT;
670 break;
671 case MYSQL_TYPE_TINY_BLOB:
672 case MYSQL_TYPE_MEDIUM_BLOB:
673 case MYSQL_TYPE_LONG_BLOB:
674 case MYSQL_TYPE_BLOB:
675 param->set_param_func = set_param_str;
676 param->value.cs_info.character_set_of_placeholder = &my_charset_bin;
677 param->value.cs_info.character_set_client =
678 thd->variables.character_set_client;
679 DBUG_ASSERT(thd->variables.character_set_client);
680 param->value.cs_info.final_character_set_of_str_value = &my_charset_bin;
681 param->item_type = Item::STRING_ITEM;
682 param->item_result_type = STRING_RESULT;
683 break;
684 case MYSQL_TYPE_JSON:
685 // MYSQL_TYPE_JSON is not allowed as Item_param lacks a proper
686 // implementation for val_json.
687 return true;
688 default:
689 // Label 'default' lets us handle string types.
690 {
691 // Check enum_field_types type definition
692 if (param_type == MYSQL_TYPE_NEWDATE ||
693 (param_type > MYSQL_TYPE_TIMESTAMP2 &&
694 param_type < MYSQL_TYPE_JSON) ||
695 param_type > MYSQL_TYPE_GEOMETRY)
696 // send error
697 return true;
698
699 const CHARSET_INFO *fromcs = thd->variables.character_set_client;
700 const CHARSET_INFO *tocs = thd->variables.collation_connection;
701 size_t dummy_offset;
702
703 param->value.cs_info.character_set_of_placeholder = fromcs;
704 param->value.cs_info.character_set_client = fromcs;
705
706 /*
707 Setup source and destination character sets so that they
708 are different only if conversion is necessary: this will
709 make later checks easier.
710 */
711 param->value.cs_info.final_character_set_of_str_value =
712 String::needs_conversion(0, fromcs, tocs, &dummy_offset) ? tocs
713 : fromcs;
714 param->set_param_func = set_param_str;
715 /*
716 Exact value of max_length is not known unless data is converted to
717 charset of connection, so we have to set it later.
718 */
719 param->item_type = Item::STRING_ITEM;
720 param->item_result_type = STRING_RESULT;
721 }
722 }
723 param->set_data_type(param_type);
724 return false;
725 }
726
727 /**
728 Check whether this parameter data type is compatible with long data.
729 Used to detect whether a long data stream has been supplied to a
730 incompatible data type.
731 */
is_param_long_data_type(Item_param * param)732 inline bool is_param_long_data_type(Item_param *param) {
733 return ((param->data_type() >= MYSQL_TYPE_TINY_BLOB) &&
734 (param->data_type() <= MYSQL_TYPE_STRING));
735 }
736
737 /**
738 Routines to assign parameters from data supplied by the client.
739
740 Update the parameter markers by reading data from the packet and
741 and generate a valid query for logging.
742
743 @note
744 with_log is set when one of slow or general logs are open.
745 Logging of prepared statements in all cases is performed
746 by means of regular queries: if parameter data was supplied from C API,
747 each placeholder in the query is replaced with its actual value;
748 if we're logging a [Dynamic] SQL prepared statement, parameter markers
749 are replaced with variable names.
750 Example:
751 @verbatim
752 mysqld_stmt_prepare("UPDATE t1 SET a=a*1.25 WHERE a=?")
753 --> general logs gets [Prepare] UPDATE t1 SET a*1.25 WHERE a=?"
754 mysqld_stmt_execute(stmt);
755 --> general and binary logs get
756 [Execute] UPDATE t1 SET a*1.25 WHERE a=1"
757 @endverbatim
758
759 If a statement has been prepared using SQL syntax:
760 @verbatim
761 PREPARE stmt FROM "UPDATE t1 SET a=a*1.25 WHERE a=?"
762 --> general log gets
763 [Query] PREPARE stmt FROM "UPDATE ..."
764 EXECUTE stmt USING @a
765 --> general log gets
766 [Query] EXECUTE stmt USING @a;
767 @endverbatim
768
769 @retval
770 0 if success
771 @retval
772 1 otherwise
773 */
774
insert_params(String * query,PS_PARAM * parameters)775 bool Prepared_statement::insert_params(String *query, PS_PARAM *parameters) {
776 Item_param **begin = param_array;
777 Item_param **end = begin + param_count;
778 size_t length = 0;
779 String str;
780 const String *res;
781 DBUG_TRACE;
782
783 if (with_log && query->copy(m_query_string.str, m_query_string.length,
784 default_charset_info))
785 return true;
786
787 uint i = 0;
788 for (Item_param **it = begin; it < end; ++it, ++i) {
789 Item_param *param = *it;
790 if (param->state != Item_param::LONG_DATA_VALUE) {
791 if (parameters[i].null_bit)
792 param->set_null();
793 else {
794 // TODO: Add error handling for set_param_func functions.
795 param->set_param_func(param, const_cast<uchar **>(¶meters[i].value),
796 parameters[i].length);
797 if (param->state == Item_param::NO_VALUE) return true;
798
799 if (with_log && param->limit_clause_param &&
800 param->state != Item_param::INT_VALUE) {
801 param->set_int(param->val_int(), MY_INT64_NUM_DECIMAL_DIGITS);
802 param->item_type = Item::INT_ITEM;
803 if (!param->unsigned_flag && param->value.integer < 0) return true;
804 }
805 }
806 }
807 /*
808 A long data stream was supplied for this parameter marker.
809 This was done after prepare, prior to providing a placeholder
810 type (the types are supplied at execute). Check that the
811 supplied type of placeholder can accept a data stream.
812 */
813 else if (!is_param_long_data_type(param))
814 return true;
815 if (with_log) {
816 res = param->query_val_str(thd, &str);
817 if (param->convert_str_value()) return true; /* out of memory */
818
819 if (query->replace(param->pos_in_query + length, 1, *res)) return true;
820
821 length += res->length() - 1;
822 } else {
823 if (param->convert_str_value()) return true; /* out of memory */
824 }
825 param->sync_clones();
826 }
827 return false;
828 }
829
setup_conversion_functions(Prepared_statement * stmt,PS_PARAM * parameters)830 static bool setup_conversion_functions(Prepared_statement *stmt,
831 PS_PARAM *parameters) {
832 DBUG_TRACE;
833 /*
834 First execute or types altered by the client, setup the
835 conversion routines for all parameters (one time)
836 */
837 Item_param **it = stmt->param_array;
838 Item_param **end = it + stmt->param_count;
839 for (uint i = 0; it < end; ++it, ++i) {
840 (**it).unsigned_flag = parameters[i].unsigned_type;
841 if (setup_one_conversion_function(stmt->thd, *it, parameters[i].type))
842 return true;
843 (**it).sync_clones();
844 }
845 return false;
846 }
847
848 /**
849 Setup data conversion routines using an array of parameter
850 markers from the original prepared statement.
851 Swap the parameter data of the original prepared
852 statement to the new one.
853
854 Used only when we re-prepare a prepared statement.
855 There are two reasons for this function to exist:
856
857 1) In the binary client/server protocol, parameter metadata
858 is sent only at first execute. Consequently, if we need to
859 reprepare a prepared statement at a subsequent execution,
860 we may not have metadata information in the packet.
861 In that case we use the parameter array of the original
862 prepared statement to setup parameter types of the new
863 prepared statement.
864
865 2) In the binary client/server protocol, we may supply
866 long data in pieces. When the last piece is supplied,
867 we assemble the pieces and convert them from client
868 character set to the connection character set. After
869 that the parameter value is only available inside
870 the parameter, the original pieces are lost, and thus
871 we can only assign the corresponding parameter of the
872 reprepared statement from the original value.
873
874 @param[out] param_array_dst parameter markers of the new statement
875 @param[in] param_array_src parameter markers of the original
876 statement
877 @param[in] param_count total number of parameters. Is the
878 same in src and dst arrays, since
879 the statement query is the same
880 */
881
swap_parameter_array(Item_param ** param_array_dst,Item_param ** param_array_src,uint param_count)882 static void swap_parameter_array(Item_param **param_array_dst,
883 Item_param **param_array_src,
884 uint param_count) {
885 Item_param **dst = param_array_dst;
886 Item_param **src = param_array_src;
887 Item_param **end = param_array_dst + param_count;
888
889 for (; dst < end; ++src, ++dst) {
890 (*dst)->set_param_type_and_swap_value(*src);
891 (*dst)->sync_clones();
892 (*src)->sync_clones();
893 }
894 }
895
896 /**
897 Assign prepared statement parameters from user variables.
898 If with_log is set, also construct query test for binary log.
899
900 @param varnames List of variables. Caller must ensure that number
901 of variables in the list is equal to number of statement
902 parameters
903 @param query The query with parameter markers replaced with corresponding
904 user variables that were used to execute the query.
905 */
906
insert_params_from_vars(List<LEX_STRING> & varnames,String * query)907 bool Prepared_statement::insert_params_from_vars(List<LEX_STRING> &varnames,
908 String *query) {
909 Item_param **begin = param_array;
910 Item_param **end = begin + param_count;
911 List_iterator<LEX_STRING> var_it(varnames);
912 StringBuffer<STRING_BUFFER_USUAL_SIZE> buf;
913 const String *val;
914 size_t length = 0;
915
916 DBUG_TRACE;
917
918 // Reserve an extra space of 32 bytes for each placeholder parameter.
919 if (with_log) query->reserve(m_query_string.length + 32 * param_count);
920
921 /* Protects thd->user_vars */
922 mysql_mutex_lock(&thd->LOCK_thd_data);
923
924 for (Item_param **it = begin; it < end; ++it) {
925 Item_param *param = *it;
926 LEX_STRING *varname = var_it++;
927
928 user_var_entry *entry =
929 find_or_nullptr(thd->user_vars, to_string(*varname));
930 if (with_log) {
931 /*
932 We have to call the setup_one_conversion_function() here to set
933 the parameter's members that might be needed further
934 (e.g. value.cs_info.character_set_client is used in the
935 query_val_str()).
936 */
937 setup_one_conversion_function(thd, param, param->data_type());
938 if (param->set_from_user_var(thd, entry)) goto error;
939 val = param->query_val_str(thd, &buf);
940
941 if (param->convert_str_value()) goto error;
942
943 size_t num_bytes = param->pos_in_query - length;
944 if (query->length() + num_bytes + val->length() >
945 std::numeric_limits<uint32>::max())
946 goto error;
947
948 if (query->append(m_query_string.str + length, num_bytes) ||
949 query->append(*val))
950 goto error;
951
952 length = param->pos_in_query + 1;
953 } else {
954 if (param->set_from_user_var(thd, entry)) goto error;
955
956 if (entry) length += entry->length();
957
958 if (length > std::numeric_limits<uint32>::max() ||
959 param->convert_str_value())
960 goto error;
961 }
962 param->sync_clones();
963 }
964
965 /*
966 If logging, take care of tail.
967 */
968 if (with_log)
969 query->append(m_query_string.str + length, m_query_string.length - length);
970
971 mysql_mutex_unlock(&thd->LOCK_thd_data);
972 return false;
973
974 error:
975 mysql_mutex_unlock(&thd->LOCK_thd_data);
976 return true;
977 }
978
979 /**
980 Validate SHOW statement.
981
982 In case of success, if this query is not EXPLAIN, send column list info
983 back to the client.
984
985 @param stmt prepared statement
986 @param tables list of tables used in the query
987
988 @return false on succes and true on error
989 */
990
mysql_test_show(Prepared_statement * stmt,TABLE_LIST * tables)991 bool mysql_test_show(Prepared_statement *stmt, TABLE_LIST *tables) {
992 THD *thd = stmt->thd;
993 LEX *lex = stmt->lex;
994 SELECT_LEX_UNIT *unit = lex->unit;
995 DBUG_TRACE;
996
997 DBUG_ASSERT(!thd->is_error());
998
999 lex->select_lex->context.resolve_in_select_list = true;
1000
1001 if (show_precheck(thd, lex, false)) goto error;
1002
1003 DBUG_ASSERT(lex->result == nullptr);
1004 DBUG_ASSERT(lex->sql_command != SQLCOM_DO);
1005 DBUG_ASSERT(!lex->is_explain());
1006
1007 if (!lex->result) {
1008 if (!(lex->result = new (stmt->m_arena.mem_root) Query_result_send()))
1009 goto error; /* purecov: inspected */
1010 }
1011
1012 if (open_tables_for_query(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL))
1013 goto error;
1014
1015 /*
1016 SELECT_LEX::prepare calls
1017 It is not SELECT COMMAND for sure, so setup_tables will be called as
1018 usual, and we pass 0 as setup_tables_done_option
1019 */
1020 if (unit->prepare(thd, nullptr, 0, 0)) goto error;
1021
1022 return false;
1023 error:
1024 return true;
1025 }
1026
send_statement(THD * thd,const Prepared_statement * stmt,uint no_columns,Query_result * result,List<Item> * types)1027 bool send_statement(THD *thd, const Prepared_statement *stmt, uint no_columns,
1028 Query_result *result, List<Item> *types) {
1029 // Send the statement status(id, no_columns, no_params, error_count);
1030 bool rc = thd->get_protocol()->store_ps_status(
1031 stmt->id, no_columns, stmt->param_count,
1032 thd->get_stmt_da()->current_statement_cond_count());
1033 if (!rc && stmt->param_count)
1034 // Send the list of parameters
1035 rc |= thd->send_result_metadata((List<Item> *)&stmt->lex->param_list,
1036 Protocol::SEND_EOF);
1037 if (rc) return true; /* purecov: inspected */
1038
1039 // Send
1040 if (types && result &&
1041 result->send_result_set_metadata(thd, *types, Protocol::SEND_EOF))
1042 return true; /* purecov: inspected */
1043
1044 // Flag that a response has already been sent
1045 thd->get_stmt_da()->disable_status();
1046
1047 // Flush the result only if previous statements succeeded.
1048 if (!rc) {
1049 thd->get_stmt_da()->set_overwrite_status(true);
1050 rc |= thd->get_protocol()->flush();
1051 thd->get_stmt_da()->set_overwrite_status(false);
1052 }
1053
1054 return rc;
1055 }
1056
1057 /**
1058 Validate and prepare for execution SET statement expressions.
1059
1060 @param stmt prepared statement
1061 @param tables list of tables used in this query
1062 @param var_list list of expressions
1063
1064 @retval
1065 false success
1066 @retval
1067 true error, error message is set in THD
1068 */
1069
mysql_test_set_fields(Prepared_statement * stmt,TABLE_LIST * tables,List<set_var_base> * var_list)1070 static bool mysql_test_set_fields(Prepared_statement *stmt, TABLE_LIST *tables,
1071 List<set_var_base> *var_list) {
1072 List_iterator_fast<set_var_base> it(*var_list);
1073 THD *thd = stmt->thd;
1074 set_var_base *var;
1075 DBUG_TRACE;
1076 DBUG_ASSERT(stmt->m_arena.is_stmt_prepare());
1077
1078 if (tables &&
1079 check_table_access(thd, SELECT_ACL, tables, false, UINT_MAX, false))
1080 return true; /* purecov: inspected */
1081
1082 if (open_tables_for_query(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL))
1083 return true; /* purecov: inspected */
1084
1085 while ((var = it++)) {
1086 if (var->light_check(thd)) return true; /* purecov: inspected */
1087 }
1088
1089 return false;
1090 }
1091
1092 /**
1093 Check internal SELECT of the prepared command.
1094
1095 @note Old version. Will be replaced with select_like_stmt_cmd_test() after
1096 the parser refactoring.
1097
1098 @param thd Thread handle.
1099
1100 @note
1101 This function won't directly open tables used in select. They should
1102 be opened either by calling function (and in this case you probably
1103 should use select_like_stmt_test_with_open()) or by
1104 "specific_prepare" call (like this happens in case of multi-update).
1105
1106 @retval
1107 false success
1108 @retval
1109 true error, error message is set in THD
1110 */
1111
select_like_stmt_test(THD * thd)1112 static bool select_like_stmt_test(THD *thd) {
1113 DBUG_TRACE;
1114 LEX *const lex = thd->lex;
1115
1116 lex->select_lex->context.resolve_in_select_list = true;
1117
1118 /* Calls SELECT_LEX::prepare */
1119 const bool ret = lex->unit->prepare(thd, nullptr, 0, 0);
1120 return ret;
1121 }
1122
1123 /**
1124 Validate and prepare for execution CREATE TABLE statement.
1125
1126 @param thd Thread handle.
1127
1128 @retval
1129 false success
1130 @retval
1131 true error, error message is set in THD
1132 */
1133
prepare(THD * thd)1134 bool Sql_cmd_create_table::prepare(THD *thd) {
1135 LEX *const lex = thd->lex;
1136 SELECT_LEX *select_lex = lex->select_lex;
1137 TABLE_LIST *create_table = lex->query_tables;
1138 DBUG_TRACE;
1139
1140 if (create_table_precheck(thd, query_expression_tables, create_table))
1141 return true;
1142
1143 if (select_lex->fields_list.elements) {
1144 /* Base table and temporary table are not in the same name space. */
1145 if (!(lex->create_info->options & HA_LEX_CREATE_TMP_TABLE))
1146 create_table->open_type = OT_BASE_ONLY;
1147
1148 if (open_tables_for_query(thd, lex->query_tables,
1149 MYSQL_OPEN_FORCE_SHARED_MDL))
1150 return true;
1151
1152 select_lex->context.resolve_in_select_list = true;
1153
1154 bool link_to_local;
1155 lex->unlink_first_table(&link_to_local);
1156 const bool res = select_like_stmt_test(thd);
1157 lex->link_first_table_back(create_table, link_to_local);
1158 if (res) return true;
1159 } else {
1160 /*
1161 Check that the source table exist, and also record
1162 its metadata version. Even though not strictly necessary,
1163 we validate metadata of all CREATE TABLE statements,
1164 which keeps metadata validation code simple.
1165 */
1166 if (open_tables_for_query(thd, lex->query_tables,
1167 MYSQL_OPEN_FORCE_SHARED_MDL))
1168 return true;
1169 }
1170
1171 set_prepared();
1172 return false;
1173 }
1174
1175 /**
1176 @brief Validate and prepare for execution CREATE VIEW statement
1177
1178 @param stmt prepared statement
1179
1180 @note This function handles create view commands.
1181
1182 @retval false Operation was a success.
1183 @retval true An error occurred.
1184 */
1185
mysql_test_create_view(Prepared_statement * stmt)1186 static bool mysql_test_create_view(Prepared_statement *stmt) {
1187 THD *thd = stmt->thd;
1188 LEX *lex = stmt->lex;
1189 bool res = true;
1190 /* Skip first table, which is the view we are creating */
1191 bool link_to_local;
1192 TABLE_LIST *view = lex->unlink_first_table(&link_to_local);
1193 TABLE_LIST *tables = lex->query_tables;
1194 DBUG_TRACE;
1195 DBUG_ASSERT(stmt->m_arena.is_stmt_prepare());
1196
1197 if (create_view_precheck(thd, tables, view, lex->create_view_mode)) goto err;
1198
1199 /*
1200 Since we can't pre-open temporary tables for SQLCOM_CREATE_VIEW,
1201 (see mysql_create_view) we have to do it here instead.
1202 */
1203 if (open_temporary_tables(thd, tables)) goto err;
1204
1205 if (open_tables_for_query(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL)) goto err;
1206
1207 lex->context_analysis_only |= CONTEXT_ANALYSIS_ONLY_VIEW;
1208 res = select_like_stmt_test(thd);
1209
1210 err:
1211 /* put view back for PS rexecuting */
1212 lex->link_first_table_back(view, link_to_local);
1213 return res;
1214 }
1215
1216 /**
1217 Perform semantic analysis of the parsed tree and send a response packet
1218 to the client.
1219
1220 This function
1221 - opens all tables and checks access rights
1222 - validates semantics of statement columns and SQL functions
1223 by calling fix_fields.
1224
1225 @param stmt prepared statement
1226
1227 @retval
1228 false success, statement metadata is sent to client
1229 @retval
1230 true error, error message is set in THD (but not sent)
1231 */
1232
check_prepared_statement(Prepared_statement * stmt)1233 static bool check_prepared_statement(Prepared_statement *stmt) {
1234 THD *thd = stmt->thd;
1235 LEX *lex = stmt->lex;
1236 DBUG_ASSERT(lex == thd->lex); // set_n_backup_active_arena() guarantees that
1237 SELECT_LEX *select_lex = lex->select_lex;
1238 enum enum_sql_command sql_command = lex->sql_command;
1239 int res = 0;
1240 DBUG_TRACE;
1241 DBUG_PRINT("enter",
1242 ("command: %d param_count: %u", sql_command, stmt->param_count));
1243
1244 lex->first_lists_tables_same();
1245 TABLE_LIST *const tables = lex->query_tables;
1246
1247 /* set context for commands which do not use setup_tables */
1248 lex->select_lex->context.resolve_in_table_list_only(
1249 select_lex->get_table_list());
1250
1251 /*
1252 For the optimizer trace, this is the symmetric, for statement preparation,
1253 of what is done at statement execution (in mysql_execute_command()).
1254 */
1255 Opt_trace_start ots(thd, tables, sql_command, &lex->var_list,
1256 thd->query().str, thd->query().length, nullptr,
1257 thd->variables.character_set_client);
1258
1259 Opt_trace_object trace_command(&thd->opt_trace);
1260 Opt_trace_array trace_command_steps(&thd->opt_trace, "steps");
1261
1262 if ((thd->lex->keep_diagnostics == DA_KEEP_COUNTS) ||
1263 (thd->lex->keep_diagnostics == DA_KEEP_DIAGNOSTICS)) {
1264 my_error(ER_UNSUPPORTED_PS, MYF(0));
1265 return true;
1266 }
1267
1268 if (sql_command_flags[sql_command] & CF_HA_CLOSE)
1269 mysql_ha_rm_tables(thd, tables);
1270
1271 /*
1272 Open temporary tables that are known now. Temporary tables added by
1273 prelocking will be opened afterwards (during open_tables()).
1274 */
1275 if (sql_command_flags[sql_command] & CF_PREOPEN_TMP_TABLES) {
1276 if (open_temporary_tables(thd, tables)) return true;
1277 }
1278
1279 switch (sql_command) {
1280 /* The following allow WHERE clause, so they must be tested like SELECT */
1281 case SQLCOM_SHOW_DATABASES:
1282 case SQLCOM_SHOW_TABLES:
1283 case SQLCOM_SHOW_TRIGGERS:
1284 case SQLCOM_SHOW_EVENTS:
1285 case SQLCOM_SHOW_OPEN_TABLES:
1286 case SQLCOM_SHOW_COLLATIONS:
1287 case SQLCOM_SHOW_CHARSETS:
1288 case SQLCOM_SHOW_VARIABLES:
1289 case SQLCOM_SHOW_STATUS:
1290 case SQLCOM_SHOW_TABLE_STATUS:
1291 case SQLCOM_SHOW_STATUS_PROC:
1292 case SQLCOM_SHOW_STATUS_FUNC:
1293 if (mysql_test_show(stmt, tables)) return true;
1294 break;
1295 case SQLCOM_CREATE_VIEW:
1296 if (lex->create_view_mode == enum_view_create_mode::VIEW_ALTER) {
1297 my_error(ER_UNSUPPORTED_PS, MYF(0));
1298 return true;
1299 }
1300 res = mysql_test_create_view(stmt);
1301 break;
1302
1303 case SQLCOM_SET_PASSWORD:
1304 case SQLCOM_SET_OPTION:
1305 res = mysql_test_set_fields(stmt, tables, &lex->var_list);
1306 break;
1307
1308 /*
1309 Note that we don't need to have cases in this list if they are
1310 marked with CF_STATUS_COMMAND in sql_command_flags
1311 */
1312 case SQLCOM_DROP_TABLE:
1313 case SQLCOM_RENAME_TABLE:
1314 case SQLCOM_ALTER_TABLE:
1315 case SQLCOM_COMMIT:
1316 case SQLCOM_CREATE_INDEX:
1317 case SQLCOM_DROP_INDEX:
1318 case SQLCOM_ROLLBACK:
1319 case SQLCOM_TRUNCATE:
1320 case SQLCOM_DROP_VIEW:
1321 case SQLCOM_REPAIR:
1322 case SQLCOM_ANALYZE:
1323 case SQLCOM_OPTIMIZE:
1324 case SQLCOM_CHANGE_MASTER:
1325 case SQLCOM_CHANGE_REPLICATION_FILTER:
1326 case SQLCOM_RESET:
1327 case SQLCOM_FLUSH:
1328 case SQLCOM_SLAVE_START:
1329 case SQLCOM_SLAVE_STOP:
1330 case SQLCOM_INSTALL_PLUGIN:
1331 case SQLCOM_UNINSTALL_PLUGIN:
1332 case SQLCOM_CREATE_DB:
1333 case SQLCOM_DROP_DB:
1334 case SQLCOM_CHECKSUM:
1335 case SQLCOM_CREATE_USER:
1336 case SQLCOM_RENAME_USER:
1337 case SQLCOM_DROP_USER:
1338 case SQLCOM_ALTER_USER:
1339 case SQLCOM_ASSIGN_TO_KEYCACHE:
1340 case SQLCOM_PRELOAD_KEYS:
1341 case SQLCOM_GRANT:
1342 case SQLCOM_GRANT_ROLE:
1343 case SQLCOM_REVOKE:
1344 case SQLCOM_REVOKE_ALL:
1345 case SQLCOM_REVOKE_ROLE:
1346 case SQLCOM_KILL:
1347 case SQLCOM_ALTER_INSTANCE:
1348 case SQLCOM_SET_ROLE:
1349 case SQLCOM_ALTER_USER_DEFAULT_ROLE:
1350 break;
1351
1352 case SQLCOM_CREATE_TABLE:
1353 /*
1354 CREATE TABLE ... START TRANSACTION is not supported with
1355 prepared statements
1356 */
1357 if (lex->create_info->m_transactional_ddl) {
1358 my_error(ER_UNSUPPORTED_PS, MYF(0));
1359 return true;
1360 }
1361 #if defined(__has_cpp_attribute)
1362 #if __has_cpp_attribute(fallthrough)
1363 [[fallthrough]];
1364 #endif
1365 #endif
1366 case SQLCOM_SELECT:
1367 case SQLCOM_DO:
1368 case SQLCOM_DELETE:
1369 case SQLCOM_DELETE_MULTI:
1370 case SQLCOM_UPDATE:
1371 case SQLCOM_UPDATE_MULTI:
1372 case SQLCOM_INSERT:
1373 case SQLCOM_INSERT_SELECT:
1374 case SQLCOM_REPLACE:
1375 case SQLCOM_REPLACE_SELECT:
1376 case SQLCOM_CALL:
1377 case SQLCOM_SHOW_FIELDS:
1378 case SQLCOM_SHOW_KEYS:
1379 case SQLCOM_SET_RESOURCE_GROUP:
1380 res = lex->m_sql_cmd->prepare(thd);
1381 // @todo Temporary solution: Unprepare after preparation to preserve
1382 // old behaviour
1383 if (!res) lex->m_sql_cmd->unprepare(thd);
1384 break;
1385
1386 case SQLCOM_PREPARE:
1387 case SQLCOM_EXECUTE:
1388 case SQLCOM_DEALLOCATE_PREPARE:
1389 default:
1390 /*
1391 Trivial check of all status commands and diagnostic commands.
1392 This is easier than having things in the above case list,
1393 as it's less chance for mistakes.
1394 */
1395 if (!(sql_command_flags[sql_command] & CF_STATUS_COMMAND) ||
1396 (sql_command_flags[sql_command] & CF_DIAGNOSTIC_STMT)) {
1397 /* All other statements are not supported yet. */
1398 my_error(ER_UNSUPPORTED_PS, MYF(0));
1399 return true;
1400 }
1401 break;
1402 }
1403 if (res) return true;
1404
1405 if (stmt->is_sql_prepare()) return false;
1406
1407 List<Item> *types = nullptr;
1408 Query_result *result = nullptr;
1409 uint no_columns = 0;
1410
1411 if ((sql_command_flags[lex->sql_command] & CF_HAS_RESULT_SET) &&
1412 !lex->is_explain()) {
1413 SELECT_LEX_UNIT *unit = lex->unit;
1414 result = unit->query_result();
1415 if (result == nullptr) result = unit->first_select()->query_result();
1416 if (result == nullptr) result = lex->result;
1417 types = unit->get_unit_column_types();
1418 no_columns = result->field_count(*types);
1419 }
1420
1421 return send_statement(thd, stmt, no_columns, result, types);
1422 }
1423
1424 /**
1425 Initialize array of parameters in statement from LEX.
1426 (We need to have quick access to items by number in mysql_stmt_get_longdata).
1427 This is to avoid using malloc/realloc in the parser.
1428 */
1429
init_param_array(Prepared_statement * stmt)1430 static bool init_param_array(Prepared_statement *stmt) {
1431 LEX *lex = stmt->lex;
1432 if ((stmt->param_count = lex->param_list.elements)) {
1433 if (stmt->param_count > (uint)UINT_MAX16) {
1434 /* Error code to be defined in 5.0 */
1435 my_error(ER_PS_MANY_PARAM, MYF(0));
1436 return true;
1437 }
1438
1439 Item_param **to;
1440 List_iterator<Item_param> param_iterator(lex->param_list);
1441 /* Use thd->mem_root as it points at statement mem_root */
1442 stmt->param_array =
1443 stmt->thd->mem_root->ArrayAlloc<Item_param *>(stmt->param_count);
1444 if (stmt->param_array == nullptr) return true;
1445 for (to = stmt->param_array; to < stmt->param_array + stmt->param_count;
1446 ++to) {
1447 *to = param_iterator++;
1448 }
1449 }
1450 return false;
1451 }
1452
1453 /**
1454 COM_STMT_PREPARE handler.
1455
1456 Given a query string with parameter markers, create a prepared
1457 statement from it and send PS info back to the client.
1458
1459 If parameter markers are found in the query, then store the information
1460 using Item_param along with maintaining a list in lex->param_array, so
1461 that a fast and direct retrieval can be made without going through all
1462 field items.
1463
1464 In case of success a new statement id and metadata is sent
1465 to the client, otherwise an error message is set in THD.
1466
1467 @param thd thread handle
1468 @param query query to be prepared
1469 @param length query string length, including ignored
1470 trailing NULL or quote char.
1471 @param stmt Prepared_statement to be used for preparation.
1472
1473 @note
1474 This function parses the query and sends the total number of parameters
1475 and resultset metadata information back to client (if any), without
1476 executing the query i.e. without any log/disk writes. This allows the
1477 queries to be re-executed without re-parsing during execute.
1478 */
1479
mysqld_stmt_prepare(THD * thd,const char * query,uint length,Prepared_statement * stmt)1480 void mysqld_stmt_prepare(THD *thd, const char *query, uint length,
1481 Prepared_statement *stmt) {
1482 DBUG_TRACE;
1483 DBUG_PRINT("prep_query", ("%s", query));
1484 DBUG_ASSERT(stmt != nullptr);
1485
1486 bool switch_protocol = thd->is_classic_protocol();
1487 if (switch_protocol) {
1488 // set the current client capabilities before switching the protocol
1489 thd->protocol_binary->set_client_capabilities(
1490 thd->get_protocol()->get_client_capabilities());
1491 thd->push_protocol(thd->protocol_binary);
1492 }
1493
1494 // Initially, optimize the statement for the primary storage engine.
1495 // If an eligible secondary storage engine is found, the statement
1496 // may be reprepared for the secondary storage engine later.
1497 const auto saved_secondary_engine = thd->secondary_engine_optimization();
1498 thd->set_secondary_engine_optimization(
1499 Secondary_engine_optimization::PRIMARY_TENTATIVELY);
1500 /* Create PS table entry, set query text after rewrite. */
1501 stmt->m_prepared_stmt =
1502 MYSQL_CREATE_PS(stmt, stmt->id, thd->m_statement_psi, stmt->name().str,
1503 stmt->name().length, nullptr, 0);
1504
1505 if (stmt->prepare(query, length)) {
1506 /* Delete this stmt stats from PS table. */
1507 MYSQL_DESTROY_PS(stmt->m_prepared_stmt);
1508 /* Statement map deletes statement on erase */
1509 thd->stmt_map.erase(stmt);
1510 }
1511
1512 thd->set_secondary_engine_optimization(saved_secondary_engine);
1513 if (switch_protocol) thd->pop_protocol();
1514
1515 sp_cache_enforce_limit(thd->sp_proc_cache, stored_program_cache_size);
1516 sp_cache_enforce_limit(thd->sp_func_cache, stored_program_cache_size);
1517
1518 /* check_prepared_statement sends the metadata packet in case of success */
1519 }
1520
1521 /**
1522 Searches for the statement with the specified id and validates it.
1523
1524 @param thd [in] thread handle
1525 @param com_data [in] command data
1526 @param cmd [in] command type to be executed
1527 @param stmt [out] pointer to Prepared_statement to store it if found
1528 */
1529
mysql_stmt_precheck(THD * thd,const COM_DATA * com_data,enum enum_server_command cmd,Prepared_statement ** stmt)1530 bool mysql_stmt_precheck(THD *thd, const COM_DATA *com_data,
1531 enum enum_server_command cmd,
1532 Prepared_statement **stmt) {
1533 *stmt = nullptr;
1534 ulong stmt_id = 0;
1535
1536 switch (cmd) {
1537 case COM_STMT_FETCH:
1538 stmt_id = com_data->com_stmt_fetch.stmt_id;
1539 if (!(*stmt = thd->stmt_map.find(stmt_id))) goto not_found;
1540 break;
1541 case COM_STMT_CLOSE:
1542 stmt_id = com_data->com_stmt_close.stmt_id;
1543 if (!(*stmt = thd->stmt_map.find(stmt_id))) goto silent_error;
1544 break;
1545 case COM_STMT_RESET: {
1546 stmt_id = com_data->com_stmt_reset.stmt_id;
1547 if (!(*stmt = thd->stmt_map.find(stmt_id))) goto not_found;
1548 break;
1549 }
1550 case COM_STMT_PREPARE: {
1551 if (!(*stmt = new Prepared_statement(thd)))
1552 // out of memory: error is set in MEM_ROOT
1553 goto silent_error; /* purecov: inspected */
1554
1555 if (thd->stmt_map.insert(*stmt))
1556 /*
1557 The error is set in the insert. The statement itself
1558 will be also deleted there (this is how the hash works).
1559 */
1560 goto silent_error;
1561 break;
1562 }
1563 case COM_STMT_SEND_LONG_DATA: {
1564 stmt_id = com_data->com_stmt_send_long_data.stmt_id;
1565 if (!(*stmt = thd->stmt_map.find(stmt_id))) goto silent_error;
1566 if (com_data->com_stmt_send_long_data.param_number >=
1567 (*stmt)->param_count) {
1568 /* Error will be sent in execute call */
1569 (*stmt)->m_arena.set_state(Query_arena::STMT_ERROR);
1570 (*stmt)->last_errno = ER_WRONG_ARGUMENTS;
1571 sprintf((*stmt)->last_error, ER_THD(thd, ER_WRONG_ARGUMENTS),
1572 "mysql_stmt_precheck");
1573 goto silent_error;
1574 }
1575 break;
1576 }
1577 case COM_STMT_EXECUTE: {
1578 stmt_id = com_data->com_stmt_execute.stmt_id;
1579 if (!(*stmt = thd->stmt_map.find(stmt_id))) goto not_found;
1580 if ((*stmt)->param_count != com_data->com_stmt_execute.parameter_count)
1581 goto wrong_arg;
1582 break;
1583 }
1584 default:
1585 DBUG_ASSERT(0);
1586 return true;
1587 }
1588 return false;
1589
1590 not_found:
1591 char llbuf[22];
1592 my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), static_cast<int>(sizeof(llbuf)),
1593 llstr(stmt_id, llbuf), "mysql_stmt_precheck");
1594 return true;
1595
1596 wrong_arg:
1597 my_error(ER_WRONG_ARGUMENTS, MYF(0), "COM_STMT_EXECUTE");
1598 return true;
1599
1600 silent_error:
1601 return true;
1602 }
1603
1604 /**
1605 Get an SQL statement text from a user variable or from plain text.
1606
1607 If the statement is plain text, just assign the
1608 pointers, otherwise allocate memory in thd->mem_root and copy
1609 the contents of the variable, possibly with character
1610 set conversion.
1611
1612 @param[in] lex main lex
1613 @param[out] query_len length of the SQL statement (is set only
1614 in case of success)
1615
1616 @retval
1617 non-zero success
1618 @retval
1619 0 in case of error (out of memory)
1620 */
1621
get_dynamic_sql_string(LEX * lex,size_t * query_len)1622 static const char *get_dynamic_sql_string(LEX *lex, size_t *query_len) {
1623 THD *thd = lex->thd;
1624 char *query_str = nullptr;
1625
1626 if (lex->prepared_stmt_code_is_varref) {
1627 /* This is PREPARE stmt FROM or EXECUTE IMMEDIATE @var. */
1628 String str;
1629 const CHARSET_INFO *to_cs = thd->variables.collation_connection;
1630 bool needs_conversion;
1631 String *var_value = &str;
1632 size_t unused;
1633 size_t len;
1634
1635 /* Protects thd->user_vars */
1636 mysql_mutex_lock(&thd->LOCK_thd_data);
1637
1638 const auto it = thd->user_vars.find(to_string(lex->prepared_stmt_code));
1639
1640 /*
1641 Convert @var contents to string in connection character set. Although
1642 it is known that int/real/NULL value cannot be a valid query we still
1643 convert it for error messages to be uniform.
1644 */
1645 if (it != thd->user_vars.end() && it->second->ptr()) {
1646 user_var_entry *entry = it->second.get();
1647 bool is_var_null;
1648 var_value = entry->val_str(&is_var_null, &str, DECIMAL_NOT_SPECIFIED);
1649
1650 mysql_mutex_unlock(&thd->LOCK_thd_data);
1651
1652 /*
1653 NULL value of variable checked early as entry->value so here
1654 we can't get NULL in normal conditions
1655 */
1656 DBUG_ASSERT(!is_var_null);
1657 if (!var_value) goto end;
1658 } else {
1659 mysql_mutex_unlock(&thd->LOCK_thd_data);
1660
1661 /*
1662 variable absent or equal to NULL, so we need to set variable to
1663 something reasonable to get a readable error message during parsing
1664 */
1665 str.set(STRING_WITH_LEN("NULL"), &my_charset_latin1);
1666 }
1667
1668 needs_conversion = String::needs_conversion(
1669 var_value->length(), var_value->charset(), to_cs, &unused);
1670
1671 len = (needs_conversion ? var_value->length() * to_cs->mbmaxlen
1672 : var_value->length());
1673 if (!(query_str = (char *)thd->mem_root->Alloc(len + 1))) goto end;
1674
1675 if (needs_conversion) {
1676 uint dummy_errors;
1677 len = copy_and_convert(query_str, len, to_cs, var_value->ptr(),
1678 var_value->length(), var_value->charset(),
1679 &dummy_errors);
1680 } else
1681 memcpy(query_str, var_value->ptr(), var_value->length());
1682 query_str[len] = '\0'; // Safety (mostly for debug)
1683 *query_len = len;
1684 } else {
1685 query_str = lex->prepared_stmt_code.str;
1686 *query_len = lex->prepared_stmt_code.length;
1687 }
1688 end:
1689 return query_str;
1690 }
1691
1692 /**
1693 SQLCOM_PREPARE implementation.
1694
1695 Prepare an SQL prepared statement. This is called from
1696 mysql_execute_command and should therefore behave like an
1697 ordinary query (e.g. should not reset any global THD data).
1698
1699 In case of success, OK packet is sent to the client,
1700 otherwise an error message is set in THD.
1701
1702 @param thd thread handle
1703 */
1704
mysql_sql_stmt_prepare(THD * thd)1705 void mysql_sql_stmt_prepare(THD *thd) {
1706 LEX *lex = thd->lex;
1707 const LEX_CSTRING &name = lex->prepared_stmt_name;
1708 Prepared_statement *stmt;
1709 const char *query;
1710 size_t query_len = 0;
1711 DBUG_TRACE;
1712
1713 if ((stmt = thd->stmt_map.find_by_name(name))) {
1714 /*
1715 If there is a statement with the same name, remove it. It is ok to
1716 remove old and fail to insert a new one at the same time.
1717 */
1718 if (stmt->is_in_use()) {
1719 my_error(ER_PS_NO_RECURSION, MYF(0));
1720 return;
1721 }
1722
1723 MYSQL_DESTROY_PS(stmt->m_prepared_stmt);
1724 stmt->deallocate();
1725 }
1726
1727 if (!(query = get_dynamic_sql_string(lex, &query_len)) ||
1728 !(stmt = new Prepared_statement(thd))) {
1729 return; /* out of memory */
1730 }
1731
1732 stmt->set_sql_prepare();
1733
1734 /* Set the name first, insert should know that this statement has a name */
1735 if (stmt->set_name(name)) {
1736 delete stmt;
1737 return;
1738 }
1739
1740 if (thd->stmt_map.insert(stmt)) {
1741 /* The statement is deleted and an error is set if insert fails */
1742 return;
1743 }
1744
1745 /* Create PS table entry, set query text after rewrite. */
1746 stmt->m_prepared_stmt =
1747 MYSQL_CREATE_PS(stmt, stmt->id, thd->m_statement_psi, stmt->name().str,
1748 stmt->name().length, nullptr, 0);
1749
1750 if (stmt->prepare(query, query_len)) {
1751 /* Delete this stmt stats from PS table. */
1752 MYSQL_DESTROY_PS(stmt->m_prepared_stmt);
1753 /* Statement map deletes the statement on erase */
1754 thd->stmt_map.erase(stmt);
1755 } else {
1756 /* send the boolean tracker in the OK packet when
1757 @@session_track_state_change is set to ON */
1758 if (thd->session_tracker.get_tracker(SESSION_STATE_CHANGE_TRACKER)
1759 ->is_enabled())
1760 thd->session_tracker.get_tracker(SESSION_STATE_CHANGE_TRACKER)
1761 ->mark_as_changed(thd, nullptr);
1762 my_ok(thd, 0L, 0L, "Statement prepared");
1763 }
1764 }
1765
1766 /**
1767 Reinit prepared statement/stored procedure before execution. Resets the LEX
1768 object.
1769
1770
1771 @todo
1772 When the new table structure is ready, then have a status bit
1773 to indicate the table is altered, and re-do the setup_*
1774 and open the tables back.
1775
1776 @retval false OK.
1777 @retval true Error.
1778 */
1779
reinit_stmt_before_use(THD * thd,LEX * lex)1780 bool reinit_stmt_before_use(THD *thd, LEX *lex) {
1781 SELECT_LEX *sl = lex->all_selects_list;
1782 DBUG_TRACE;
1783
1784 // Default to READ access for every field that is resolved
1785 thd->mark_used_columns = MARK_COLUMNS_READ;
1786 /*
1787 We have to update "thd" pointer in LEX, all its units and in LEX::result,
1788 since statements which belong to trigger body are associated with TABLE
1789 object and because of this can be used in different threads.
1790 */
1791 lex->thd = thd;
1792
1793 if (lex->m_sql_cmd != nullptr) lex->m_sql_cmd->cleanup(thd);
1794
1795 for (; sl; sl = sl->next_select_in_list()) {
1796 if (!sl->first_execution) {
1797 /* see unique_table() */
1798 sl->exclude_from_table_unique_test = false;
1799
1800 /*
1801 These must be reset before every new preparation.
1802 @note done here and not in SELECT_LEX::prepare() since for
1803 multi-table UPDATE and DELETE, derived tables are merged into
1804 the outer query block before ::prepare() is called.
1805 */
1806 sl->cond_count = 0;
1807 sl->between_count = 0;
1808 sl->max_equal_elems = 0;
1809
1810 if (sl->where_cond()) {
1811 DBUG_ASSERT(sl->where_cond()->real_item()); // no dangling 'ref'
1812 sl->where_cond()->cleanup();
1813 }
1814 if (sl->having_cond()) {
1815 DBUG_ASSERT(sl->having_cond()->real_item());
1816 sl->having_cond()->cleanup();
1817 }
1818 DBUG_ASSERT(sl->join == nullptr);
1819 ORDER *order;
1820 /* Fix GROUP list */
1821 if (sl->group_list_ptrs && sl->group_list_ptrs->size() > 0) {
1822 for (uint ix = 0; ix < sl->group_list_ptrs->size() - 1; ++ix) {
1823 order = sl->group_list_ptrs->at(ix);
1824 order->next = sl->group_list_ptrs->at(ix + 1);
1825 }
1826 }
1827 for (order = sl->group_list.first; order; order = order->next)
1828 order->item = &order->item_ptr;
1829 /* Fix ORDER list */
1830 if (sl->order_list_ptrs && sl->order_list_ptrs->size() > 0) {
1831 for (uint ix = 0; ix < sl->order_list_ptrs->size() - 1; ++ix) {
1832 order = sl->order_list_ptrs->at(ix);
1833 order->next = sl->order_list_ptrs->at(ix + 1);
1834 }
1835 }
1836 for (order = sl->order_list.first; order; order = order->next)
1837 order->item = &order->item_ptr;
1838 if (sl->m_windows.elements > 0) {
1839 List_iterator<Window> li(sl->m_windows);
1840 Window *w;
1841 while ((w = li++)) w->reinit_before_use();
1842 }
1843 }
1844 {
1845 SELECT_LEX_UNIT *unit = sl->master_unit();
1846 unit->unclean();
1847 unit->types.empty();
1848 /* for derived tables & PS (which can't be reset by Item_subquery) */
1849 unit->reinit_exec_mechanism();
1850 }
1851 }
1852
1853 /*
1854 m_view_ctx_list contains all the view tables view_ctx objects and must
1855 be emptied now since it's going to be re-populated below as we reiterate
1856 over all query_tables and call TABLE_LIST::prepare_security().
1857 */
1858 thd->m_view_ctx_list.empty();
1859
1860 /*
1861 TODO: When the new table structure is ready, then have a status bit
1862 to indicate the table is altered, and re-do the setup_*
1863 and open the tables back.
1864 */
1865 /*
1866 NOTE: We should reset whole table list here including all tables added
1867 by prelocking algorithm (it is not a problem for substatements since
1868 they have their own table list).
1869 Another note: this loop uses query_tables so does not see TABLE_LISTs
1870 which represent join nests.
1871 */
1872 for (TABLE_LIST *tables = lex->query_tables; tables;
1873 tables = tables->next_global) {
1874 tables->reinit_before_use(thd);
1875 }
1876
1877 lex->set_current_select(lex->select_lex);
1878
1879 lex->allow_sum_func = 0;
1880 lex->m_deny_window_func = 0;
1881 lex->in_sum_func = nullptr;
1882
1883 lex->reset_exec_started();
1884
1885 if (unlikely(lex->is_broken())) {
1886 // Force a Reprepare, to get a fresh LEX
1887 Reprepare_observer *reprepare_observer = thd->get_reprepare_observer();
1888 if (reprepare_observer && reprepare_observer->report_error(thd)) {
1889 DBUG_ASSERT(thd->is_error());
1890 return true;
1891 }
1892 }
1893
1894 return false;
1895 }
1896
1897 /**
1898 Clears parameters from data left from previous execution or long data.
1899
1900 @param stmt prepared statement for which parameters should
1901 be reset
1902 */
1903
reset_stmt_params(Prepared_statement * stmt)1904 static void reset_stmt_params(Prepared_statement *stmt) {
1905 Item_param **item = stmt->param_array;
1906 Item_param **end = item + stmt->param_count;
1907 for (; item < end; ++item) {
1908 (**item).reset();
1909 (**item).sync_clones();
1910 }
1911 }
1912
1913 /**
1914 COM_STMT_EXECUTE handler: execute a previously prepared statement.
1915
1916 If there are any parameters, then replace parameter markers with the
1917 data supplied from the client, and then execute the statement.
1918 This function uses binary protocol to send a possible result set
1919 to the client.
1920
1921 In case of success OK packet or a result set is sent to the
1922 client, otherwise an error message is set in THD.
1923
1924 @param thd current thread
1925 @param stmt prepared statement
1926 @param has_new_types true if parsed parameters have data types defined
1927 @param execute_flags flag used to decide if a cursor should be used
1928 @param parameters prepared statement's parsed parameters
1929 */
1930
mysqld_stmt_execute(THD * thd,Prepared_statement * stmt,bool has_new_types,ulong execute_flags,PS_PARAM * parameters)1931 void mysqld_stmt_execute(THD *thd, Prepared_statement *stmt, bool has_new_types,
1932 ulong execute_flags, PS_PARAM *parameters) {
1933 DBUG_TRACE;
1934
1935 #if defined(ENABLED_PROFILING)
1936 thd->profiling->set_query_source(stmt->m_query_string.str,
1937 stmt->m_query_string.length);
1938 #endif
1939 DBUG_PRINT("info", ("stmt: %p", stmt));
1940
1941 bool switch_protocol = thd->is_classic_protocol();
1942 if (switch_protocol) {
1943 // set the current client capabilities before switching the protocol
1944 thd->protocol_binary->set_client_capabilities(
1945 thd->get_protocol()->get_client_capabilities());
1946 thd->push_protocol(thd->protocol_binary);
1947 }
1948
1949 MYSQL_EXECUTE_PS(thd->m_statement_psi, stmt->m_prepared_stmt);
1950
1951 // Initially, optimize the statement for the primary storage engine.
1952 // If an eligible secondary storage engine is found, the statement
1953 // may be reprepared for the secondary storage engine later.
1954 const auto saved_secondary_engine = thd->secondary_engine_optimization();
1955 thd->set_secondary_engine_optimization(
1956 Secondary_engine_optimization::PRIMARY_TENTATIVELY);
1957
1958 // Query text for binary, general or slow log, if any of them is open
1959 String expanded_query;
1960 // If no error happened while setting the parameters, execute statement.
1961 if (!stmt->set_parameters(&expanded_query, has_new_types, parameters)) {
1962 bool open_cursor =
1963 static_cast<bool>(execute_flags & (ulong)CURSOR_TYPE_READ_ONLY);
1964 stmt->execute_loop(&expanded_query, open_cursor);
1965 }
1966
1967 thd->set_secondary_engine_optimization(saved_secondary_engine);
1968
1969 if (switch_protocol) thd->pop_protocol();
1970
1971 sp_cache_enforce_limit(thd->sp_proc_cache, stored_program_cache_size);
1972 sp_cache_enforce_limit(thd->sp_func_cache, stored_program_cache_size);
1973
1974 /* Close connection socket; for use with client testing (Bug#43560). */
1975 DBUG_EXECUTE_IF("close_conn_after_stmt_execute",
1976 thd->get_protocol()->shutdown(););
1977 }
1978
1979 /**
1980 SQLCOM_EXECUTE implementation.
1981
1982 Execute prepared statement using parameter values from
1983 lex->prepared_stmt_params and send result to the client using
1984 text protocol. This is called from mysql_execute_command and
1985 therefore should behave like an ordinary query (e.g. not change
1986 global THD data, such as warning count, server status, etc).
1987 This function uses text protocol to send a possible result set.
1988
1989 In case of success, OK (or result set) packet is sent to the
1990 client, otherwise an error is set in THD.
1991
1992 @param thd thread handle
1993 */
1994
mysql_sql_stmt_execute(THD * thd)1995 void mysql_sql_stmt_execute(THD *thd) {
1996 LEX *lex = thd->lex;
1997 const LEX_CSTRING &name = lex->prepared_stmt_name;
1998 DBUG_TRACE;
1999 DBUG_PRINT("info", ("EXECUTE: %.*s\n", (int)name.length, name.str));
2000
2001 Prepared_statement *stmt;
2002 if (!(stmt = thd->stmt_map.find_by_name(name))) {
2003 my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), static_cast<int>(name.length),
2004 name.str, "EXECUTE");
2005 return;
2006 }
2007
2008 if (stmt->param_count != lex->prepared_stmt_params.elements) {
2009 my_error(ER_WRONG_ARGUMENTS, MYF(0), "EXECUTE");
2010 return;
2011 }
2012
2013 DBUG_PRINT("info", ("stmt: %p", stmt));
2014 MYSQL_EXECUTE_PS(thd->m_statement_psi, stmt->m_prepared_stmt);
2015
2016 // Query text for binary, general or slow log, if any of them is open
2017 String expanded_query;
2018 if (stmt->set_parameters(&expanded_query)) return;
2019
2020 stmt->execute_loop(&expanded_query, false);
2021 }
2022
2023 /**
2024 COM_STMT_FETCH handler: fetches requested amount of rows from cursor.
2025
2026 @param thd Thread handle.
2027 @param stmt Pointer to the prepared statement.
2028 @param num_rows Number of rows to fetch.
2029 */
2030
mysqld_stmt_fetch(THD * thd,Prepared_statement * stmt,ulong num_rows)2031 void mysqld_stmt_fetch(THD *thd, Prepared_statement *stmt, ulong num_rows) {
2032 DBUG_TRACE;
2033 thd->status_var.com_stmt_fetch++;
2034
2035 Server_side_cursor *cursor = stmt->cursor;
2036 if (!cursor) {
2037 my_error(ER_STMT_HAS_NO_OPEN_CURSOR, MYF(0), stmt->id);
2038 return;
2039 }
2040
2041 thd->stmt_arena = &stmt->m_arena;
2042 Statement_backup stmt_backup;
2043 stmt_backup.set_thd_to_ps(thd, stmt);
2044
2045 cursor->fetch(num_rows);
2046
2047 if (!cursor->is_open()) {
2048 stmt->close_cursor();
2049 reset_stmt_params(stmt);
2050 }
2051
2052 stmt_backup.restore_thd(thd, stmt);
2053 thd->stmt_arena = thd;
2054 }
2055
2056 /**
2057 Reset a prepared statement in case there was a recoverable error.
2058
2059 This function resets statement to the state it was right after prepare.
2060 It can be used to:
2061 - clear an error happened during mysqld_stmt_send_long_data
2062 - cancel long data stream for all placeholders without
2063 having to call mysqld_stmt_execute.
2064 - close an open cursor
2065 Sends 'OK' packet in case of success (statement was reset)
2066 or 'ERROR' packet (unrecoverable error/statement not found/etc).
2067
2068 @param thd Thread handle
2069 @param stmt Pointer to the Prepared_statement
2070 */
2071
mysqld_stmt_reset(THD * thd,Prepared_statement * stmt)2072 void mysqld_stmt_reset(THD *thd, Prepared_statement *stmt) {
2073 DBUG_TRACE;
2074
2075 thd->status_var.com_stmt_reset++;
2076 stmt->close_cursor();
2077
2078 /*
2079 Clear parameters from data which could be set by
2080 mysqld_stmt_send_long_data() call.
2081 */
2082 reset_stmt_params(stmt);
2083
2084 stmt->m_arena.set_state(Query_arena::STMT_PREPARED);
2085
2086 query_logger.general_log_print(thd, thd->get_command(), NullS);
2087
2088 my_ok(thd);
2089 }
2090
2091 /**
2092 Delete a prepared statement from memory.
2093
2094 @note
2095 we don't send any reply to this command.
2096 */
2097
mysqld_stmt_close(THD * thd,Prepared_statement * stmt)2098 void mysqld_stmt_close(THD *thd, Prepared_statement *stmt) {
2099 DBUG_TRACE;
2100 /*
2101 The only way currently a statement can be deallocated when it's
2102 in use is from within Dynamic SQL.
2103 */
2104 DBUG_ASSERT(!stmt->is_in_use());
2105 MYSQL_DESTROY_PS(stmt->m_prepared_stmt);
2106 stmt->deallocate();
2107 query_logger.general_log_print(thd, thd->get_command(), NullS);
2108 }
2109
2110 /**
2111 SQLCOM_DEALLOCATE implementation.
2112
2113 Close an SQL prepared statement. As this can be called from Dynamic
2114 SQL, we should be careful to not close a statement that is currently
2115 being executed.
2116
2117 OK packet is sent in case of success, otherwise an error
2118 message is set in THD.
2119 */
2120
mysql_sql_stmt_close(THD * thd)2121 void mysql_sql_stmt_close(THD *thd) {
2122 Prepared_statement *stmt;
2123 const LEX_CSTRING &name = thd->lex->prepared_stmt_name;
2124 DBUG_PRINT("info",
2125 ("DEALLOCATE PREPARE: %.*s\n", (int)name.length, name.str));
2126
2127 if (!(stmt = thd->stmt_map.find_by_name(name)))
2128 my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), static_cast<int>(name.length),
2129 name.str, "DEALLOCATE PREPARE");
2130 else if (stmt->is_in_use())
2131 my_error(ER_PS_NO_RECURSION, MYF(0));
2132 else {
2133 MYSQL_DESTROY_PS(stmt->m_prepared_stmt);
2134 stmt->deallocate();
2135 if (thd->session_tracker.get_tracker(SESSION_STATE_CHANGE_TRACKER)
2136 ->is_enabled())
2137 thd->session_tracker.get_tracker(SESSION_STATE_CHANGE_TRACKER)
2138 ->mark_as_changed(thd, nullptr);
2139 my_ok(thd);
2140 }
2141 }
2142
2143 /**
2144 Handle long data in pieces from client.
2145
2146 Get a part of a long data. To make the protocol efficient, we are
2147 not sending any return packets here. If something goes wrong, then
2148 we will send the error on 'execute' We assume that the client takes
2149 care of checking that all parts are sent to the server. (No checking
2150 that we get a 'end of column' in the server is performed).
2151
2152 @param thd Thread handle
2153 @param stmt Pointer to Prepared_statement
2154 @param param_number Number of parameters
2155 @param str String to append
2156 @param length Length of string (including end \\0)
2157 */
2158
mysql_stmt_get_longdata(THD * thd,Prepared_statement * stmt,uint param_number,uchar * str,ulong length)2159 void mysql_stmt_get_longdata(THD *thd, Prepared_statement *stmt,
2160 uint param_number, uchar *str, ulong length) {
2161 DBUG_TRACE;
2162
2163 thd->status_var.com_stmt_send_long_data++;
2164 Diagnostics_area new_stmt_da(false);
2165 thd->push_diagnostics_area(&new_stmt_da);
2166
2167 Item_param *param = stmt->param_array[param_number];
2168 param->set_longdata((char *)str, length);
2169 if (thd->get_stmt_da()->is_error()) {
2170 stmt->m_arena.set_state(Query_arena::STMT_ERROR);
2171 stmt->last_errno = thd->get_stmt_da()->mysql_errno();
2172 snprintf(stmt->last_error, sizeof(stmt->last_error), "%.*s",
2173 MYSQL_ERRMSG_SIZE - 1, thd->get_stmt_da()->message_text());
2174 }
2175 thd->pop_diagnostics_area();
2176
2177 query_logger.general_log_print(thd, thd->get_command(), NullS);
2178 }
2179
2180 /***************************************************************************
2181 Query_fetch_protocol_binary
2182 ****************************************************************************/
2183
2184 namespace {
2185
send_result_set_metadata(THD * thd,List<Item> & list,uint flags)2186 bool Query_fetch_protocol_binary::send_result_set_metadata(THD *thd,
2187 List<Item> &list,
2188 uint flags) {
2189 bool rc;
2190
2191 protocol.set_client_capabilities(
2192 thd->get_protocol()->get_client_capabilities());
2193 /*
2194 Protocol::send_result_set_metadata caches the information about column
2195 types: this information is later used to send data. Therefore, the same
2196 dedicated Protocol object must be used for all operations with
2197 a cursor.
2198 */
2199 thd->push_protocol(&protocol);
2200 rc = Query_result_send::send_result_set_metadata(thd, list, flags);
2201 thd->pop_protocol();
2202
2203 return rc;
2204 }
2205
send_eof(THD * thd)2206 bool Query_fetch_protocol_binary::send_eof(THD *thd) {
2207 /*
2208 Don't send EOF if we're in error condition (which implies we've already
2209 sent or are sending an error)
2210 */
2211 if (thd->is_error()) return true;
2212
2213 ::my_eof(thd);
2214 return false;
2215 }
2216
send_data(THD * thd,List<Item> & fields)2217 bool Query_fetch_protocol_binary::send_data(THD *thd, List<Item> &fields) {
2218 bool rc;
2219
2220 // set the current client capabilities before switching the protocol
2221 protocol.set_client_capabilities(
2222 thd->get_protocol()->get_client_capabilities());
2223 thd->push_protocol(&protocol);
2224 rc = Query_result_send::send_data(thd, fields);
2225 thd->pop_protocol();
2226 return rc;
2227 }
2228
2229 } // namespace
2230
2231 /*******************************************************************
2232 * Reprepare_observer
2233 *******************************************************************/
2234 /** Push an error to the error stack and return true for now. */
2235
report_error(THD * thd)2236 bool Reprepare_observer::report_error(THD *thd) {
2237 /*
2238 This 'error' is purely internal to the server:
2239 - No exception handler is invoked,
2240 - No condition is added in the condition area (warn_list).
2241 The Diagnostics Area is set to an error status to enforce
2242 that this thread execution stops and returns to the caller,
2243 backtracking all the way to Prepared_statement::execute_loop().
2244
2245 As the DA has not yet been reset at this point, we'll need to
2246 reset the previous statement's result status first.
2247 Test with rpl_sp_effects and friends.
2248 */
2249 thd->get_stmt_da()->reset_diagnostics_area();
2250 thd->get_stmt_da()->set_error_status(thd, ER_NEED_REPREPARE);
2251 m_invalidated = true;
2252
2253 return true;
2254 }
2255
2256 /*******************************************************************
2257 * Server_runnable
2258 *******************************************************************/
2259
~Server_runnable()2260 Server_runnable::~Server_runnable() {}
2261
2262 ///////////////////////////////////////////////////////////////////////////
2263
2264 namespace {
2265
Execute_sql_statement(LEX_STRING sql_text)2266 Execute_sql_statement::Execute_sql_statement(LEX_STRING sql_text)
2267 : m_sql_text(sql_text) {}
2268
2269 /**
2270 Parse and execute a statement. Does not prepare the query.
2271
2272 Allows to execute a statement from within another statement.
2273 The main property of the implementation is that it does not
2274 affect the environment -- i.e. you can run many
2275 executions without having to cleanup/reset THD in between.
2276 */
2277
execute_server_code(THD * thd)2278 bool Execute_sql_statement::execute_server_code(THD *thd) {
2279 sql_digest_state *parent_digest;
2280 PSI_statement_locker *parent_locker;
2281 bool error;
2282
2283 if (alloc_query(thd, m_sql_text.str, m_sql_text.length)) return true;
2284
2285 Parser_state parser_state;
2286 if (parser_state.init(thd, thd->query().str, thd->query().length))
2287 return true;
2288
2289 parser_state.m_lip.multi_statements = false;
2290 lex_start(thd);
2291
2292 parent_digest = thd->m_digest;
2293 parent_locker = thd->m_statement_psi;
2294 thd->m_digest = nullptr;
2295 thd->m_statement_psi = nullptr;
2296 error = parse_sql(thd, &parser_state, nullptr) || thd->is_error();
2297 thd->m_digest = parent_digest;
2298 thd->m_statement_psi = parent_locker;
2299
2300 if (error) goto end;
2301
2302 thd->lex->set_trg_event_type_for_tables();
2303
2304 parent_locker = thd->m_statement_psi;
2305 thd->m_statement_psi = nullptr;
2306
2307 /*
2308 Rewrite first (if needed); execution might replace passwords
2309 with hashes in situ without flagging it, and then we'd make
2310 a hash of that hash.
2311 */
2312 rewrite_query_if_needed(thd);
2313 log_execute_line(thd);
2314
2315 error = mysql_execute_command(thd);
2316 thd->m_statement_psi = parent_locker;
2317
2318 end:
2319 lex_end(thd->lex);
2320
2321 return error;
2322 }
2323
2324 } // namespace
2325
2326 /***************************************************************************
2327 Prepared_statement
2328 ****************************************************************************/
2329
Prepared_statement(THD * thd_arg)2330 Prepared_statement::Prepared_statement(THD *thd_arg)
2331 : m_arena(&main_mem_root, Query_arena::STMT_INITIALIZED),
2332 thd(thd_arg),
2333 param_array(nullptr),
2334 cursor(nullptr),
2335 param_count(0),
2336 last_errno(0),
2337 id(++thd_arg->statement_id_counter),
2338 lex(nullptr),
2339 m_query_string(NULL_CSTR),
2340 m_prepared_stmt(nullptr),
2341 result(nullptr),
2342 flags((uint)IS_IN_USE),
2343 with_log(false),
2344 m_name(NULL_CSTR),
2345 m_db(NULL_CSTR) {
2346 init_sql_alloc(key_memory_prepared_statement_main_mem_root, &main_mem_root,
2347 thd_arg->variables.query_alloc_block_size,
2348 thd_arg->variables.query_prealloc_size);
2349 *last_error = '\0';
2350 }
2351
close_cursor()2352 void Prepared_statement::close_cursor() {
2353 destroy(result);
2354 result = nullptr;
2355 delete cursor;
2356 cursor = nullptr;
2357 }
2358
setup_set_params()2359 void Prepared_statement::setup_set_params() {
2360 DBUG_EXECUTE_IF("bug16617026_simulate_audit_log_ps",
2361 { lex->safe_to_cache_query = 0; });
2362 /*
2363 Decide if we have to expand the query (because we must write it to logs)
2364 or not.
2365 We don't have to substitute the params when bin-logging DML in RBL.
2366 */
2367 if ((mysql_bin_log.is_open() && is_update_query(lex->sql_command) &&
2368 (!thd->is_current_stmt_binlog_format_row() ||
2369 ((sql_command_flags[lex->sql_command] & CF_AUTO_COMMIT_TRANS) ==
2370 CF_AUTO_COMMIT_TRANS))) ||
2371 opt_general_log || opt_slow_log ||
2372 (lex->sql_command == SQLCOM_SELECT && lex->safe_to_cache_query &&
2373 !lex->is_explain()) ||
2374 is_global_audit_mask_set()) {
2375 with_log = true;
2376 }
2377 }
2378
2379 /**
2380 Destroy this prepared statement, cleaning up all used memory
2381 and resources.
2382
2383 This is called from @c deallocate() to handle COM_STMT_CLOSE and
2384 DEALLOCATE PREPARE or when THD ends and all prepared statements are freed.
2385 */
2386
~Prepared_statement()2387 Prepared_statement::~Prepared_statement() {
2388 DBUG_TRACE;
2389 DBUG_PRINT("enter", ("stmt: %p cursor: %p", this, cursor));
2390 destroy(result);
2391 delete cursor;
2392 /*
2393 We have to call free on the items even if cleanup is called as some items,
2394 like Item_param, don't free everything until free_items()
2395 */
2396 m_arena.free_items();
2397 if (lex) {
2398 DBUG_ASSERT(lex->sphead == nullptr);
2399 lex_end(lex);
2400 destroy(lex->result);
2401 delete (st_lex_local *)lex; // TRASH memory
2402 }
2403 free_root(&main_mem_root, MYF(0));
2404 }
2405
cleanup_stmt()2406 void Prepared_statement::cleanup_stmt() {
2407 DBUG_TRACE;
2408 DBUG_PRINT("enter", ("stmt: %p", this));
2409
2410 cleanup_items(m_arena.item_list());
2411 thd->cleanup_after_query();
2412 thd->rollback_item_tree_changes();
2413 }
2414
set_name(const LEX_CSTRING & name_arg)2415 bool Prepared_statement::set_name(const LEX_CSTRING &name_arg) {
2416 m_name.length = name_arg.length;
2417 m_name.str = static_cast<char *>(
2418 memdup_root(m_arena.mem_root, name_arg.str, name_arg.length));
2419 return m_name.str == nullptr;
2420 }
2421
2422 /**
2423 Remember the current database.
2424
2425 We must reset/restore the current database during execution of
2426 a prepared statement since it affects execution environment:
2427 privileges, @@character_set_database, and other.
2428
2429 @return Returns an error if out of memory.
2430 */
2431
set_db(const LEX_CSTRING & db_arg)2432 bool Prepared_statement::set_db(const LEX_CSTRING &db_arg) {
2433 /* Remember the current database. */
2434 if (db_arg.str && db_arg.length) {
2435 m_db.str = m_arena.strmake(db_arg.str, db_arg.length);
2436 m_db.length = db_arg.length;
2437 } else {
2438 m_db = NULL_CSTR;
2439 }
2440 return db_arg.str != nullptr && m_db.str == nullptr;
2441 }
2442
2443 /**************************************************************************
2444 Common parts of mysql_[sql]_stmt_prepare, mysql_[sql]_stmt_execute.
2445 Essentially, these functions do all the magic of preparing/executing
2446 a statement, leaving network communication, input data handling and
2447 global THD state management to the caller.
2448 ***************************************************************************/
2449
2450 /**
2451 Parse statement text, validate the statement, and prepare it for execution.
2452
2453 You should not change global THD state in this function, if at all
2454 possible: it may be called from any context, e.g. when executing
2455 a COM_* command, and SQLCOM_* command, or a stored procedure.
2456
2457 @param query_str statement text
2458 @param query_length the length of the statement text
2459
2460 @note
2461 Precondition:
2462 The caller must ensure that thd->change_list and thd->item_list
2463 is empty: this function will not back them up but will free
2464 in the end of its execution.
2465
2466 @note
2467 Postcondition:
2468 thd->mem_root contains unused memory allocated during validation.
2469 */
2470
prepare(const char * query_str,size_t query_length)2471 bool Prepared_statement::prepare(const char *query_str, size_t query_length) {
2472 bool error;
2473 Query_arena arena_backup;
2474 Query_arena *old_stmt_arena;
2475 sql_digest_state *parent_digest = thd->m_digest;
2476 PSI_statement_locker *parent_locker = thd->m_statement_psi;
2477 unsigned char *token_array = nullptr;
2478
2479 DBUG_TRACE;
2480 /*
2481 If this is an SQLCOM_PREPARE, we also increase Com_prepare_sql.
2482 However, it seems handy if com_stmt_prepare is increased always,
2483 no matter what kind of prepare is processed.
2484 */
2485 thd->status_var.com_stmt_prepare++;
2486
2487 if (!(lex = new (m_arena.mem_root) st_lex_local)) return true;
2488
2489 if (set_db(thd->db())) return true;
2490
2491 /*
2492 alloc_query() uses thd->memroot && thd->query, so we should call
2493 both of backup_statement() and backup_query_arena() here.
2494 */
2495 Statement_backup stmt_backup;
2496 stmt_backup.set_thd_to_ps(thd, this);
2497 stmt_backup.save_rlb(thd);
2498 thd->swap_query_arena(m_arena, &arena_backup);
2499
2500 if (alloc_query(thd, query_str, query_length)) {
2501 stmt_backup.restore_thd(thd, this);
2502 stmt_backup.restore_rlb(thd);
2503 thd->swap_query_arena(arena_backup, &m_arena);
2504 return true;
2505 }
2506
2507 if (max_digest_length > 0) {
2508 token_array = (unsigned char *)thd->alloc(max_digest_length);
2509 }
2510
2511 old_stmt_arena = thd->stmt_arena;
2512 thd->stmt_arena = &m_arena;
2513
2514 Parser_state parser_state;
2515 if (parser_state.init(thd, thd->query().str, thd->query().length)) {
2516 stmt_backup.restore_thd(thd, this);
2517 stmt_backup.restore_rlb(thd);
2518 thd->swap_query_arena(arena_backup, &m_arena);
2519 thd->stmt_arena = old_stmt_arena;
2520 return true;
2521 }
2522
2523 parser_state.m_lip.stmt_prepare_mode = true;
2524 parser_state.m_lip.multi_statements = false;
2525
2526 lex_start(thd);
2527 lex->context_analysis_only |= CONTEXT_ANALYSIS_ONLY_PREPARE;
2528
2529 thd->m_digest = nullptr;
2530 thd->m_statement_psi = nullptr;
2531
2532 sql_digest_state digest;
2533 digest.reset(token_array, max_digest_length);
2534 thd->m_digest = &digest;
2535
2536 enable_digest_if_any_plugin_needs_it(thd, &parser_state);
2537 if (is_audit_plugin_class_active(thd, MYSQL_AUDIT_GENERAL_CLASS))
2538 parser_state.m_input.m_compute_digest = true;
2539
2540 thd->m_parser_state = &parser_state;
2541 invoke_pre_parse_rewrite_plugins(thd);
2542 thd->m_parser_state = nullptr;
2543
2544 error = thd->is_error();
2545
2546 if (!error) {
2547 error = parse_sql(thd, &parser_state, nullptr) || thd->is_error() ||
2548 init_param_array(this);
2549 }
2550 if (!error) { // We've just created the statement maybe there is a rewrite
2551 invoke_post_parse_rewrite_plugins(thd, true);
2552 error = init_param_array(this);
2553 }
2554
2555 // Bind Sql command object with this prepared statement
2556 if (lex->m_sql_cmd) lex->m_sql_cmd->set_owner(this);
2557
2558 lex->set_trg_event_type_for_tables();
2559
2560 /*
2561 Pre-clear the diagnostics area unless a warning was thrown
2562 during parsing.
2563 */
2564 if (thd->lex->keep_diagnostics != DA_KEEP_PARSE_ERROR)
2565 thd->get_stmt_da()->reset_condition_info(thd);
2566
2567 /*
2568 While doing context analysis of the query (in check_prepared_statement)
2569 we allocate a lot of additional memory: for open tables, JOINs, derived
2570 tables, etc. Let's save a snapshot of current parse tree to the
2571 statement and restore original THD. In cases when some tree
2572 transformation can be reused on execute, we set again thd->mem_root from
2573 stmt->mem_root (see setup_wild for one place where we do that).
2574 */
2575 thd->swap_query_arena(arena_backup, &m_arena);
2576
2577 /*
2578 If called from a stored procedure, ensure that we won't rollback
2579 external changes when cleaning up after validation.
2580 */
2581 DBUG_ASSERT(thd->change_list.is_empty());
2582
2583 /*
2584 Marker used to release metadata locks acquired while the prepared
2585 statement is being checked.
2586 */
2587 MDL_savepoint mdl_savepoint = thd->mdl_context.mdl_savepoint();
2588
2589 // A subsystem, such as the Audit plugin, may have set error unnoticed:
2590 error |= thd->is_error();
2591
2592 /*
2593 The only case where we should have items in the thd->item_list is
2594 after stmt->set_params_from_vars(), which may in some cases create
2595 Item_null objects.
2596 */
2597
2598 if (error == 0) error = check_prepared_statement(this);
2599 DBUG_ASSERT(error || !thd->is_error());
2600
2601 /*
2602 Currently CREATE PROCEDURE/TRIGGER/EVENT are prohibited in prepared
2603 statements: ensure we have no memory leak here if by someone tries
2604 to PREPARE stmt FROM "CREATE PROCEDURE ..."
2605 */
2606 DBUG_ASSERT(lex->sphead == nullptr || error != 0);
2607 /* The order is important */
2608 lex->unit->cleanup(thd, true);
2609
2610 lex->clear_values_map();
2611
2612 close_thread_tables(thd);
2613 thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
2614
2615 /*
2616 Transaction rollback was requested since MDL deadlock was discovered
2617 while trying to open tables. Rollback transaction in all storage
2618 engines including binary log and release all locks.
2619
2620 Once dynamic SQL is allowed as substatements the below if-statement
2621 has to be adjusted to not do rollback in substatement.
2622 */
2623 DBUG_ASSERT(!thd->in_sub_stmt);
2624 if (thd->transaction_rollback_request) {
2625 trans_rollback_implicit(thd);
2626 thd->mdl_context.release_transactional_locks();
2627 }
2628
2629 lex_end(lex);
2630
2631 rewrite_query_if_needed(thd);
2632
2633 if (thd->rewritten_query().length()) {
2634 thd->set_query_for_display(thd->rewritten_query().ptr(),
2635 thd->rewritten_query().length());
2636 MYSQL_SET_PS_TEXT(m_prepared_stmt, thd->rewritten_query().ptr(),
2637 thd->rewritten_query().length());
2638 } else {
2639 thd->set_query_for_display(thd->query().str, thd->query().length);
2640 MYSQL_SET_PS_TEXT(m_prepared_stmt, thd->query().str, thd->query().length);
2641 }
2642
2643 cleanup_stmt();
2644 stmt_backup.restore_thd(thd, this);
2645 thd->stmt_arena = old_stmt_arena;
2646
2647 if (error == 0) {
2648 setup_set_params();
2649 lex->context_analysis_only &= ~CONTEXT_ANALYSIS_ONLY_PREPARE;
2650 m_arena.set_state(Query_arena::STMT_PREPARED);
2651 flags &= ~(uint)IS_IN_USE;
2652
2653 /*
2654 Log COM_STMT_PREPARE to the general log. Note, that in case of SQL
2655 prepared statements this causes two records to be output:
2656
2657 Query PREPARE stmt from @user_variable
2658 Prepare <statement SQL text>
2659
2660 This is considered user-friendly, since in the second log Entry
2661 we output the actual statement text rather than the variable name.
2662
2663 Rewriting/password obfuscation:
2664
2665 - If we're preparing from a string literal rather than from a
2666 variable, the literal is elided in the "Query" log line, as
2667 it may contain a password. (As we've parsed the PREPARE statement,
2668 but not the statement to prepare yet, we don't know at that point.)
2669 Eliding the literal is fine, as we'll print it in the next log line
2670 ("Prepare"), anyway.
2671
2672 - Any passwords in the "Prepare" line should be substituted with their
2673 hashes, or a notice.
2674
2675 Do not print anything if this is an SQL prepared statement and
2676 we're inside a stored procedure (also called Dynamic SQL) --
2677 sub-statements inside stored procedures are not logged into
2678 the general log.
2679 */
2680 if (thd->sp_runtime_ctx == nullptr) {
2681 if (thd->rewritten_query().length())
2682 query_logger.general_log_write(thd, COM_STMT_PREPARE,
2683 thd->rewritten_query().ptr(),
2684 thd->rewritten_query().length());
2685 else
2686 query_logger.general_log_write(
2687 thd, COM_STMT_PREPARE, m_query_string.str, m_query_string.length);
2688
2689 /* audit plugins can return an error */
2690 error |= thd->is_error();
2691 }
2692 }
2693
2694 /* Restore the original rewritten query. */
2695 stmt_backup.restore_rlb(thd);
2696
2697 thd->m_digest = parent_digest;
2698 thd->m_statement_psi = parent_locker;
2699
2700 return error;
2701 }
2702
2703 /**
2704 Assign parameter values either from variables, in case of SQL PS
2705 or from the execute packet.
2706
2707 @param expanded_query a container with the original SQL statement.
2708 '?' placeholders will be replaced with
2709 their values in case of success.
2710 The result is used for logging and replication
2711 @param has_new_types flag used to signal that new types are provided.
2712 @param parameters prepared statement's parsed parameters.
2713
2714 @todo Use a paremeter source class family instead of 'if's, and
2715 support stored procedure variables.
2716
2717 @return bool representing the function execution status.
2718 @retval true an error occurred when assigning a parameter (likely
2719 a conversion error or out of memory, or malformed packet)
2720 @retval false success
2721 */
2722
set_parameters(String * expanded_query,bool has_new_types,PS_PARAM * parameters)2723 bool Prepared_statement::set_parameters(String *expanded_query,
2724 bool has_new_types,
2725 PS_PARAM *parameters) {
2726 if (!param_count) return false;
2727 /*
2728 Setup conversion functions if new types are provided
2729 and insert parameters (types supplied / first execute)
2730 */
2731 if ((has_new_types && setup_conversion_functions(this, parameters)) ||
2732 insert_params(expanded_query, parameters)) {
2733 my_error(ER_WRONG_ARGUMENTS, MYF(0), "mysqld_stmt_execute");
2734 reset_stmt_params(this);
2735 return true;
2736 }
2737 return false;
2738 }
2739
set_parameters(String * expanded_query)2740 bool Prepared_statement::set_parameters(String *expanded_query) {
2741 /* SQL prepared statement */
2742 if (insert_params_from_vars(thd->lex->prepared_stmt_params, expanded_query)) {
2743 my_error(ER_WRONG_ARGUMENTS, MYF(0), "EXECUTE");
2744 reset_stmt_params(this);
2745 return true;
2746 }
2747 return false;
2748 }
2749
2750 /**
2751 Disables the general log for the current session by setting the OPTION_LOG_OFF
2752 bit in thd->variables.option_bits.
2753
2754 @param thd the session
2755 @return whether the setting was changed
2756 @retval false if the general log was already disabled for this session
2757 @retval true if the general log was enabled for the session and is now
2758 disabled
2759 */
disable_general_log(THD * thd)2760 static bool disable_general_log(THD *thd) {
2761 if ((thd->variables.option_bits & OPTION_LOG_OFF) != 0) return false;
2762 thd->variables.option_bits |= OPTION_LOG_OFF;
2763 return true;
2764 }
2765
2766 /**
2767 Execute a prepared statement. Re-prepare it a limited number
2768 of times if necessary.
2769
2770 Try to execute a prepared statement. If there is a metadata
2771 validation error, prepare a new copy of the prepared statement,
2772 swap the old and the new statements, and try again.
2773 If there is a validation error again, repeat the above, but
2774 perform no more than MAX_REPREPARE_ATTEMPTS.
2775
2776 @note We have to try several times in a loop since we
2777 release metadata locks on tables after prepared statement
2778 prepare. Therefore, a DDL statement may sneak in between prepare
2779 and execute of a new statement. If this happens repeatedly
2780 more than MAX_REPREPARE_ATTEMPTS times, we give up.
2781
2782 @param expanded_query Query string.
2783 @param open_cursor Flag to specift if a cursor should be used.
2784
2785 @return a bool value representing the function execution status.
2786 @retval true error: either MAX_REPREPARE_ATTEMPTS has been reached,
2787 or some general error
2788 @retval false successfully executed the statement, perhaps
2789 after having reprepared it a few times.
2790 */
2791
execute_loop(String * expanded_query,bool open_cursor)2792 bool Prepared_statement::execute_loop(String *expanded_query,
2793 bool open_cursor) {
2794 const int MAX_REPREPARE_ATTEMPTS = 3;
2795 Reprepare_observer reprepare_observer;
2796 bool error;
2797 int reprepare_attempt = 0;
2798
2799 /* Check if we got an error when sending long data */
2800 if (m_arena.get_state() == Query_arena::STMT_ERROR) {
2801 my_message(last_errno, last_error, MYF(0));
2802 return true;
2803 }
2804
2805 DBUG_ASSERT(!thd->get_stmt_da()->is_set());
2806
2807 if (unlikely(!thd->security_context()->account_is_locked() &&
2808 thd->security_context()->password_expired() &&
2809 lex->sql_command != SQLCOM_SET_PASSWORD &&
2810 lex->sql_command != SQLCOM_ALTER_USER)) {
2811 my_error(ER_MUST_CHANGE_PASSWORD, MYF(0));
2812 return true;
2813 }
2814
2815 // Remember if the general log was temporarily disabled when repreparing the
2816 // statement for a secondary engine.
2817 bool general_log_temporarily_disabled = false;
2818
2819 reexecute:
2820 /*
2821 If the item_list is not empty, we'll wrongly free some externally
2822 allocated items when cleaning up after validation of the prepared
2823 statement.
2824 */
2825 DBUG_ASSERT(thd->item_list() == nullptr);
2826
2827 /*
2828 Install the metadata observer. If some metadata version is
2829 different from prepare time and an observer is installed,
2830 the observer method will be invoked to push an error into
2831 the error stack.
2832 */
2833 Reprepare_observer *stmt_reprepare_observer = nullptr;
2834
2835 if (sql_command_flags[lex->sql_command] & CF_REEXECUTION_FRAGILE) {
2836 reprepare_observer.reset_reprepare_observer();
2837 stmt_reprepare_observer = &reprepare_observer;
2838 }
2839
2840 thd->push_reprepare_observer(stmt_reprepare_observer);
2841
2842 error = execute(expanded_query, open_cursor) || thd->is_error();
2843
2844 thd->pop_reprepare_observer();
2845
2846 // Check if we have a non-fatal error and the statement allows reexecution.
2847 if ((sql_command_flags[lex->sql_command] & CF_REEXECUTION_FRAGILE) && error &&
2848 !thd->is_fatal_error() && !thd->is_killed()) {
2849 // If we have an error due to a metadata change, reprepare the
2850 // statement and execute it again.
2851 if (reprepare_observer.is_invalidated()) {
2852 DBUG_ASSERT(thd->get_stmt_da()->mysql_errno() == ER_NEED_REPREPARE);
2853
2854 if ((reprepare_attempt++ < MAX_REPREPARE_ATTEMPTS) &&
2855 DBUG_EVALUATE_IF("simulate_max_reprepare_attempts_hit_case", false,
2856 true)) {
2857 thd->clear_error();
2858 error = reprepare();
2859 DEBUG_SYNC(thd, "after_statement_reprepare");
2860 } else {
2861 /*
2862 Reprepare_observer sets error status in DA but Sql_condition is not
2863 added. Please check Reprepare_observer::report_error(). Pushing
2864 Sql_condition for ER_NEED_REPREPARE here.
2865 */
2866 Diagnostics_area *da = thd->get_stmt_da();
2867 da->push_warning(thd, da->mysql_errno(), da->returned_sqlstate(),
2868 Sql_condition::SL_ERROR, da->message_text());
2869 }
2870 } else {
2871 // Otherwise, if repreparation was requested, try again in the primary
2872 // or secondary engine, depending on cause.
2873 const uint err_seen = thd->get_stmt_da()->mysql_errno();
2874 if (err_seen == ER_PREPARE_FOR_SECONDARY_ENGINE ||
2875 (err_seen == ER_NEED_REPREPARE &&
2876 reprepare_attempt++ < MAX_REPREPARE_ATTEMPTS)) {
2877 DBUG_ASSERT((thd->secondary_engine_optimization() ==
2878 Secondary_engine_optimization::PRIMARY_TENTATIVELY) ||
2879 err_seen == ER_NEED_REPREPARE);
2880 DBUG_ASSERT(!lex->unit->is_executed());
2881 thd->clear_error();
2882 if (err_seen == ER_PREPARE_FOR_SECONDARY_ENGINE)
2883 thd->set_secondary_engine_optimization(
2884 Secondary_engine_optimization::SECONDARY);
2885 else
2886 thd->set_secondary_engine_optimization(
2887 Secondary_engine_optimization::PRIMARY_ONLY);
2888 // Disable the general log. The query was written to the general log in
2889 // the first attempt to execute it. No need to write it twice.
2890 general_log_temporarily_disabled |= disable_general_log(thd);
2891 error = reprepare();
2892 }
2893
2894 // If (re-?)preparation or optimization failed and it was for
2895 // a secondary storage engine, disable the secondary storage
2896 // engine and try again without it.
2897 if (error && lex->m_sql_cmd != nullptr &&
2898 thd->secondary_engine_optimization() ==
2899 Secondary_engine_optimization::SECONDARY &&
2900 !lex->unit->is_executed()) {
2901 thd->clear_error();
2902 thd->set_secondary_engine_optimization(
2903 Secondary_engine_optimization::PRIMARY_ONLY);
2904 error = reprepare();
2905 if (!error) {
2906 // The reprepared statement should not use a secondary engine.
2907 DBUG_ASSERT(!lex->m_sql_cmd->using_secondary_storage_engine());
2908 lex->m_sql_cmd->disable_secondary_storage_engine();
2909 }
2910 }
2911 }
2912
2913 if (!error) /* Success */
2914 goto reexecute;
2915 }
2916 reset_stmt_params(this);
2917
2918 // Reenable the general log if it was temporarily disabled while repreparing
2919 // and executing a statement for a secondary engine.
2920 if (general_log_temporarily_disabled)
2921 thd->variables.option_bits &= ~OPTION_LOG_OFF;
2922
2923 return error;
2924 }
2925
execute_server_runnable(Server_runnable * server_runnable)2926 bool Prepared_statement::execute_server_runnable(
2927 Server_runnable *server_runnable) {
2928 Query_arena arena_backup;
2929 bool error;
2930 Query_arena *save_stmt_arena = thd->stmt_arena;
2931 Item_change_list save_change_list;
2932 thd->change_list.move_elements_to(&save_change_list);
2933
2934 m_arena.set_state(Query_arena::STMT_REGULAR_EXECUTION);
2935
2936 if (!(lex = new (m_arena.mem_root) st_lex_local)) return true;
2937
2938 Statement_backup stmt_backup;
2939 stmt_backup.set_thd_to_ps(thd, this);
2940 stmt_backup.save_rlb(thd);
2941 thd->swap_query_arena(m_arena, &arena_backup);
2942 thd->stmt_arena = &m_arena;
2943
2944 error = server_runnable->execute_server_code(thd);
2945
2946 thd->cleanup_after_query();
2947
2948 thd->swap_query_arena(arena_backup, &m_arena);
2949 stmt_backup.restore_thd(thd, this);
2950 stmt_backup.restore_rlb(thd);
2951 thd->stmt_arena = save_stmt_arena;
2952
2953 save_change_list.move_elements_to(&thd->change_list);
2954
2955 /* Items and memory will freed in destructor */
2956
2957 return error;
2958 }
2959
2960 /**
2961 Reprepare this prepared statement.
2962
2963 Performs a light reset of the Prepared_statement object (resets its MEM_ROOT
2964 and clears its MEM_ROOT allocated members), and calls prepare() on it again.
2965
2966 The resetting of the MEM_ROOT and clearing of the MEM_ROOT allocated members
2967 is performed by a swap operation (swap_prepared_statement()) on this
2968 Prepared_statement and a newly created, intermediate Prepared_statement. This
2969 both clears the data from this object and stores a backup of the original data
2970 in the intermediate object. If the repreparation fails, the original data is
2971 swapped back into this Prepared_statement.
2972
2973 @retval true an error occurred. Possible errors include
2974 incompatibility of new and old result set
2975 metadata
2976 @retval false success, the statement has been reprepared
2977 */
2978
reprepare()2979 bool Prepared_statement::reprepare() {
2980 char saved_cur_db_name_buf[NAME_LEN + 1];
2981 LEX_STRING saved_cur_db_name = {saved_cur_db_name_buf,
2982 sizeof(saved_cur_db_name_buf)};
2983
2984 /*
2985 Create an intermediate Prepared_statement object and move the MEM_ROOT
2986 allocated data of the original Prepared_statement into it. Set up a guard
2987 that moves the data back into the original statement if the repreparation
2988 fails.
2989 */
2990 Prepared_statement copy(thd);
2991 swap_prepared_statement(©);
2992 auto copy_guard =
2993 create_scope_guard([&]() { swap_prepared_statement(©); });
2994
2995 thd->status_var.com_stmt_reprepare++;
2996
2997 /*
2998 m_name has been moved to the copy. Allocate it again in the original
2999 statement.
3000 */
3001 if (copy.m_name.str != nullptr && set_name(copy.m_name)) return true;
3002
3003 bool cur_db_changed;
3004 if (mysql_opt_change_db(thd, copy.m_db, &saved_cur_db_name, true,
3005 &cur_db_changed))
3006 return true;
3007
3008 /*
3009 Suppress sending metadata to the client while repreparing. It was sent
3010 during the initial preparation.
3011 */
3012 const unsigned saved_flags = flags;
3013 set_sql_prepare();
3014 const bool prepare_error =
3015 prepare(copy.m_query_string.str, copy.m_query_string.length);
3016 flags = saved_flags;
3017
3018 if (cur_db_changed)
3019 mysql_change_db(thd, to_lex_cstring(saved_cur_db_name), true);
3020
3021 if (prepare_error) return true;
3022
3023 if (validate_metadata(©)) return true;
3024
3025 /* Update reprepare count for this prepared statement in P_S table. */
3026 MYSQL_REPREPARE_PS(m_prepared_stmt);
3027
3028 /*
3029 A new parameter array was created by prepare(). Make sure it contains the
3030 same values as the original array.
3031 */
3032 DBUG_ASSERT(param_count == copy.param_count);
3033 swap_parameter_array(param_array, copy.param_array, param_count);
3034
3035 /*
3036 Clear possible warnings during reprepare, it has to be completely
3037 transparent to the user. We use reset_condition_info() since
3038 there were no separate query id issued for re-prepare.
3039 Sic: we can't simply silence warnings during reprepare, because if
3040 it's failed, we need to return all the warnings to the user.
3041 */
3042 thd->get_stmt_da()->reset_condition_info(thd);
3043
3044 copy_guard.commit();
3045 return false;
3046 }
3047
3048 /**
3049 Validate statement result set metadata (if the statement returns
3050 a result set).
3051
3052 Currently we only check that the number of columns of the result
3053 set did not change.
3054 This is a helper method used during re-prepare.
3055
3056 @param[in] copy the re-prepared prepared statement to verify
3057 the metadata of
3058
3059 @retval true error, ER_PS_REBIND is reported
3060 @retval false statement return no or compatible metadata
3061 */
3062
validate_metadata(Prepared_statement * copy)3063 bool Prepared_statement::validate_metadata(Prepared_statement *copy) {
3064 /**
3065 If this is an SQL prepared statement or EXPLAIN,
3066 return false -- the metadata of the original SELECT,
3067 if any, has not been sent to the client.
3068 */
3069 if (is_sql_prepare() || lex->is_explain()) return false;
3070
3071 if (lex->select_lex->fields_list.elements !=
3072 copy->lex->select_lex->fields_list.elements) {
3073 /** Column counts mismatch, update the client */
3074 thd->server_status |= SERVER_STATUS_METADATA_CHANGED;
3075 }
3076
3077 return false;
3078 }
3079
3080 /**
3081 Swap the MEM_ROOT allocated data of two prepared statements.
3082
3083 This is a private helper that is used as part of statement reprepare. It is
3084 used in the beginning of reprepare() to clear the MEM_ROOT of the statement
3085 before the new preparation, while keeping the data available as some of it is
3086 needed later in the repreparation. It is also used for restoring the original
3087 data from the copy, should the repreparation fail.
3088
3089 The operation is symmetric. It can be used both for saving an original
3090 statement into a backup, and for restoring the original state of the statement
3091 from the backup.
3092 */
3093
swap_prepared_statement(Prepared_statement * copy)3094 void Prepared_statement::swap_prepared_statement(Prepared_statement *copy) {
3095 Query_arena tmp_arena;
3096
3097 /* Swap memory roots. */
3098 std::swap(main_mem_root, copy->main_mem_root);
3099
3100 /* Swap the arenas */
3101 m_arena.swap_query_arena(copy->m_arena, &tmp_arena);
3102 copy->m_arena.set_query_arena(tmp_arena);
3103
3104 /* Swap the statement attributes */
3105 std::swap(lex, copy->lex);
3106 std::swap(m_query_string, copy->m_query_string);
3107
3108 /* Swap mem_roots back, they must continue pointing at the main_mem_roots */
3109 std::swap(m_arena.mem_root, copy->m_arena.mem_root);
3110 /*
3111 Swap the old and the new parameters array. The old array
3112 is allocated in the old arena.
3113 */
3114 std::swap(param_array, copy->param_array);
3115 std::swap(param_count, copy->param_count);
3116
3117 /* Don't swap flags: the copy has IS_SQL_PREPARE always set. */
3118 /* std::swap(flags, copy->flags); */
3119 /* Swap names, the old name is allocated in the wrong memory root */
3120 std::swap(m_name, copy->m_name);
3121 /* Ditto */
3122 std::swap(m_db, copy->m_db);
3123
3124 DBUG_ASSERT(thd == copy->thd);
3125 }
3126
3127 /**
3128 Execute a prepared statement.
3129
3130 You should not change global THD state in this function, if at all
3131 possible: it may be called from any context, e.g. when executing
3132 a COM_* command, and SQLCOM_* command, or a stored procedure.
3133
3134 @param expanded_query A query for binlogging which has all parameter
3135 markers ('?') replaced with their actual values.
3136 @param open_cursor True if an attempt to open a cursor should be made.
3137 Currenlty used only in the binary protocol.
3138
3139 @note
3140 Preconditions, postconditions.
3141 - See the comment for Prepared_statement::prepare().
3142
3143 @retval
3144 false ok
3145 @retval
3146 true Error
3147 */
3148
execute(String * expanded_query,bool open_cursor)3149 bool Prepared_statement::execute(String *expanded_query, bool open_cursor) {
3150 Query_arena *old_stmt_arena;
3151 char saved_cur_db_name_buf[NAME_LEN + 1];
3152 LEX_STRING saved_cur_db_name = {saved_cur_db_name_buf,
3153 sizeof(saved_cur_db_name_buf)};
3154 bool cur_db_changed;
3155
3156 thd->status_var.com_stmt_execute++;
3157
3158 /*
3159 Reset the diagnostics area.
3160
3161 For regular statements, this would have happened in the parsing
3162 stage.
3163
3164 SQL prepared statements (SQLCOM_EXECUTE) also have a parsing
3165 stage first (where we find out it's EXECUTE ... [USING ...]).
3166
3167 However, ps-protocol prepared statements have no parsing stage for
3168 COM_STMT_EXECUTE before coming here, so we reset the condition info
3169 here. Since diagnostics statements can't be prepared, we don't need
3170 to make an exception for them.
3171 */
3172 thd->get_stmt_da()->reset_condition_info(thd);
3173
3174 if (flags & (uint)IS_IN_USE) {
3175 my_error(ER_PS_NO_RECURSION, MYF(0));
3176 return true;
3177 }
3178
3179 /*
3180 For SHOW VARIABLES lex->result is NULL, as it's a non-SELECT
3181 command. For such queries we don't return an error and don't
3182 open a cursor -- the client library will recognize this case and
3183 materialize the result set.
3184 For SELECT statements lex->result is created in
3185 check_prepared_statement. lex->result->simple_select() is false
3186 in INSERT ... SELECT and similar commands.
3187 */
3188
3189 if (open_cursor && lex->result && lex->result->check_simple_select()) {
3190 DBUG_PRINT("info", ("Cursor asked for not SELECT stmt"));
3191 return true;
3192 }
3193
3194 /* In case the command has a call to SP which re-uses this statement name */
3195 flags |= IS_IN_USE;
3196
3197 close_cursor();
3198
3199 /*
3200 If the free_list is not empty, we'll wrongly free some externally
3201 allocated items when cleaning up after execution of this statement.
3202 */
3203 DBUG_ASSERT(thd->change_list.is_empty());
3204
3205 /*
3206 The only case where we should have items in the thd->m_item_list is
3207 after stmt->set_params_from_vars(), which may in some cases create
3208 Item_null objects.
3209 */
3210
3211 Statement_backup stmt_backup;
3212 stmt_backup.set_thd_to_ps(thd, this);
3213 stmt_backup.save_rlb(thd);
3214
3215 /*
3216 Change the current database (if needed).
3217
3218 Force switching, because the database of the prepared statement may be
3219 NULL (prepared statements can be created while no current database
3220 selected).
3221 */
3222 if (mysql_opt_change_db(thd, m_db, &saved_cur_db_name, true,
3223 &cur_db_changed)) {
3224 flags &= ~(uint)IS_IN_USE;
3225 stmt_backup.restore_thd(thd, this);
3226 stmt_backup.restore_rlb(thd);
3227 return true;
3228 }
3229
3230 /* Allocate query. */
3231
3232 if (expanded_query->length() &&
3233 alloc_query(thd, expanded_query->ptr(), expanded_query->length())) {
3234 my_error(ER_OUTOFMEMORY, MYF(ME_FATALERROR), expanded_query->length());
3235 flags &= ~(uint)IS_IN_USE;
3236 stmt_backup.restore_thd(thd, this);
3237 stmt_backup.restore_rlb(thd);
3238 return true;
3239 }
3240
3241 /*
3242 At first execution of prepared statement we may perform logical
3243 transformations of the query tree. Such changes should be performed
3244 on the parse tree of current prepared statement and new items should
3245 be allocated in its memory root. Set the appropriate pointer in THD
3246 to the arena of the statement.
3247 */
3248 old_stmt_arena = thd->stmt_arena;
3249 thd->stmt_arena = &m_arena;
3250 bool error = reinit_stmt_before_use(thd, lex);
3251
3252 /*
3253 Set a hint so mysql_execute_command() won't clear the DA *again*,
3254 thereby discarding any conditions we might raise in here
3255 (e.g. "database we prepared with no longer exists", ER_BAD_DB_ERROR).
3256 */
3257 thd->lex->keep_diagnostics = DA_KEEP_PARSE_ERROR;
3258
3259 if (!error) {
3260 // Execute
3261 if (open_cursor) {
3262 lex->safe_to_cache_query = false;
3263 // Initialize Query_result_send before opening the cursor
3264 if (thd->is_classic_protocol())
3265 result = new (m_arena.mem_root) Query_fetch_protocol_binary(thd);
3266 else
3267 result = new (m_arena.mem_root) Query_result_send();
3268 if (!result) {
3269 error = true; // OOM
3270 } else if ((error = mysql_open_cursor(thd, result, &cursor))) {
3271 // cursor is freed inside mysql_open_cursor
3272 destroy(result);
3273 result = nullptr;
3274 }
3275 } else {
3276 /*
3277 Log COM_STMT_EXECUTE to the general log. Note, that in case of SQL
3278 prepared statements this causes two records to be output:
3279
3280 Query EXECUTE <statement name>
3281 Execute <statement SQL text>
3282
3283 This is considered user-friendly, since in the
3284 second log entry we output values of parameter markers.
3285
3286 Rewriting/password obfuscation:
3287
3288 - Any passwords in the "Execute" line should be substituted with
3289 their hashes, or a notice.
3290
3291 Rewrite first (if needed); execution might replace passwords
3292 with hashes in situ without flagging it, and then we'd make
3293 a hash of that hash.
3294 */
3295 rewrite_query_if_needed(thd);
3296 log_execute_line(thd);
3297
3298 thd->binlog_need_explicit_defaults_ts =
3299 lex->binlog_need_explicit_defaults_ts;
3300 resourcegroups::Resource_group *src_res_grp = nullptr;
3301 resourcegroups::Resource_group *dest_res_grp = nullptr;
3302 MDL_ticket *ticket = nullptr;
3303 MDL_ticket *cur_ticket = nullptr;
3304 auto mgr_ptr = resourcegroups::Resource_group_mgr::instance();
3305 bool switched = mgr_ptr->switch_resource_group_if_needed(
3306 thd, &src_res_grp, &dest_res_grp, &ticket, &cur_ticket);
3307
3308 error = mysql_execute_command(thd, true);
3309
3310 if (switched)
3311 mgr_ptr->restore_original_resource_group(thd, src_res_grp,
3312 dest_res_grp);
3313 thd->resource_group_ctx()->m_switch_resource_group_str[0] = '\0';
3314 if (ticket != nullptr)
3315 mgr_ptr->release_shared_mdl_for_resource_group(thd, ticket);
3316 if (cur_ticket != nullptr)
3317 mgr_ptr->release_shared_mdl_for_resource_group(thd, cur_ticket);
3318 }
3319 }
3320
3321 /*
3322 Restore the current database (if changed).
3323
3324 Force switching back to the saved current database (if changed),
3325 because it may be NULL. In this case, mysql_change_db() would generate
3326 an error.
3327 */
3328
3329 if (cur_db_changed)
3330 mysql_change_db(thd, to_lex_cstring(saved_cur_db_name), true);
3331
3332 // Assert that if an error, the cursor and the result are deallocated.
3333 DBUG_ASSERT(!error || (cursor == nullptr && result == nullptr));
3334
3335 cleanup_stmt();
3336
3337 /*
3338 Note that we cannot call restore_thd() here as that would overwrite
3339 the expanded query in THD::m_query_string, which is needed for is
3340 needed for slow logging. Use alloc_query() to make sure the query
3341 is allocated on the correct MEM_ROOT, since otherwise
3342 THD::m_query_string could end up as a dangling pointer
3343 (i.e. pointer to freed memory) once the PS MEM_ROOT is freed.
3344 */
3345 mysql_mutex_lock(&thd->LOCK_thd_data);
3346 thd->lex = stmt_backup.lex();
3347 mysql_mutex_unlock(&thd->LOCK_thd_data);
3348 alloc_query(thd, thd->query().str, thd->query().length);
3349
3350 thd->stmt_arena = old_stmt_arena;
3351
3352 /* Restore the original rewritten query. */
3353 stmt_backup.restore_rlb(thd);
3354
3355 if (m_arena.get_state() == Query_arena::STMT_PREPARED)
3356 m_arena.set_state(Query_arena::STMT_EXECUTED);
3357
3358 if (error == 0 && this->lex->sql_command == SQLCOM_CALL)
3359 thd->get_protocol()->send_parameters(&this->lex->param_list,
3360 is_sql_prepare());
3361 flags &= ~(uint)IS_IN_USE;
3362 return error;
3363 }
3364
3365 /** Common part of DEALLOCATE PREPARE and mysqld_stmt_close. */
3366
deallocate()3367 void Prepared_statement::deallocate() {
3368 /* We account deallocate in the same manner as mysqld_stmt_close */
3369 thd->status_var.com_stmt_close++;
3370 /* Statement map calls delete stmt on erase */
3371 thd->stmt_map.erase(this);
3372 }
3373
3374 /***************************************************************************
3375 * Ed_result_set
3376 ***************************************************************************/
3377 /**
3378 Initialize an instance of Ed_result_set.
3379
3380 Instances of the class, as well as all result set rows, are
3381 always allocated in the memory root passed over as the third
3382 argument. In the constructor, we take over ownership of the
3383 memory root. It will be freed when the class is destroyed.
3384
3385 sic: Ed_result_est is not designed to be allocated on stack.
3386 */
3387
Ed_result_set(List<Ed_row> * rows_arg,Ed_row * fields,size_t column_count_arg,MEM_ROOT * mem_root_arg)3388 Ed_result_set::Ed_result_set(List<Ed_row> *rows_arg, Ed_row *fields,
3389 size_t column_count_arg, MEM_ROOT *mem_root_arg)
3390 : m_mem_root(std::move(*mem_root_arg)),
3391 m_column_count(column_count_arg),
3392 m_rows(rows_arg),
3393 m_fields(fields),
3394 m_next_rset(nullptr) {}
3395
3396 /***************************************************************************
3397 * Ed_result_set
3398 ***************************************************************************/
3399
3400 /**
3401 Create a new "execute direct" connection.
3402 */
3403
Ed_connection(THD * thd)3404 Ed_connection::Ed_connection(THD *thd)
3405 : m_diagnostics_area(false),
3406 m_thd(thd),
3407 m_rsets(nullptr),
3408 m_current_rset(nullptr) {}
3409
3410 /**
3411 Free all result sets of the previous statement, if any,
3412 and reset warnings and errors.
3413
3414 Called before execution of the next query.
3415 */
3416
free_old_result()3417 void Ed_connection::free_old_result() {
3418 while (m_rsets) {
3419 Ed_result_set *rset = m_rsets->m_next_rset;
3420 delete m_rsets;
3421 m_rsets = rset;
3422 }
3423 m_current_rset = m_rsets;
3424 m_diagnostics_area.reset_diagnostics_area();
3425 m_diagnostics_area.reset_condition_info(m_thd);
3426 }
3427
3428 /**
3429 A simple wrapper that uses a helper class to execute SQL statements.
3430 */
3431
execute_direct(LEX_STRING sql_text)3432 bool Ed_connection::execute_direct(LEX_STRING sql_text) {
3433 Execute_sql_statement execute_sql_statement(sql_text);
3434 DBUG_PRINT("ed_query", ("%s", sql_text.str));
3435
3436 return execute_direct(&execute_sql_statement);
3437 }
3438
3439 /**
3440 Execute a fragment of server functionality without an effect on
3441 thd, and store results in memory.
3442
3443 Conventions:
3444 - the code fragment must finish with OK, EOF or ERROR.
3445 - the code fragment doesn't have to close thread tables,
3446 free memory, commit statement transaction or do any other
3447 cleanup that is normally done in the end of dispatch_command().
3448
3449 @param server_runnable A code fragment to execute.
3450 */
3451
execute_direct(Server_runnable * server_runnable)3452 bool Ed_connection::execute_direct(Server_runnable *server_runnable) {
3453 DBUG_TRACE;
3454
3455 free_old_result(); /* Delete all data from previous execution, if any */
3456
3457 Protocol_local protocol_local(m_thd, this);
3458 m_thd->push_protocol(&protocol_local);
3459 m_thd->push_diagnostics_area(&m_diagnostics_area);
3460
3461 Prepared_statement stmt(m_thd);
3462 bool rc = stmt.execute_server_runnable(server_runnable);
3463 m_thd->send_statement_status();
3464
3465 m_thd->pop_protocol();
3466 m_thd->pop_diagnostics_area();
3467 /*
3468 Protocol_local makes use of m_current_rset to keep
3469 track of the last result set, while adding result sets to the end.
3470 Reset it to point to the first result set instead.
3471 */
3472 m_current_rset = m_rsets;
3473
3474 /*
3475 Reset rewritten (for password obfuscation etc.) query after
3476 internal call from NDB etc. Without this, a rewritten query
3477 would get "stuck" in SHOW PROCESSLIST.
3478 */
3479 m_thd->reset_rewritten_query();
3480 m_thd->reset_query_for_display();
3481
3482 return rc;
3483 }
3484
3485 /**
3486 A helper method that is called only during execution.
3487
3488 Although Ed_connection doesn't support multi-statements,
3489 a statement may generate many result sets. All subsequent
3490 result sets are appended to the end.
3491
3492 @pre This is called only by Protocol_local.
3493 */
3494
add_result_set(Ed_result_set * ed_result_set)3495 void Ed_connection::add_result_set(Ed_result_set *ed_result_set) {
3496 if (m_rsets) {
3497 m_current_rset->m_next_rset = ed_result_set;
3498 /* While appending, use m_current_rset as a pointer to the tail. */
3499 m_current_rset = ed_result_set;
3500 } else
3501 m_current_rset = m_rsets = ed_result_set;
3502 }
3503
3504 /*************************************************************************
3505 * Protocol_local
3506 **************************************************************************/
3507
Protocol_local(THD * thd,Ed_connection * ed_connection)3508 Protocol_local::Protocol_local(THD *thd, Ed_connection *ed_connection)
3509 : m_connection(ed_connection),
3510 m_rset(nullptr),
3511 m_column_count(0),
3512 m_current_row(nullptr),
3513 m_current_column(nullptr),
3514 m_send_metadata(false),
3515 m_thd(thd) {}
3516
3517 /**
3518 A helper function to add the current row to the current result
3519 set. Called in @sa start_row(), when a new row is started,
3520 and in send_eof(), when the result set is finished.
3521 */
3522
opt_add_row_to_rset()3523 void Protocol_local::opt_add_row_to_rset() {
3524 if (m_current_row) {
3525 /* Add the old row to the result set */
3526 Ed_row *ed_row = new (&m_rset_root) Ed_row(m_current_row, m_column_count);
3527 if (ed_row) m_rset->push_back(ed_row, &m_rset_root);
3528 }
3529 }
3530
3531 /**
3532 Add a NULL column to the current row.
3533 */
3534
store_null()3535 bool Protocol_local::store_null() {
3536 if (m_current_column == nullptr)
3537 return true; /* start_row() failed to allocate memory. */
3538
3539 memset(m_current_column, 0, sizeof(*m_current_column));
3540 ++m_current_column;
3541 return false;
3542 }
3543
3544 /**
3545 A helper method to add any column to the current row
3546 in its binary form.
3547
3548 Allocates memory for the data in the result set memory root.
3549 */
3550
store_column(const void * data,size_t length)3551 bool Protocol_local::store_column(const void *data, size_t length) {
3552 if (m_current_column == nullptr)
3553 return true; /* start_row() failed to allocate memory. */
3554
3555 m_current_column->str = new (&m_rset_root) char[length + 1];
3556 if (!m_current_column->str) return true;
3557 memcpy(m_current_column->str, data, length);
3558 m_current_column->str[length + 1] = '\0'; /* Safety */
3559 m_current_column->length = length;
3560 ++m_current_column;
3561 return false;
3562 }
3563
3564 /**
3565 Store a string value in a result set column, optionally
3566 having converted it to character_set_results.
3567 */
3568
store_string(const char * str,size_t length,const CHARSET_INFO * src_cs,const CHARSET_INFO * dst_cs)3569 bool Protocol_local::store_string(const char *str, size_t length,
3570 const CHARSET_INFO *src_cs,
3571 const CHARSET_INFO *dst_cs) {
3572 /* Store with conversion */
3573 String convert;
3574 uint error_unused;
3575
3576 if (dst_cs && !my_charset_same(src_cs, dst_cs) && src_cs != &my_charset_bin &&
3577 dst_cs != &my_charset_bin) {
3578 if (convert.copy(str, length, src_cs, dst_cs, &error_unused)) return true;
3579 str = convert.ptr();
3580 length = convert.length();
3581 }
3582
3583 if (m_current_column == nullptr)
3584 return true; /* start_row() failed to allocate memory. */
3585
3586 m_current_column->str = strmake_root(&m_rset_root, str, length);
3587 if (!m_current_column->str) return true;
3588 m_current_column->length = length;
3589 ++m_current_column;
3590 return false;
3591 }
3592
3593 /** Store a tiny int as is (1 byte) in a result set column. */
3594
store_tiny(longlong value,uint32)3595 bool Protocol_local::store_tiny(longlong value, uint32) {
3596 char v = (char)value;
3597 return store_column(&v, 1);
3598 }
3599
3600 /** Store a short as is (2 bytes, host order) in a result set column. */
3601
store_short(longlong value,uint32)3602 bool Protocol_local::store_short(longlong value, uint32) {
3603 int16 v = (int16)value;
3604 return store_column(&v, 2);
3605 }
3606
3607 /** Store a "long" as is (4 bytes, host order) in a result set column. */
3608
store_long(longlong value,uint32)3609 bool Protocol_local::store_long(longlong value, uint32) {
3610 int32 v = (int32)value;
3611 return store_column(&v, 4);
3612 }
3613
3614 /** Store a "longlong" as is (8 bytes, host order) in a result set column. */
3615
store_longlong(longlong value,bool,uint32)3616 bool Protocol_local::store_longlong(longlong value, bool, uint32) {
3617 int64 v = (int64)value;
3618 return store_column(&v, 8);
3619 }
3620
3621 /** Store a decimal in string format in a result set column */
3622
store_decimal(const my_decimal * value,uint prec,uint dec)3623 bool Protocol_local::store_decimal(const my_decimal *value, uint prec,
3624 uint dec) {
3625 StringBuffer<DECIMAL_MAX_STR_LENGTH> str;
3626 const int rc = my_decimal2string(E_DEC_FATAL_ERROR, value, prec, dec, &str);
3627
3628 if (rc) return true;
3629
3630 return store_column(str.ptr(), str.length());
3631 }
3632
3633 /** Convert to cs_results and store a string. */
3634
store_string(const char * str,size_t length,const CHARSET_INFO * src_cs)3635 bool Protocol_local::store_string(const char *str, size_t length,
3636 const CHARSET_INFO *src_cs) {
3637 const CHARSET_INFO *dst_cs;
3638
3639 dst_cs = m_connection->m_thd->variables.character_set_results;
3640 return store_string(str, length, src_cs, dst_cs);
3641 }
3642
3643 /* Store MYSQL_TIME (in binary format) */
3644
store_datetime(const MYSQL_TIME & time,uint)3645 bool Protocol_local::store_datetime(const MYSQL_TIME &time, uint) {
3646 return store_column(&time, sizeof(MYSQL_TIME));
3647 }
3648
3649 /** Store MYSQL_TIME (in binary format) */
3650
store_date(const MYSQL_TIME & time)3651 bool Protocol_local::store_date(const MYSQL_TIME &time) {
3652 return store_column(&time, sizeof(MYSQL_TIME));
3653 }
3654
3655 /** Store MYSQL_TIME (in binary format) */
3656
store_time(const MYSQL_TIME & time,uint)3657 bool Protocol_local::store_time(const MYSQL_TIME &time, uint) {
3658 return store_column(&time, sizeof(MYSQL_TIME));
3659 }
3660
3661 /* Store a floating point number, as is. */
3662
store_float(float value,uint32,uint32)3663 bool Protocol_local::store_float(float value, uint32, uint32) {
3664 return store_column(&value, sizeof(float));
3665 }
3666
3667 /* Store a double precision number, as is. */
3668
store_double(double value,uint32,uint32)3669 bool Protocol_local::store_double(double value, uint32, uint32) {
3670 return store_column(&value, sizeof(double));
3671 }
3672
3673 /* Store a Field. */
3674
store_field(const Field * field)3675 bool Protocol_local::store_field(const Field *field) {
3676 return field->send_to_protocol(this);
3677 }
3678
3679 /** Called for statements that don't have a result set, at statement end. */
3680
send_ok(uint,uint,ulonglong,ulonglong,const char *)3681 bool Protocol_local::send_ok(uint, uint, ulonglong, ulonglong, const char *) {
3682 /*
3683 Just make sure nothing is sent to the client, we have grabbed
3684 the status information in the connection Diagnostics Area.
3685 */
3686 m_column_count = 0;
3687 return false;
3688 }
3689
3690 /**
3691 Called at the end of a result set. Append a complete
3692 result set to the list in Ed_connection.
3693
3694 Don't send anything to the client, but instead finish
3695 building of the result set at hand.
3696 */
3697
send_eof(uint,uint)3698 bool Protocol_local::send_eof(uint, uint) {
3699 Ed_result_set *ed_result_set;
3700
3701 DBUG_ASSERT(m_rset);
3702 m_current_row = nullptr;
3703
3704 ed_result_set = new (&m_rset_root)
3705 Ed_result_set(m_rset, m_fields, m_column_count, &m_rset_root);
3706
3707 m_rset = nullptr;
3708 m_fields = nullptr;
3709
3710 if (!ed_result_set) return true;
3711
3712 /*
3713 Link the created Ed_result_set instance into the list of connection
3714 result sets. Never fails.
3715 */
3716 m_connection->add_result_set(ed_result_set);
3717 m_column_count = 0;
3718 return false;
3719 }
3720
3721 /** Called to send an error to the client at the end of a statement. */
3722
send_error(uint,const char *,const char *)3723 bool Protocol_local::send_error(uint, const char *, const char *) {
3724 /*
3725 Just make sure that nothing is sent to the client (default
3726 implementation).
3727 */
3728 m_column_count = 0;
3729 return false;
3730 }
3731
read_packet()3732 int Protocol_local::read_packet() { return 0; }
3733
get_client_capabilities()3734 ulong Protocol_local::get_client_capabilities() { return 0; }
3735
has_client_capability(unsigned long)3736 bool Protocol_local::has_client_capability(unsigned long) { return false; }
3737
connection_alive() const3738 bool Protocol_local::connection_alive() const { return false; }
3739
end_partial_result_set()3740 void Protocol_local::end_partial_result_set() {}
3741
shutdown(bool)3742 int Protocol_local::shutdown(bool) { return 0; }
3743
3744 /**
3745 Called between two result set rows.
3746
3747 Prepare structures to fill result set rows.
3748 Unfortunately, we can't return an error here. If memory allocation
3749 fails, we'll have to return an error later. And so is done
3750 in methods such as @sa store_column().
3751 */
start_row()3752 void Protocol_local::start_row() {
3753 DBUG_TRACE;
3754
3755 if (m_send_metadata) return;
3756 DBUG_ASSERT(alloc_root_inited(&m_rset_root));
3757
3758 /* Start a new row. */
3759 m_current_row =
3760 (Ed_column *)m_rset_root.Alloc(sizeof(Ed_column) * m_column_count);
3761 m_current_column = m_current_row;
3762 }
3763
3764 /**
3765 Add the current row to the result set
3766 */
end_row()3767 bool Protocol_local::end_row() {
3768 DBUG_TRACE;
3769 if (m_send_metadata) return false;
3770
3771 DBUG_ASSERT(m_rset);
3772 opt_add_row_to_rset();
3773 m_current_row = nullptr;
3774
3775 return false;
3776 }
3777
get_rw_status()3778 uint Protocol_local::get_rw_status() { return 0; }
3779
start_result_metadata(uint elements,uint,const CHARSET_INFO *)3780 bool Protocol_local::start_result_metadata(uint elements, uint,
3781 const CHARSET_INFO *) {
3782 m_column_count = elements;
3783 start_row();
3784 m_send_metadata = true;
3785 m_rset = new (&m_rset_root) List<Ed_row>;
3786 return false;
3787 }
3788
end_result_metadata()3789 bool Protocol_local::end_result_metadata() {
3790 m_send_metadata = false;
3791 m_fields = new (&m_rset_root) Ed_row(m_current_row, m_column_count);
3792 m_current_row = nullptr;
3793 return false;
3794 }
3795
send_field_metadata(Send_field * field,const CHARSET_INFO * cs)3796 bool Protocol_local::send_field_metadata(Send_field *field,
3797 const CHARSET_INFO *cs) {
3798 store_string(field->col_name, strlen(field->col_name), cs);
3799 return false;
3800 }
3801
get_compression()3802 bool Protocol_local::get_compression() { return false; }
3803
get_compression_algorithm()3804 char *Protocol_local::get_compression_algorithm() { return nullptr; }
3805
get_compression_level()3806 uint Protocol_local::get_compression_level() { return 0; }
3807
get_command(COM_DATA *,enum_server_command *)3808 int Protocol_local::get_command(COM_DATA *, enum_server_command *) {
3809 return -1;
3810 }
3811