1 /* Copyright (c) 2002, 2021, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23 /**
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_prepare.h"
94 #include "auth_common.h" // insert_precheck
95 #include "log.h" // query_logger
96 #include "m_string.h"
97 #include "opt_trace.h" // Opt_trace_array
98 #include "probes_mysql.h" // MYSQL_QUERY_EXEC_START
99 #include "set_var.h" // set_var_base
100 #include "sp.h" // Sroutine_hash_entry
101 #include "sp_cache.h" // sp_cache_enforce_limit
102 #include "sql_analyse.h" // Query_result_analyse
103 #include "sql_base.h" // open_tables_for_query, open_temporary_table
104 #include "sql_cursor.h" // Server_side_cursor
105 #include "sql_db.h" // mysql_change_db
106 #include "sql_delete.h" // mysql_prepare_delete
107 #include "sql_handler.h" // mysql_ha_rm_tables
108 #include "sql_insert.h" // mysql_prepare_insert
109 #include "sql_parse.h" // sql_command_flags
110 #include "sql_rewrite.h" // mysql_rewrite_query
111 #include "sql_update.h" // mysql_prepare_update
112 #include "sql_do.h" // Query_result_do
113 #include "sql_view.h" // create_view_precheck
114 #include "transaction.h" // trans_rollback_implicit
115 #include "mysql/psi/mysql_ps.h" // MYSQL_EXECUTE_PS
116 #include "binlog.h"
117 #include "sql_audit.h" // mysql_global_audit_mask
118 #include "sql_plugin.h"
119
120 #ifdef EMBEDDED_LIBRARY
121 /* include MYSQL_BIND headers */
122 #include <mysql.h>
123 #else
124 #include <mysql_com.h>
125 #endif
126 #include "sql_query_rewrite.h"
127
128 #include <algorithm>
129 #include <limits>
130 using std::max;
131 using std::min;
132
133 /****************************************************************************/
134
135 /**
136 Execute one SQL statement in an isolated context.
137 */
138
139 class Execute_sql_statement: public Server_runnable
140 {
141 public:
142 Execute_sql_statement(LEX_STRING sql_text);
143 virtual bool execute_server_code(THD *thd);
144 private:
145 LEX_STRING m_sql_text;
146 };
147
148
149 class Ed_connection;
150
151 /**
152 Protocol_local: a helper class to intercept the result
153 of the data written to the network.
154 */
155
156 class Protocol_local : public Protocol
157 {
158 public:
159 Protocol_local(THD *thd, Ed_connection *ed_connection);
~Protocol_local()160 ~Protocol_local() { free_root(&m_rset_root, MYF(0)); }
161
162 virtual int read_packet();
163
164 virtual int get_command(COM_DATA *com_data, enum_server_command *cmd);
165 virtual ulong get_client_capabilities();
166 virtual bool has_client_capability(unsigned long client_capability);
167 virtual void end_partial_result_set();
168 virtual int shutdown(bool server_shutdown= false);
169 virtual bool connection_alive();
170 virtual void start_row();
171 virtual bool end_row();
abort_row()172 virtual void abort_row(){};
173 virtual uint get_rw_status();
174 virtual bool get_compression();
175
176 virtual bool start_result_metadata(uint num_cols, uint flags,
177 const CHARSET_INFO *resultcs);
178 virtual bool end_result_metadata();
179 virtual bool send_field_metadata(Send_field *field, const CHARSET_INFO *charset);
180 protected:
181 String *convert;
182 virtual bool store_null();
183 virtual bool store_tiny(longlong from);
184 virtual bool store_short(longlong from);
185 virtual bool store_long(longlong from);
186 virtual bool store_longlong(longlong from, bool unsigned_flag);
187 virtual bool store_decimal(const my_decimal *, uint, uint);
188 virtual bool store(const char *from, size_t length, const CHARSET_INFO *cs);
189 virtual bool store(const char *from, size_t length,
190 const CHARSET_INFO *fromcs, const CHARSET_INFO *tocs);
191 virtual bool store(MYSQL_TIME *time, uint precision);
192 virtual bool store_date(MYSQL_TIME *time);
193 virtual bool store_time(MYSQL_TIME *time, uint precision);
194 virtual bool store(float value, uint32 decimals, String *buffer);
195 virtual bool store(double value, uint32 decimals, String *buffer);
196 virtual bool store(Proto_field *field);
197
type()198 virtual enum enum_protocol_type type() { return PROTOCOL_LOCAL; }
connection_type()199 virtual enum enum_vio_type connection_type() { return VIO_TYPE_LOCAL; }
200
201 virtual bool send_ok(uint server_status, uint statement_warn_count,
202 ulonglong affected_rows, ulonglong last_insert_id,
203 const char *message);
204
205 virtual bool send_eof(uint server_status, uint statement_warn_count);
206 virtual bool send_error(uint sql_errno, const char *err_msg, const char* sqlstate);
207 private:
208 bool store_string(const char *str, size_t length,
209 const CHARSET_INFO *src_cs, const CHARSET_INFO *dst_cs);
210
211 bool store_column(const void *data, size_t length);
212 void opt_add_row_to_rset();
213 private:
214 Ed_connection *m_connection;
215 MEM_ROOT m_rset_root;
216 List<Ed_row> *m_rset;
217 size_t m_column_count;
218 Ed_column *m_current_row;
219 Ed_column *m_current_column;
220 bool m_send_metadata;
221 THD *m_thd;
222 };
223
224 /******************************************************************************
225 Implementation
226 ******************************************************************************/
227
228 /**
229 Rewrite the current query (to obfuscate passwords etc.) if needed
230 (i.e. only if we'll be writing the query to any of our logs).
231
232 Side-effect: thd->rewritten_query() may be populated with a rewritten
233 query. If the query is not of a rewritable type,
234 thd->rewritten_query() will be empty.
235
236 @param thd thread handle
237 */
rewrite_query_if_needed(THD * thd)238 static inline void rewrite_query_if_needed(THD *thd)
239 {
240 bool general= (opt_general_log &&
241 !(opt_general_log_raw || thd->slave_thread));
242
243 if ((thd->sp_runtime_ctx == NULL) &&
244 (general || opt_slow_log || opt_bin_log)) {
245 /*
246 thd->m_rewritten_query may already contain "PREPARE stmt FROM ..."
247 at this point, so we reset it here so mysql_rewrite_query()
248 won't complain.
249 */
250 thd->reset_rewritten_query();
251 /*
252 Now replace the "PREPARE ..." with the obfuscated version of the
253 actual query were prepare.
254 */
255 mysql_rewrite_query(thd);
256 }
257 }
258
259 /**
260 Unless we're doing dynamic SQL, write the current query to the
261 general query log if it's open. If we have a rewritten version
262 of the query, use that instead of the "raw" one.
263
264 Side-effect: query may be written to general log if it's open.
265
266 @param thd thread handle
267 */
log_execute_line(THD * thd)268 static inline void log_execute_line(THD *thd)
269 {
270 /*
271 Do not print anything if this is an SQL prepared statement and
272 we're inside a stored procedure (also called Dynamic SQL) --
273 sub-statements inside stored procedures are not logged into
274 the general log.
275 */
276 if (thd->sp_runtime_ctx != NULL)
277 return;
278
279 if (thd->rewritten_query().length())
280 query_logger.general_log_write(thd, COM_STMT_EXECUTE,
281 thd->rewritten_query().ptr(),
282 thd->rewritten_query().length());
283 else
284 query_logger.general_log_write(thd, COM_STMT_EXECUTE,
285 thd->query().str, thd->query().length);
286 }
287
is_param_null(const uchar * pos,ulong param_no)288 inline bool is_param_null(const uchar *pos, ulong param_no)
289 {
290 return pos[param_no/8] & (1 << (param_no & 7));
291 }
292
293
294
295 class Statement_backup
296 {
297 LEX *m_lex;
298 LEX_CSTRING m_query_string;
299 bool m_safe_to_display;
300
301 public:
lex() const302 LEX *lex() const { return m_lex; }
303
304 /**
305 Prepared the THD to execute the prepared statement.
306 Save the current THD statement state.
307 */
set_thd_to_ps(THD * thd,Prepared_statement * stmt)308 void set_thd_to_ps(THD *thd, Prepared_statement *stmt)
309 {
310 DBUG_ENTER("Statement_backup::set_thd_to_ps");
311
312 mysql_mutex_lock(&thd->LOCK_thd_data);
313 m_lex= thd->lex;
314 thd->lex= stmt->lex;
315 mysql_mutex_unlock(&thd->LOCK_thd_data);
316
317 m_query_string= thd->query();
318 thd->set_query(stmt->m_query_string);
319
320 m_safe_to_display = thd->safe_to_display();
321
322 /* Keep the current behaviour of displaying prepared statements always by
323 default. This can be changed in future if required. */
324 thd->set_safe_display(true);
325
326 DBUG_VOID_RETURN;
327 }
328
329
330 /**
331 Restore the THD statement state after the prepared
332 statement has finished executing.
333 */
restore_thd(THD * thd,Prepared_statement * stmt)334 void restore_thd(THD *thd, Prepared_statement *stmt)
335 {
336 DBUG_ENTER("Statement_backup::restore_thd");
337
338 mysql_mutex_lock(&thd->LOCK_thd_data);
339 stmt->lex= thd->lex;
340 thd->lex= m_lex;
341 mysql_mutex_unlock(&thd->LOCK_thd_data);
342
343 thd->set_safe_display(m_safe_to_display);
344 stmt->m_query_string= thd->query();
345 thd->set_query(m_query_string);
346
347 DBUG_VOID_RETURN;
348 }
349 };
350
351
352 /**
353 Send prepared statement id and metadata to the client after prepare.
354
355 @todo
356 Fix this nasty upcast from List<Item_param> to List<Item>
357
358 @return
359 0 in case of success, 1 otherwise
360 */
361
362 #ifndef EMBEDDED_LIBRARY
send_prep_stmt(Prepared_statement * stmt,uint columns)363 static bool send_prep_stmt(Prepared_statement *stmt, uint columns)
364 {
365 THD *thd= stmt->thd;
366 DBUG_ENTER("send_prep_stmt");
367 NET *net= thd->get_protocol_classic()->get_net();
368 uchar buff[12];
369 uint tmp;
370 int error;
371
372 buff[0]= 0; /* OK packet indicator */
373 int4store(buff+1, stmt->id);
374 int2store(buff+5, columns);
375 int2store(buff+7, stmt->param_count);
376 buff[9]= 0; // Guard against a 4.1 client
377 tmp= min(stmt->thd->get_stmt_da()->current_statement_cond_count(), 65535UL);
378 int2store(buff+10, tmp);
379
380 /*
381 Send types and names of placeholders to the client
382 XXX: fix this nasty upcast from List<Item_param> to List<Item>
383 */
384 error= my_net_write(net, buff, sizeof(buff));
385 if (stmt->param_count && ! error)
386 {
387 error= thd->send_result_metadata((List<Item> *) &stmt->lex->param_list,
388 Protocol::SEND_EOF);
389 }
390
391 if (!error)
392 /* Flag that a response has already been sent */
393 thd->get_stmt_da()->disable_status();
394
395 DBUG_RETURN(error);
396 }
397 #else
send_prep_stmt(Prepared_statement * stmt,uint columns MY_ATTRIBUTE ((unused)))398 static bool send_prep_stmt(Prepared_statement *stmt,
399 uint columns MY_ATTRIBUTE((unused)))
400 {
401 THD *thd= stmt->thd;
402
403 thd->client_stmt_id= stmt->id;
404 thd->client_param_count= stmt->param_count;
405 thd->clear_error();
406 thd->get_stmt_da()->disable_status();
407
408 return 0;
409 }
410 #endif /*!EMBEDDED_LIBRARY*/
411
412
413 #ifndef EMBEDDED_LIBRARY
414
415 /**
416 Read the length of the parameter data and return it back to
417 the caller.
418
419 Read data length, position the packet to the first byte after it,
420 and return the length to the caller.
421
422 @param packet a pointer to the data
423 @param len remaining packet length
424
425 @return
426 Length of data piece.
427 */
428
get_param_length(uchar ** packet,ulong len)429 static ulong get_param_length(uchar **packet, ulong len)
430 {
431 uchar *pos= *packet;
432 if (len < 1)
433 return 0;
434 if (*pos < 251)
435 {
436 (*packet)++;
437 return (ulong) *pos;
438 }
439 if (len < 3)
440 return 0;
441 if (*pos == 252)
442 {
443 (*packet)+=3;
444 return (ulong) uint2korr(pos+1);
445 }
446 if (len < 4)
447 return 0;
448 if (*pos == 253)
449 {
450 (*packet)+=4;
451 return (ulong) uint3korr(pos+1);
452 }
453 if (len < 5)
454 return 0;
455 (*packet)+=9; // Must be 254 when here
456 /*
457 In our client-server protocol all numbers bigger than 2^24
458 stored as 8 bytes with uint8korr. Here we always know that
459 parameter length is less than 2^4 so don't look at the second
460 4 bytes. But still we need to obey the protocol hence 9 in the
461 assignment above.
462 */
463 return (ulong) uint4korr(pos+1);
464 }
465 #else
466 #define get_param_length(packet, len) len
467 #endif /*!EMBEDDED_LIBRARY*/
468
469 /**
470 Data conversion routines.
471
472 All these functions read the data from pos, convert it to requested
473 type and assign to param; pos is advanced to predefined length.
474
475 Make a note that the NULL handling is examined at first execution
476 (i.e. when input types altered) and for all subsequent executions
477 we don't read any values for this.
478
479 @param param parameter item
480 @param pos input data buffer
481 @param len length of data in the buffer
482 */
483
set_param_tiny(Item_param * param,uchar ** pos,ulong len)484 static void set_param_tiny(Item_param *param, uchar **pos, ulong len)
485 {
486 #ifndef EMBEDDED_LIBRARY
487 if (len < 1)
488 return;
489 #endif
490 int8 value= (int8) **pos;
491 param->set_int(param->unsigned_flag ? (longlong) ((uint8) value) :
492 (longlong) value, 4);
493 *pos+= 1;
494 }
495
set_param_short(Item_param * param,uchar ** pos,ulong len)496 static void set_param_short(Item_param *param, uchar **pos, ulong len)
497 {
498 int16 value;
499 #ifndef EMBEDDED_LIBRARY
500 if (len < 2)
501 return;
502 value= sint2korr(*pos);
503 #else
504 shortget(&value, *pos);
505 #endif
506 param->set_int(param->unsigned_flag ? (longlong) ((uint16) value) :
507 (longlong) value, 6);
508 *pos+= 2;
509 }
510
set_param_int32(Item_param * param,uchar ** pos,ulong len)511 static void set_param_int32(Item_param *param, uchar **pos, ulong len)
512 {
513 int32 value;
514 #ifndef EMBEDDED_LIBRARY
515 if (len < 4)
516 return;
517 value= sint4korr(*pos);
518 #else
519 longget(&value, *pos);
520 #endif
521 param->set_int(param->unsigned_flag ? (longlong) ((uint32) value) :
522 (longlong) value, 11);
523 *pos+= 4;
524 }
525
set_param_int64(Item_param * param,uchar ** pos,ulong len)526 static void set_param_int64(Item_param *param, uchar **pos, ulong len)
527 {
528 longlong value;
529 #ifndef EMBEDDED_LIBRARY
530 if (len < 8)
531 return;
532 value= sint8korr(*pos);
533 #else
534 longlongget(&value, *pos);
535 #endif
536 param->set_int(value, 21);
537 *pos+= 8;
538 }
539
set_param_float(Item_param * param,uchar ** pos,ulong len)540 static void set_param_float(Item_param *param, uchar **pos, ulong len)
541 {
542 float data;
543 #ifndef EMBEDDED_LIBRARY
544 if (len < 4)
545 return;
546 float4get(&data,*pos);
547 #else
548 floatget(&data, *pos);
549 #endif
550 param->set_double((double) data);
551 *pos+= 4;
552 }
553
set_param_double(Item_param * param,uchar ** pos,ulong len)554 static void set_param_double(Item_param *param, uchar **pos, ulong len)
555 {
556 double data;
557 #ifndef EMBEDDED_LIBRARY
558 if (len < 8)
559 return;
560 float8get(&data,*pos);
561 #else
562 doubleget(&data, *pos);
563 #endif
564 param->set_double(data);
565 *pos+= 8;
566 }
567
set_param_decimal(Item_param * param,uchar ** pos,ulong len)568 static void set_param_decimal(Item_param *param, uchar **pos, ulong len)
569 {
570 ulong length= get_param_length(pos, len);
571 param->set_decimal((char*)*pos, length);
572 *pos+= length;
573 }
574
575 #ifndef EMBEDDED_LIBRARY
576
577 /*
578 Read date/time/datetime parameter values from network (binary
579 protocol). See writing counterparts of these functions in
580 libmysql.c (store_param_{time,date,datetime}).
581 */
582
583 /**
584 @todo
585 Add warning 'Data truncated' here
586 */
set_param_time(Item_param * param,uchar ** pos,ulong len)587 static void set_param_time(Item_param *param, uchar **pos, ulong len)
588 {
589 MYSQL_TIME tm;
590 ulong length= get_param_length(pos, len);
591
592 if (length >= 8)
593 {
594 uchar *to= *pos;
595 uint day;
596
597 tm.neg= (bool) to[0];
598 day= (uint) sint4korr(to+1);
599 tm.hour= (uint) to[5] + day * 24;
600 tm.minute= (uint) to[6];
601 tm.second= (uint) to[7];
602 tm.second_part= (length > 8) ? (ulong) sint4korr(to+8) : 0;
603 if (tm.hour > 838)
604 {
605 /* TODO: add warning 'Data truncated' here */
606 tm.hour= 838;
607 tm.minute= 59;
608 tm.second= 59;
609 }
610 tm.day= tm.year= tm.month= 0;
611 }
612 else
613 set_zero_time(&tm, MYSQL_TIMESTAMP_TIME);
614 param->set_time(&tm, MYSQL_TIMESTAMP_TIME,
615 MAX_TIME_FULL_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
616 *pos+= length;
617 }
618
set_param_datetime(Item_param * param,uchar ** pos,ulong len)619 static void set_param_datetime(Item_param *param, uchar **pos, ulong len)
620 {
621 MYSQL_TIME tm;
622 ulong length= get_param_length(pos, len);
623
624 if (length >= 4)
625 {
626 uchar *to= *pos;
627
628 tm.neg= 0;
629 tm.year= (uint) sint2korr(to);
630 tm.month= (uint) to[2];
631 tm.day= (uint) to[3];
632 if (length > 4)
633 {
634 tm.hour= (uint) to[4];
635 tm.minute= (uint) to[5];
636 tm.second= (uint) to[6];
637 }
638 else
639 tm.hour= tm.minute= tm.second= 0;
640
641 tm.second_part= (length > 7) ? (ulong) sint4korr(to+7) : 0;
642 }
643 else
644 set_zero_time(&tm, MYSQL_TIMESTAMP_DATETIME);
645 param->set_time(&tm, MYSQL_TIMESTAMP_DATETIME,
646 MAX_DATETIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
647 *pos+= length;
648 }
649
650
set_param_date(Item_param * param,uchar ** pos,ulong len)651 static void set_param_date(Item_param *param, uchar **pos, ulong len)
652 {
653 MYSQL_TIME tm;
654 ulong length= get_param_length(pos, len);
655
656 if (length >= 4)
657 {
658 uchar *to= *pos;
659
660 tm.year= (uint) sint2korr(to);
661 tm.month= (uint) to[2];
662 tm.day= (uint) to[3];
663
664 tm.hour= tm.minute= tm.second= 0;
665 tm.second_part= 0;
666 tm.neg= 0;
667 }
668 else
669 set_zero_time(&tm, MYSQL_TIMESTAMP_DATE);
670 param->set_time(&tm, MYSQL_TIMESTAMP_DATE,
671 MAX_DATE_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
672 *pos+= length;
673 }
674
675 #else/*!EMBEDDED_LIBRARY*/
676 /**
677 @todo
678 Add warning 'Data truncated' here
679 */
set_param_time(Item_param * param,uchar ** pos,ulong len)680 void set_param_time(Item_param *param, uchar **pos, ulong len)
681 {
682 MYSQL_TIME tm= *((MYSQL_TIME*)*pos);
683 tm.hour+= tm.day * 24;
684 tm.day= tm.year= tm.month= 0;
685 if (tm.hour > 838)
686 {
687 /* TODO: add warning 'Data truncated' here */
688 tm.hour= 838;
689 tm.minute= 59;
690 tm.second= 59;
691 }
692 param->set_time(&tm, MYSQL_TIMESTAMP_TIME,
693 MAX_TIME_FULL_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
694
695 }
696
set_param_datetime(Item_param * param,uchar ** pos,ulong len)697 void set_param_datetime(Item_param *param, uchar **pos, ulong len)
698 {
699 MYSQL_TIME tm= *((MYSQL_TIME*)*pos);
700 tm.neg= 0;
701
702 param->set_time(&tm, MYSQL_TIMESTAMP_DATETIME,
703 MAX_DATETIME_FULL_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
704 }
705
set_param_date(Item_param * param,uchar ** pos,ulong len)706 void set_param_date(Item_param *param, uchar **pos, ulong len)
707 {
708 MYSQL_TIME *to= (MYSQL_TIME*)*pos;
709
710 param->set_time(to, MYSQL_TIMESTAMP_DATE,
711 MAX_DATE_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
712 }
713 #endif /*!EMBEDDED_LIBRARY*/
714
715
set_param_str(Item_param * param,uchar ** pos,ulong len)716 static void set_param_str(Item_param *param, uchar **pos, ulong len)
717 {
718 ulong length= get_param_length(pos, len);
719 if (length > len)
720 length= len;
721 param->set_str((const char *)*pos, length);
722 *pos+= length;
723 }
724
725
726 #undef get_param_length
727
setup_one_conversion_function(THD * thd,Item_param * param,uchar param_type)728 static void setup_one_conversion_function(THD *thd, Item_param *param,
729 uchar param_type)
730 {
731 switch (param_type) {
732 case MYSQL_TYPE_TINY:
733 param->set_param_func= set_param_tiny;
734 param->item_type= Item::INT_ITEM;
735 param->item_result_type= INT_RESULT;
736 break;
737 case MYSQL_TYPE_SHORT:
738 param->set_param_func= set_param_short;
739 param->item_type= Item::INT_ITEM;
740 param->item_result_type= INT_RESULT;
741 break;
742 case MYSQL_TYPE_LONG:
743 param->set_param_func= set_param_int32;
744 param->item_type= Item::INT_ITEM;
745 param->item_result_type= INT_RESULT;
746 break;
747 case MYSQL_TYPE_LONGLONG:
748 param->set_param_func= set_param_int64;
749 param->item_type= Item::INT_ITEM;
750 param->item_result_type= INT_RESULT;
751 break;
752 case MYSQL_TYPE_FLOAT:
753 param->set_param_func= set_param_float;
754 param->item_type= Item::REAL_ITEM;
755 param->item_result_type= REAL_RESULT;
756 break;
757 case MYSQL_TYPE_DOUBLE:
758 param->set_param_func= set_param_double;
759 param->item_type= Item::REAL_ITEM;
760 param->item_result_type= REAL_RESULT;
761 break;
762 case MYSQL_TYPE_DECIMAL:
763 case MYSQL_TYPE_NEWDECIMAL:
764 param->set_param_func= set_param_decimal;
765 param->item_type= Item::DECIMAL_ITEM;
766 param->item_result_type= DECIMAL_RESULT;
767 break;
768 case MYSQL_TYPE_TIME:
769 param->set_param_func= set_param_time;
770 param->item_type= Item::STRING_ITEM;
771 param->item_result_type= STRING_RESULT;
772 break;
773 case MYSQL_TYPE_DATE:
774 param->set_param_func= set_param_date;
775 param->item_type= Item::STRING_ITEM;
776 param->item_result_type= STRING_RESULT;
777 break;
778 case MYSQL_TYPE_DATETIME:
779 case MYSQL_TYPE_TIMESTAMP:
780 param->set_param_func= set_param_datetime;
781 param->item_type= Item::STRING_ITEM;
782 param->item_result_type= STRING_RESULT;
783 break;
784 case MYSQL_TYPE_TINY_BLOB:
785 case MYSQL_TYPE_MEDIUM_BLOB:
786 case MYSQL_TYPE_LONG_BLOB:
787 case MYSQL_TYPE_BLOB:
788 param->set_param_func= set_param_str;
789 param->value.cs_info.character_set_of_placeholder= &my_charset_bin;
790 param->value.cs_info.character_set_client=
791 thd->variables.character_set_client;
792 assert(thd->variables.character_set_client);
793 param->value.cs_info.final_character_set_of_str_value= &my_charset_bin;
794 param->item_type= Item::STRING_ITEM;
795 param->item_result_type= STRING_RESULT;
796 break;
797 default:
798 /*
799 The client library ensures that we won't get any other typecodes
800 except typecodes above and typecodes for string types. Marking
801 label as 'default' lets us to handle malformed packets as well.
802 */
803 {
804 const CHARSET_INFO *fromcs= thd->variables.character_set_client;
805 const CHARSET_INFO *tocs= thd->variables.collation_connection;
806 size_t dummy_offset;
807
808 param->value.cs_info.character_set_of_placeholder= fromcs;
809 param->value.cs_info.character_set_client= fromcs;
810
811 /*
812 Setup source and destination character sets so that they
813 are different only if conversion is necessary: this will
814 make later checks easier.
815 */
816 param->value.cs_info.final_character_set_of_str_value=
817 String::needs_conversion(0, fromcs, tocs, &dummy_offset) ?
818 tocs : fromcs;
819 param->set_param_func= set_param_str;
820 /*
821 Exact value of max_length is not known unless data is converted to
822 charset of connection, so we have to set it later.
823 */
824 param->item_type= Item::STRING_ITEM;
825 param->item_result_type= STRING_RESULT;
826 }
827 }
828 param->param_type= (enum enum_field_types) param_type;
829 }
830
831 #ifndef EMBEDDED_LIBRARY
832
833 /**
834 Check whether this parameter data type is compatible with long data.
835 Used to detect whether a long data stream has been supplied to a
836 incompatible data type.
837 */
is_param_long_data_type(Item_param * param)838 inline bool is_param_long_data_type(Item_param *param)
839 {
840 return ((param->param_type >= MYSQL_TYPE_TINY_BLOB) &&
841 (param->param_type <= MYSQL_TYPE_STRING));
842 }
843
844 #ifdef HAVE_PSI_PS_INTERFACE
get_PS_prepared_stmt()845 PSI_prepared_stmt* Prepared_statement::get_PS_prepared_stmt()
846 {
847 return m_prepared_stmt;
848 }
849 #endif
850
851 /**
852 Routines to assign parameters from data supplied by the client.
853
854 Update the parameter markers by reading data from the packet and
855 and generate a valid query for logging.
856
857 @note
858 with_log is set when one of slow or general logs are open.
859 Logging of prepared statements in all cases is performed
860 by means of conventional queries: if parameter
861 data was supplied from C API, each placeholder in the query is
862 replaced with its actual value; if we're logging a [Dynamic] SQL
863 prepared statement, parameter markers are replaced with variable names.
864 Example:
865 @verbatim
866 mysqld_stmt_prepare("UPDATE t1 SET a=a*1.25 WHERE a=?")
867 --> general logs gets [Prepare] UPDATE t1 SET a*1.25 WHERE a=?"
868 mysqld_stmt_execute(stmt);
869 --> general and binary logs get
870 [Execute] UPDATE t1 SET a*1.25 WHERE a=1"
871 @endverbatim
872
873 If a statement has been prepared using SQL syntax:
874 @verbatim
875 PREPARE stmt FROM "UPDATE t1 SET a=a*1.25 WHERE a=?"
876 --> general log gets
877 [Query] PREPARE stmt FROM "UPDATE ..."
878 EXECUTE stmt USING @a
879 --> general log gets
880 [Query] EXECUTE stmt USING @a;
881 @endverbatim
882
883 @retval
884 0 if success
885 @retval
886 1 otherwise
887 */
888
insert_params(uchar * null_array,uchar * read_pos,uchar * data_end,String * query)889 bool Prepared_statement::insert_params(uchar *null_array,
890 uchar *read_pos, uchar *data_end,
891 String *query)
892 {
893 Item_param **begin= param_array;
894 Item_param **end= begin + param_count;
895 size_t length= 0;
896 String str;
897 const String *res;
898 DBUG_ENTER("insert_params");
899
900 if (with_log && query->copy(m_query_string.str,
901 m_query_string.length, default_charset_info))
902 DBUG_RETURN(1);
903
904 for (Item_param **it= begin; it < end; ++it)
905 {
906 Item_param *param= *it;
907 if (param->state != Item_param::LONG_DATA_VALUE)
908 {
909 if (is_param_null(null_array, (uint) (it - begin)))
910 param->set_null();
911 else
912 {
913 if (read_pos >= data_end)
914 DBUG_RETURN(1);
915 param->set_param_func(param, &read_pos, (uint) (data_end - read_pos));
916 if (param->state == Item_param::NO_VALUE)
917 DBUG_RETURN(1);
918
919 if (with_log &&
920 param->limit_clause_param && param->state != Item_param::INT_VALUE)
921 {
922 param->set_int(param->val_int(), MY_INT64_NUM_DECIMAL_DIGITS);
923 param->item_type= Item::INT_ITEM;
924 if (!param->unsigned_flag && param->value.integer < 0)
925 DBUG_RETURN(1);
926 }
927 }
928 }
929 /*
930 A long data stream was supplied for this parameter marker.
931 This was done after prepare, prior to providing a placeholder
932 type (the types are supplied at execute). Check that the
933 supplied type of placeholder can accept a data stream.
934 */
935 else if (! is_param_long_data_type(param))
936 DBUG_RETURN(1);
937 if (with_log)
938 {
939 res= param->query_val_str(thd, &str);
940 if (param->convert_str_value(thd))
941 DBUG_RETURN(1); /* out of memory */
942
943 if (query->replace(param->pos_in_query+length, 1, *res))
944 DBUG_RETURN(1);
945
946 length+= res->length()-1;
947 }
948 else
949 {
950 if (param->convert_str_value(thd))
951 DBUG_RETURN(1); /* out of memory */
952 }
953 }
954 DBUG_RETURN(0);
955 }
956
957
setup_conversion_functions(Prepared_statement * stmt,uchar ** data,uchar * data_end)958 static bool setup_conversion_functions(Prepared_statement *stmt,
959 uchar **data, uchar *data_end)
960 {
961 /* skip null bits */
962 uchar *read_pos= *data + (stmt->param_count+7) / 8;
963
964 DBUG_ENTER("setup_conversion_functions");
965
966 if (read_pos >= data_end)
967 DBUG_RETURN(1);
968
969 if (*read_pos++) //types supplied / first execute
970 {
971 /*
972 First execute or types altered by the client, setup the
973 conversion routines for all parameters (one time)
974 */
975 Item_param **it= stmt->param_array;
976 Item_param **end= it + stmt->param_count;
977 THD *thd= stmt->thd;
978 for (; it < end; ++it)
979 {
980 ushort typecode;
981 const uint signed_bit= 1 << 15;
982
983 if (read_pos >= data_end)
984 DBUG_RETURN(1);
985
986 typecode= sint2korr(read_pos);
987 read_pos+= 2;
988 (**it).unsigned_flag= MY_TEST(typecode & signed_bit);
989 setup_one_conversion_function(thd, *it, (uchar) (typecode & ~signed_bit));
990 }
991 }
992 *data= read_pos;
993 DBUG_RETURN(0);
994 }
995
996 #else
997
998 /**
999 Embedded counterparts of the parameter assignment routine.
1000
1001 The main difference between the embedded library and the server is
1002 that in embedded case we don't serialize/deserialize parameters data.
1003
1004 Additionally, for unknown reason, the client-side flag raised for
1005 changed types of placeholders is ignored and we simply setup conversion
1006 functions at each execute (TODO: fix).
1007 */
1008
emb_insert_params(String * query)1009 bool Prepared_statement::emb_insert_params(String *query)
1010 {
1011 Item_param **it= param_array;
1012 Item_param **end= it + param_count;
1013 MYSQL_BIND *client_param= thd->client_params;
1014
1015 String str;
1016 const String *res;
1017 size_t length= 0;
1018
1019 DBUG_ENTER("emb_insert_params");
1020
1021 if (with_log && query->copy(m_query_string.str,
1022 m_query_string.length,
1023 default_charset_info))
1024 DBUG_RETURN(true);
1025
1026 for (; it < end; ++it, ++client_param)
1027 {
1028 Item_param *param= *it;
1029 setup_one_conversion_function(thd, param, client_param->buffer_type);
1030 if (param->state != Item_param::LONG_DATA_VALUE)
1031 {
1032 if (*client_param->is_null)
1033 param->set_null();
1034 else
1035 {
1036 uchar *buff= (uchar*) client_param->buffer;
1037 param->unsigned_flag= client_param->is_unsigned;
1038 param->set_param_func(param, &buff,
1039 client_param->length ?
1040 *client_param->length :
1041 client_param->buffer_length);
1042 if (param->state == Item_param::NO_VALUE)
1043 DBUG_RETURN(1);
1044 }
1045 }
1046 if (with_log)
1047 {
1048 res= param->query_val_str(thd, &str);
1049 if (param->convert_str_value(thd))
1050 DBUG_RETURN(1); /* out of memory */
1051
1052 if (query->replace(param->pos_in_query + length, 1, *res))
1053 DBUG_RETURN(1);
1054
1055 length+= res->length()-1;
1056 }
1057 else
1058 {
1059 if (param->convert_str_value(thd))
1060 DBUG_RETURN(1); /* out of memory */
1061 }
1062 }
1063 DBUG_RETURN(0);
1064 }
1065
1066 #endif /*!EMBEDDED_LIBRARY*/
1067
1068 /**
1069 Setup data conversion routines using an array of parameter
1070 markers from the original prepared statement.
1071 Swap the parameter data of the original prepared
1072 statement to the new one.
1073
1074 Used only when we re-prepare a prepared statement.
1075 There are two reasons for this function to exist:
1076
1077 1) In the binary client/server protocol, parameter metadata
1078 is sent only at first execute. Consequently, if we need to
1079 reprepare a prepared statement at a subsequent execution,
1080 we may not have metadata information in the packet.
1081 In that case we use the parameter array of the original
1082 prepared statement to setup parameter types of the new
1083 prepared statement.
1084
1085 2) In the binary client/server protocol, we may supply
1086 long data in pieces. When the last piece is supplied,
1087 we assemble the pieces and convert them from client
1088 character set to the connection character set. After
1089 that the parameter value is only available inside
1090 the parameter, the original pieces are lost, and thus
1091 we can only assign the corresponding parameter of the
1092 reprepared statement from the original value.
1093
1094 @param[out] param_array_dst parameter markers of the new statement
1095 @param[in] param_array_src parameter markers of the original
1096 statement
1097 @param[in] param_count total number of parameters. Is the
1098 same in src and dst arrays, since
1099 the statement query is the same
1100
1101 @return this function never fails
1102 */
1103
1104 static void
swap_parameter_array(Item_param ** param_array_dst,Item_param ** param_array_src,uint param_count)1105 swap_parameter_array(Item_param **param_array_dst,
1106 Item_param **param_array_src,
1107 uint param_count)
1108 {
1109 Item_param **dst= param_array_dst;
1110 Item_param **src= param_array_src;
1111 Item_param **end= param_array_dst + param_count;
1112
1113 for (; dst < end; ++src, ++dst)
1114 (*dst)->set_param_type_and_swap_value(*src);
1115 }
1116
1117
1118 /**
1119 Assign prepared statement parameters from user variables.
1120 If with_log is set, also construct query test for binary log.
1121
1122 @param varnames List of variables. Caller must ensure that number
1123 of variables in the list is equal to number of statement
1124 parameters
1125 @param query The query with parameter markers replaced with corresponding
1126 user variables that were used to execute the query.
1127 */
1128
insert_params_from_vars(List<LEX_STRING> & varnames,String * query)1129 bool Prepared_statement::insert_params_from_vars(List<LEX_STRING>& varnames,
1130 String *query)
1131 {
1132 Item_param **begin= param_array;
1133 Item_param **end= begin + param_count;
1134 user_var_entry *entry;
1135 LEX_STRING *varname;
1136 List_iterator<LEX_STRING> var_it(varnames);
1137 StringBuffer<STRING_BUFFER_USUAL_SIZE> buf;
1138 const String *val;
1139 size_t length= 0;
1140
1141 DBUG_ENTER("insert_params_from_vars");
1142
1143 if (with_log) query->reserve(m_query_string.length + 32 * param_count);
1144
1145 /* Protects thd->user_vars */
1146 mysql_mutex_lock(&thd->LOCK_thd_data);
1147
1148 for (Item_param **it= begin; it < end; ++it)
1149 {
1150 Item_param *param= *it;
1151 varname= var_it++;
1152
1153 entry= (user_var_entry *) my_hash_search(&thd->user_vars, (uchar*)
1154 varname->str, varname->length);
1155 if (with_log)
1156 {
1157 /*
1158 We have to call the setup_one_conversion_function() here to set
1159 the parameter's members that might be needed further
1160 (e.g. value.cs_info.character_set_client is used in the query_val_str()).
1161 */
1162 setup_one_conversion_function(thd, param, param->param_type);
1163 if (param->set_from_user_var(thd, entry))
1164 goto error;
1165 val= param->query_val_str(thd, &buf);
1166
1167 if (param->convert_str_value(thd))
1168 goto error;
1169
1170 assert(param->pos_in_query > length);
1171 size_t num_bytes = param->pos_in_query - length;
1172 if (query->length() + num_bytes + val->length() >
1173 std::numeric_limits<uint32>::max())
1174 goto error;
1175
1176 if (query->append(m_query_string.str + length, num_bytes) ||
1177 query->append(*val))
1178 goto error;
1179
1180 length = param->pos_in_query + 1;
1181 }
1182 else
1183 {
1184 if (param->set_from_user_var(thd, entry))
1185 goto error;
1186
1187 if (entry)
1188 length+= entry->length();
1189
1190 if (length > std::numeric_limits<uint32>::max() ||
1191 param->convert_str_value(thd))
1192 goto error;
1193 }
1194 }
1195 // If logging, take care of tail.
1196 if (with_log)
1197 query->append(m_query_string.str + length, m_query_string.length - length);
1198
1199 mysql_mutex_unlock(&thd->LOCK_thd_data);
1200 DBUG_RETURN(0);
1201
1202 error:
1203 mysql_mutex_unlock(&thd->LOCK_thd_data);
1204 DBUG_RETURN(1);
1205
1206 }
1207
1208 /**
1209 Validate INSERT statement.
1210
1211 @param stmt prepared statement
1212 @param tables global/local table list
1213
1214 @retval
1215 FALSE success
1216 @retval
1217 TRUE error, error message is set in THD
1218 */
1219
mysql_test_insert(THD * thd,TABLE_LIST * table_list)1220 bool Sql_cmd_insert::mysql_test_insert(THD *thd, TABLE_LIST *table_list)
1221 {
1222 List_iterator_fast<List_item> its(insert_many_values);
1223 List_item *values;
1224 DBUG_ENTER("mysql_test_insert");
1225
1226 if (open_temporary_tables(thd, table_list))
1227 goto error;
1228
1229 if (insert_precheck(thd, table_list))
1230 goto error;
1231
1232 /*
1233 Open temporary memory pool for temporary data allocated by derived
1234 tables & preparation procedure
1235 Note that this is done without locks (should not be needed as we will not
1236 access any data here)
1237 */
1238 if (open_tables_for_query(thd, table_list, MYSQL_OPEN_FORCE_SHARED_MDL))
1239 goto error;
1240
1241 if ((values= its++))
1242 {
1243 if (table_list->table)
1244 {
1245 // don't allocate insert_values
1246 table_list->table->insert_values=(uchar *)1;
1247 }
1248
1249 if (mysql_prepare_insert(thd, table_list, values, false))
1250 goto error;
1251
1252 its.rewind();
1253 }
1254 DBUG_RETURN(FALSE);
1255
1256 error:
1257 /* insert_values is cleared in open_table */
1258 DBUG_RETURN(TRUE);
1259 }
1260
1261
1262 /**
1263 Validate UPDATE statement.
1264
1265 @param thd current thread
1266
1267 @todo
1268 - here we should send types of placeholders to the client.
1269
1270 @retval
1271 0 success
1272 @retval
1273 1 error, error message is set in THD
1274 @retval
1275 2 convert to multi_update
1276 */
1277
mysql_test_update(THD * thd)1278 int Sql_cmd_update::mysql_test_update(THD *thd)
1279 {
1280 DBUG_ENTER("mysql_test_update");
1281
1282 SELECT_LEX *const select= thd->lex->select_lex;
1283 TABLE_LIST *const table_list= select->get_table_list();
1284
1285 if (update_precheck(thd, table_list))
1286 DBUG_RETURN(1);
1287 if (open_tables_for_query(thd, table_list, MYSQL_OPEN_FORCE_SHARED_MDL))
1288 DBUG_RETURN(1);
1289
1290 if (select->setup_tables(thd, table_list, false))
1291 DBUG_RETURN(true); /* purecov: inspected */
1292
1293 if (table_list->is_view())
1294 {
1295 if (table_list->resolve_derived(thd, false))
1296 DBUG_RETURN(true); /* purecov: inspected */
1297
1298 if (select->merge_derived(thd, table_list))
1299 DBUG_RETURN(true); /* purecov: inspected */
1300 }
1301
1302 if (!table_list->is_updatable())
1303 {
1304 my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "UPDATE");
1305 DBUG_RETURN(1);
1306 }
1307
1308 if (table_list->is_multiple_tables())
1309 {
1310 assert(table_list->is_view());
1311 DBUG_PRINT("info", ("Switch to multi-update"));
1312 /* convert to multiupdate */
1313 DBUG_RETURN(2);
1314 }
1315
1316 TABLE_LIST *const update_table_ref= table_list->updatable_base_table();
1317
1318 key_map covering_keys_for_cond;
1319 if (mysql_prepare_update(thd, update_table_ref, &covering_keys_for_cond,
1320 update_value_list))
1321 DBUG_RETURN(1);
1322
1323 /* TODO: here we should send types of placeholders to the client. */
1324 DBUG_RETURN(0);
1325 }
1326
1327
1328 /**
1329 Validate DELETE statement.
1330
1331 @param thd current thread
1332
1333 @retval
1334 FALSE success
1335 @retval
1336 TRUE error, error message is set in THD
1337 */
1338
prepared_statement_test(THD * thd)1339 bool Sql_cmd_delete::prepared_statement_test(THD *thd)
1340 {
1341 DBUG_ENTER("Sql_cmd_delete::prepare_test");
1342
1343 SELECT_LEX *const select= thd->lex->select_lex;
1344
1345 assert(thd->lex->query_tables ==
1346 thd->lex->select_lex->get_table_list());
1347 TABLE_LIST *const table_list= select->get_table_list();
1348
1349 if (delete_precheck(thd, table_list))
1350 DBUG_RETURN(true);
1351 if (open_tables_for_query(thd, table_list, MYSQL_OPEN_FORCE_SHARED_MDL))
1352 DBUG_RETURN(true);
1353
1354 if (mysql_prepare_delete(thd))
1355 DBUG_RETURN(true);
1356
1357 DBUG_RETURN(false);
1358 }
1359
1360
1361 /**
1362 Validate SELECT statement.
1363
1364 In case of success, if this query is not EXPLAIN, send column list info
1365 back to the client.
1366
1367 @param stmt prepared statement
1368 @param tables list of tables used in the query
1369
1370 @retval
1371 0 success
1372 @retval
1373 1 error, error message is set in THD
1374 @retval
1375 2 success, and statement metadata has been sent
1376 */
1377
mysql_test_select(Prepared_statement * stmt,TABLE_LIST * tables)1378 static int mysql_test_select(Prepared_statement *stmt,
1379 TABLE_LIST *tables)
1380 {
1381 THD *thd= stmt->thd;
1382 LEX *lex= stmt->lex;
1383 SELECT_LEX_UNIT *unit= lex->unit;
1384 DBUG_ENTER("mysql_test_select");
1385
1386 lex->select_lex->context.resolve_in_select_list= true;
1387
1388 if (select_precheck(thd, lex, tables, lex->select_lex->table_list.first))
1389 goto error;
1390
1391 if (!lex->result)
1392 {
1393 if (lex->sql_command == SQLCOM_DO)
1394 {
1395 if (!(lex->result= new (stmt->mem_root) Query_result_do(thd)))
1396 {
1397 my_error(ER_OUTOFMEMORY, MYF(ME_FATALERROR),
1398 static_cast<int>(sizeof(Query_result_do)));
1399 goto error;
1400 }
1401 }
1402 else
1403 {
1404 if (!(lex->result= new (stmt->mem_root) Query_result_send()))
1405 {
1406 my_error(ER_OUTOFMEMORY, MYF(ME_FATALERROR),
1407 static_cast<int>(sizeof(Query_result_send)));
1408 goto error;
1409 }
1410 }
1411 }
1412
1413 if (open_tables_for_query(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL))
1414 goto error;
1415
1416 thd->lex->used_tables= 0; // Updated by setup_fields
1417
1418 /*
1419 SELECT_LEX::prepare calls
1420 It is not SELECT COMMAND for sure, so setup_tables will be called as
1421 usual, and we pass 0 as setup_tables_done_option
1422 */
1423 if (unit->prepare(thd, 0, 0, 0))
1424 goto error;
1425 if (!lex->describe && !stmt->is_sql_prepare())
1426 {
1427 Query_result *result= lex->result;
1428 Query_result *analyse_result= NULL;
1429 if (lex->proc_analyse)
1430 {
1431 /*
1432 We need proper output recordset metadata for SELECT ... PROCEDURE ANALUSE()
1433 */
1434 if ((result= analyse_result=
1435 new Query_result_analyse(result, lex->proc_analyse)) == NULL)
1436 goto error; // OOM
1437 }
1438
1439 /*
1440 We can use "result" as it should've been prepared in
1441 unit->prepare call above.
1442 */
1443 bool rc= (send_prep_stmt(stmt,
1444 lex->sql_command == SQLCOM_DO ?
1445 0 :
1446 result->field_count(unit->types)) ||
1447 result->send_result_set_metadata(unit->types,
1448 Protocol::SEND_EOF) ||
1449 thd->get_protocol_classic()->flush());
1450 delete analyse_result;
1451 if (rc)
1452 goto error;
1453 DBUG_RETURN(2);
1454 }
1455 DBUG_RETURN(0);
1456 error:
1457 DBUG_RETURN(1);
1458 }
1459
1460
1461 /**
1462 Validate and prepare for execution SET statement expressions.
1463
1464 @param stmt prepared statement
1465 @param tables list of tables used in this query
1466 @param values list of expressions
1467
1468 @retval
1469 FALSE success
1470 @retval
1471 TRUE error, error message is set in THD
1472 */
1473
mysql_test_set_fields(Prepared_statement * stmt,TABLE_LIST * tables,List<set_var_base> * var_list)1474 static bool mysql_test_set_fields(Prepared_statement *stmt,
1475 TABLE_LIST *tables,
1476 List<set_var_base> *var_list)
1477 {
1478 List_iterator_fast<set_var_base> it(*var_list);
1479 THD *thd= stmt->thd;
1480 set_var_base *var;
1481 DBUG_ENTER("mysql_test_set_fields");
1482 assert(stmt->is_stmt_prepare());
1483
1484 if (tables &&
1485 check_table_access(thd, SELECT_ACL, tables, FALSE, UINT_MAX, FALSE))
1486 DBUG_RETURN(true); /* purecov: inspected */
1487
1488 if (open_tables_for_query(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL))
1489 DBUG_RETURN(true); /* purecov: inspected */
1490
1491 while ((var= it++))
1492 {
1493 if (var->light_check(thd))
1494 DBUG_RETURN(true); /* purecov: inspected */
1495 var->cleanup();
1496 }
1497
1498 DBUG_RETURN(false);
1499 }
1500
1501
1502 /**
1503 Validate and prepare for execution CALL statement expressions.
1504
1505 @param stmt prepared statement
1506 @param tables list of tables used in this query
1507 @param value_list list of expressions
1508
1509 @retval FALSE success
1510 @retval TRUE error, error message is set in THD
1511 */
1512
mysql_test_call_fields(Prepared_statement * stmt,TABLE_LIST * tables,List<Item> * value_list)1513 static bool mysql_test_call_fields(Prepared_statement *stmt,
1514 TABLE_LIST *tables,
1515 List<Item> *value_list)
1516 {
1517 List_iterator<Item> it(*value_list);
1518 THD *thd= stmt->thd;
1519 Item *item;
1520 DBUG_ENTER("mysql_test_call_fields");
1521 assert(stmt->is_stmt_prepare());
1522
1523 if (tables &&
1524 check_table_access(thd, SELECT_ACL, tables, FALSE, UINT_MAX, FALSE))
1525 DBUG_RETURN(true); /* purecov: inspected */
1526
1527 if (open_tables_for_query(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL))
1528 DBUG_RETURN(true); /* purecov: inspected */
1529
1530 while ((item= it++))
1531 {
1532 if ((!item->fixed && item->fix_fields(thd, it.ref())) ||
1533 item->check_cols(1))
1534 DBUG_RETURN(true); /* purecov: inspected */
1535 }
1536
1537 DBUG_RETURN(false);
1538 }
1539
1540
1541 /**
1542 Check internal SELECT of the prepared command.
1543
1544 @param stmt prepared statement
1545 @param thd current thread
1546 @param setup_tables_done_option options to be passed to LEX::unit->prepare()
1547
1548 @note
1549 This function won't directly open tables used in select. They should
1550 be opened either by calling function (and in this case you probably
1551 should use select_like_stmt_test_with_open()) or by
1552 "specific_prepare" call (like this happens in case of multi-update).
1553
1554 @retval
1555 FALSE success
1556 @retval
1557 TRUE error, error message is set in THD
1558 */
1559
select_like_stmt_cmd_test(THD * thd,Sql_cmd_dml * cmd,ulong setup_tables_done_option)1560 bool select_like_stmt_cmd_test(THD *thd,
1561 Sql_cmd_dml *cmd,
1562 ulong setup_tables_done_option)
1563 {
1564 DBUG_ENTER("select_like_stmt_test");
1565 LEX *lex= thd->lex;
1566
1567 lex->select_lex->context.resolve_in_select_list= true;
1568
1569 if (cmd != NULL && cmd->prepare(thd))
1570 DBUG_RETURN(TRUE);
1571
1572 thd->lex->used_tables= 0; // Updated by setup_fields
1573
1574 /* Calls SELECT_LEX::prepare */
1575 const bool ret= lex->unit->prepare(thd, 0, setup_tables_done_option, 0);
1576 DBUG_RETURN(ret);
1577 }
1578
1579
1580 /**
1581 Check internal SELECT of the prepared command.
1582
1583 @note Old version. Will be replaced with select_like_stmt_cmd_test() after
1584 the parser refactoring.
1585
1586 @param stmt prepared statement
1587 @param specific_prepare function of command specific prepare
1588 @param setup_tables_done_option options to be passed to LEX::unit->prepare()
1589
1590 @note
1591 This function won't directly open tables used in select. They should
1592 be opened either by calling function (and in this case you probably
1593 should use select_like_stmt_test_with_open()) or by
1594 "specific_prepare" call (like this happens in case of multi-update).
1595
1596 @retval
1597 FALSE success
1598 @retval
1599 TRUE error, error message is set in THD
1600 */
1601
select_like_stmt_test(Prepared_statement * stmt,int (* specific_prepare)(THD * thd),ulong setup_tables_done_option)1602 static bool select_like_stmt_test(Prepared_statement *stmt,
1603 int (*specific_prepare)(THD *thd),
1604 ulong setup_tables_done_option)
1605 {
1606 DBUG_ENTER("select_like_stmt_test");
1607 THD *thd= stmt->thd;
1608 LEX *lex= stmt->lex;
1609
1610 lex->select_lex->context.resolve_in_select_list= true;
1611
1612 if (specific_prepare && (*specific_prepare)(thd))
1613 DBUG_RETURN(TRUE);
1614
1615 thd->lex->used_tables= 0; // Updated by setup_fields
1616
1617 /* Calls SELECT_LEX::prepare */
1618 const bool ret= lex->unit->prepare(thd, 0, setup_tables_done_option, 0);
1619 DBUG_RETURN(ret);
1620 }
1621
1622
1623 /**
1624 Check internal SELECT of the prepared command (with opening of used
1625 tables).
1626
1627 @param thd current thread
1628 @param tables list of tables to be opened
1629 before calling specific_prepare function
1630 @param cmd Sql_cmd to call Sql_cmd::prepare()
1631 @param setup_tables_done_option options to be passed to LEX::unit->prepare()
1632
1633 @retval
1634 FALSE success
1635 @retval
1636 TRUE error
1637 */
1638
1639 static bool
select_like_stmt_cmd_test_with_open(THD * thd,TABLE_LIST * tables,Sql_cmd_dml * cmd,ulong setup_tables_done_option)1640 select_like_stmt_cmd_test_with_open(THD *thd,
1641 TABLE_LIST *tables,
1642 Sql_cmd_dml *cmd,
1643 ulong setup_tables_done_option)
1644 {
1645 DBUG_ENTER("select_like_stmt_test_with_open");
1646
1647 if (open_tables_for_query(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL))
1648 DBUG_RETURN(true);
1649
1650 if (select_like_stmt_cmd_test(thd, cmd, setup_tables_done_option))
1651 DBUG_RETURN(true);
1652
1653 DBUG_RETURN(false);
1654 }
1655
1656
1657 /**
1658 Validate and prepare for execution CREATE TABLE statement.
1659
1660 @param stmt prepared statement
1661 @param tables list of tables used in this query
1662
1663 @retval
1664 FALSE success
1665 @retval
1666 TRUE error, error message is set in THD
1667 */
1668
mysql_test_create_table(Prepared_statement * stmt)1669 static bool mysql_test_create_table(Prepared_statement *stmt)
1670 {
1671 THD *thd= stmt->thd;
1672 LEX *lex= stmt->lex;
1673 SELECT_LEX *select_lex= lex->select_lex;
1674 bool res= FALSE;
1675 bool link_to_local;
1676 TABLE_LIST *create_table= lex->query_tables;
1677 TABLE_LIST *tables= lex->create_last_non_select_table->next_global;
1678 DBUG_ENTER("mysql_test_create_table");
1679 assert(stmt->is_stmt_prepare());
1680
1681 if (create_table_precheck(thd, tables, create_table))
1682 DBUG_RETURN(TRUE);
1683
1684 if (select_lex->item_list.elements)
1685 {
1686 /* Base table and temporary table are not in the same name space. */
1687 if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE))
1688 create_table->open_type= OT_BASE_ONLY;
1689
1690 if (open_tables_for_query(stmt->thd, lex->query_tables,
1691 MYSQL_OPEN_FORCE_SHARED_MDL))
1692 DBUG_RETURN(TRUE);
1693
1694 select_lex->context.resolve_in_select_list= true;
1695
1696 lex->unlink_first_table(&link_to_local);
1697
1698 res= select_like_stmt_test(stmt, 0, 0);
1699
1700 lex->link_first_table_back(create_table, link_to_local);
1701 }
1702 else
1703 {
1704 /*
1705 Check that the source table exist, and also record
1706 its metadata version. Even though not strictly necessary,
1707 we validate metadata of all CREATE TABLE statements,
1708 which keeps metadata validation code simple.
1709 */
1710 if (open_tables_for_query(stmt->thd, lex->query_tables,
1711 MYSQL_OPEN_FORCE_SHARED_MDL))
1712 DBUG_RETURN(TRUE);
1713 }
1714
1715 DBUG_RETURN(res);
1716 }
1717
1718
1719 /**
1720 @brief Validate and prepare for execution CREATE VIEW statement
1721
1722 @param stmt prepared statement
1723
1724 @note This function handles create view commands.
1725
1726 @retval FALSE Operation was a success.
1727 @retval TRUE An error occured.
1728 */
1729
mysql_test_create_view(Prepared_statement * stmt)1730 static bool mysql_test_create_view(Prepared_statement *stmt)
1731 {
1732 THD *thd= stmt->thd;
1733 LEX *lex= stmt->lex;
1734 bool res= TRUE;
1735 /* Skip first table, which is the view we are creating */
1736 bool link_to_local;
1737 TABLE_LIST *view= lex->unlink_first_table(&link_to_local);
1738 TABLE_LIST *tables= lex->query_tables;
1739 DBUG_ENTER("mysql_test_create_view");
1740 assert(stmt->is_stmt_prepare());
1741
1742 if (create_view_precheck(thd, tables, view, lex->create_view_mode))
1743 goto err;
1744
1745 /*
1746 Since we can't pre-open temporary tables for SQLCOM_CREATE_VIEW,
1747 (see mysql_create_view) we have to do it here instead.
1748 */
1749 if (open_temporary_tables(thd, tables))
1750 goto err;
1751
1752 if (open_tables_for_query(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL))
1753 goto err;
1754
1755 lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW;
1756 res= select_like_stmt_test(stmt, 0, 0);
1757
1758 err:
1759 /* put view back for PS rexecuting */
1760 lex->link_first_table_back(view, link_to_local);
1761 DBUG_RETURN(res);
1762 }
1763
1764
1765 /**
1766 Validate and prepare for execution a multi delete statement.
1767
1768 @param thd current thread
1769 @param tables list of tables used in this query
1770
1771 @retval
1772 FALSE success
1773 @retval
1774 TRUE error, error message in THD is set.
1775 */
1776
prepared_statement_test(THD * thd)1777 bool Sql_cmd_delete_multi::prepared_statement_test(THD *thd)
1778 {
1779 LEX *lex= thd->lex;
1780 TABLE_LIST * const tables= lex->query_tables;
1781 lex->set_current_select(lex->select_lex);
1782 if (add_item_to_list(thd, new Item_null()))
1783 {
1784 /* purecov: begin inspected */
1785 my_error(ER_OUTOFMEMORY, MYF(ME_FATALERROR), 0);
1786 return true;
1787 /* purecov: end */
1788 }
1789
1790 if (multi_delete_precheck(thd, tables))
1791 return true;
1792 if (select_like_stmt_cmd_test_with_open(thd, tables,
1793 this,
1794 OPTION_SETUP_TABLES_DONE))
1795 return true;
1796
1797 return false;
1798 }
1799
1800
1801 /**
1802 Wrapper for mysql_insert_select_prepare, to make change of local tables
1803 after open_tables_for_query() call.
1804
1805 @param thd thread handle
1806
1807 We need to remove the first local table after
1808 open_tables_for_query(), because mysql_insert_select_prepare()
1809 uses local tables lists.
1810 */
1811
prepare(THD * thd)1812 bool Sql_cmd_insert_select::prepare(THD *thd)
1813 {
1814 SELECT_LEX *const first_select= thd->lex->select_lex;
1815 TABLE_LIST *const second_table= first_select->table_list.first->next_local;
1816
1817 /* Skip first table, which is the table we are inserting in */
1818 first_select->table_list.first= second_table;
1819 thd->lex->select_lex->context.table_list=
1820 thd->lex->select_lex->context.first_name_resolution_table= second_table;
1821
1822 return mysql_insert_select_prepare(thd);
1823 }
1824
1825
1826 /**
1827 Validate and prepare for execution INSERT ... SELECT statement.
1828
1829 @param thd current thread
1830
1831 @retval
1832 FALSE success
1833 @retval
1834 TRUE error, error message is set in THD
1835 */
1836
prepared_statement_test(THD * thd)1837 bool Sql_cmd_insert_select::prepared_statement_test(THD *thd)
1838 {
1839 TABLE_LIST * const tables= thd->lex->query_tables;
1840 int res;
1841 LEX *lex= thd->lex;
1842 TABLE_LIST *first_local_table;
1843
1844 if (tables->table)
1845 {
1846 // don't allocate insert_values
1847 tables->table->insert_values=(uchar *)1;
1848 }
1849
1850 if (insert_precheck(thd, tables))
1851 return 1;
1852
1853 /* store it, because Sql_cmd_insert_select::prepare() change it */
1854 first_local_table= lex->select_lex->table_list.first;
1855 assert(first_local_table != 0);
1856
1857 res=
1858 select_like_stmt_cmd_test_with_open(thd, tables,
1859 this,
1860 OPTION_SETUP_TABLES_DONE);
1861 /* revert changes made by Sql_cmd_insert_select::prepare() */
1862 lex->select_lex->table_list.first= first_local_table;
1863 return res;
1864 }
1865
1866
1867 /**
1868 Perform semantic analysis of the parsed tree and send a response packet
1869 to the client.
1870
1871 This function
1872 - opens all tables and checks access rights
1873 - validates semantics of statement columns and SQL functions
1874 by calling fix_fields.
1875
1876 @param stmt prepared statement
1877
1878 @retval
1879 FALSE success, statement metadata is sent to client
1880 @retval
1881 TRUE error, error message is set in THD (but not sent)
1882 */
1883
check_prepared_statement(Prepared_statement * stmt)1884 static bool check_prepared_statement(Prepared_statement *stmt)
1885 {
1886 THD *thd= stmt->thd;
1887 LEX *lex= stmt->lex;
1888 assert(lex == thd->lex); // set_n_backup_active_arena() guarantees that
1889 SELECT_LEX *select_lex= lex->select_lex;
1890 enum enum_sql_command sql_command= lex->sql_command;
1891 int res= 0;
1892 DBUG_ENTER("check_prepared_statement");
1893 DBUG_PRINT("enter",("command: %d param_count: %u",
1894 sql_command, stmt->param_count));
1895
1896 lex->first_lists_tables_same();
1897 TABLE_LIST *const tables= lex->query_tables;
1898
1899 /* set context for commands which do not use setup_tables */
1900 lex->select_lex->context.resolve_in_table_list_only(select_lex->
1901 get_table_list());
1902
1903 /*
1904 For the optimizer trace, this is the symmetric, for statement preparation,
1905 of what is done at statement execution (in mysql_execute_command()).
1906 */
1907 Opt_trace_start ots(thd, tables, sql_command, &lex->var_list,
1908 thd->query().str, thd->query().length, NULL,
1909 thd->variables.character_set_client);
1910
1911 Opt_trace_object trace_command(&thd->opt_trace);
1912 Opt_trace_array trace_command_steps(&thd->opt_trace, "steps");
1913
1914 if ((thd->lex->keep_diagnostics == DA_KEEP_COUNTS) ||
1915 (thd->lex->keep_diagnostics == DA_KEEP_DIAGNOSTICS))
1916 {
1917 my_error(ER_UNSUPPORTED_PS, MYF(0));
1918 goto error;
1919 }
1920
1921 if (sql_command_flags[sql_command] & CF_HA_CLOSE)
1922 mysql_ha_rm_tables(thd, tables);
1923
1924 /*
1925 Open temporary tables that are known now. Temporary tables added by
1926 prelocking will be opened afterwards (during open_tables()).
1927 */
1928 if (sql_command_flags[sql_command] & CF_PREOPEN_TMP_TABLES)
1929 {
1930 if (open_temporary_tables(thd, tables))
1931 goto error;
1932 }
1933
1934 switch (sql_command) {
1935 case SQLCOM_INSERT:
1936 case SQLCOM_INSERT_SELECT:
1937 case SQLCOM_REPLACE:
1938 case SQLCOM_REPLACE_SELECT:
1939 case SQLCOM_UPDATE:
1940 case SQLCOM_UPDATE_MULTI:
1941 case SQLCOM_DELETE:
1942 case SQLCOM_DELETE_MULTI:
1943 assert(thd->lex == stmt->lex);
1944 res=
1945 static_cast<Sql_cmd_dml *>(lex->m_sql_cmd)->prepared_statement_test(thd);
1946 break;
1947 /* The following allow WHERE clause, so they must be tested like SELECT */
1948 case SQLCOM_SHOW_DATABASES:
1949 case SQLCOM_SHOW_TABLES:
1950 case SQLCOM_SHOW_TRIGGERS:
1951 case SQLCOM_SHOW_EVENTS:
1952 case SQLCOM_SHOW_OPEN_TABLES:
1953 case SQLCOM_SHOW_FIELDS:
1954 case SQLCOM_SHOW_KEYS:
1955 case SQLCOM_SHOW_COLLATIONS:
1956 case SQLCOM_SHOW_CHARSETS:
1957 case SQLCOM_SHOW_VARIABLES:
1958 case SQLCOM_SHOW_STATUS:
1959 case SQLCOM_SHOW_TABLE_STATUS:
1960 case SQLCOM_SHOW_STATUS_PROC:
1961 case SQLCOM_SHOW_STATUS_FUNC:
1962 case SQLCOM_SELECT:
1963 case SQLCOM_DO:
1964 res= mysql_test_select(stmt, tables);
1965 if (res == 2)
1966 {
1967 /* Statement and field info has already been sent */
1968 DBUG_RETURN(FALSE);
1969 }
1970 break;
1971 case SQLCOM_CREATE_TABLE:
1972 res= mysql_test_create_table(stmt);
1973 break;
1974
1975 case SQLCOM_CREATE_VIEW:
1976 if (lex->create_view_mode == VIEW_ALTER)
1977 {
1978 my_message(ER_UNSUPPORTED_PS, ER(ER_UNSUPPORTED_PS), MYF(0));
1979 goto error;
1980 }
1981 res= mysql_test_create_view(stmt);
1982 break;
1983
1984 case SQLCOM_CALL:
1985 res= mysql_test_call_fields(stmt, tables, &lex->call_value_list);
1986 break;
1987 case SQLCOM_SET_OPTION:
1988 res= mysql_test_set_fields(stmt, tables, &lex->var_list);
1989 break;
1990
1991 /*
1992 Note that we don't need to have cases in this list if they are
1993 marked with CF_STATUS_COMMAND in sql_command_flags
1994 */
1995 case SQLCOM_DROP_TABLE:
1996 case SQLCOM_RENAME_TABLE:
1997 case SQLCOM_ALTER_TABLE:
1998 case SQLCOM_COMMIT:
1999 case SQLCOM_CREATE_INDEX:
2000 case SQLCOM_DROP_INDEX:
2001 case SQLCOM_ROLLBACK:
2002 case SQLCOM_TRUNCATE:
2003 case SQLCOM_DROP_VIEW:
2004 case SQLCOM_REPAIR:
2005 case SQLCOM_ANALYZE:
2006 case SQLCOM_OPTIMIZE:
2007 case SQLCOM_CHANGE_MASTER:
2008 case SQLCOM_CHANGE_REPLICATION_FILTER:
2009 case SQLCOM_RESET:
2010 case SQLCOM_FLUSH:
2011 case SQLCOM_SLAVE_START:
2012 case SQLCOM_SLAVE_STOP:
2013 case SQLCOM_INSTALL_PLUGIN:
2014 case SQLCOM_UNINSTALL_PLUGIN:
2015 case SQLCOM_CREATE_DB:
2016 case SQLCOM_DROP_DB:
2017 case SQLCOM_ALTER_DB_UPGRADE:
2018 case SQLCOM_CHECKSUM:
2019 case SQLCOM_CREATE_USER:
2020 case SQLCOM_RENAME_USER:
2021 case SQLCOM_DROP_USER:
2022 case SQLCOM_ALTER_USER:
2023 case SQLCOM_ASSIGN_TO_KEYCACHE:
2024 case SQLCOM_PRELOAD_KEYS:
2025 case SQLCOM_GRANT:
2026 case SQLCOM_REVOKE:
2027 case SQLCOM_KILL:
2028 case SQLCOM_ALTER_INSTANCE:
2029 break;
2030
2031 case SQLCOM_PREPARE:
2032 case SQLCOM_EXECUTE:
2033 case SQLCOM_DEALLOCATE_PREPARE:
2034 default:
2035 /*
2036 Trivial check of all status commands and diagnostic commands.
2037 This is easier than having things in the above case list,
2038 as it's less chance for mistakes.
2039 */
2040 if (!(sql_command_flags[sql_command] & CF_STATUS_COMMAND)
2041 || (sql_command_flags[sql_command] & CF_DIAGNOSTIC_STMT)
2042 )
2043 {
2044 /* All other statements are not supported yet. */
2045 my_message(ER_UNSUPPORTED_PS, ER(ER_UNSUPPORTED_PS), MYF(0));
2046 goto error;
2047 }
2048 break;
2049 }
2050 if (res == 0)
2051 {
2052 DBUG_RETURN(stmt->is_sql_prepare() ? FALSE : (send_prep_stmt(stmt, 0) ||
2053 thd->get_protocol_classic()->flush()));
2054 }
2055 error:
2056 DBUG_RETURN(TRUE);
2057 }
2058
2059 /**
2060 Initialize array of parameters in statement from LEX.
2061 (We need to have quick access to items by number in mysql_stmt_get_longdata).
2062 This is to avoid using malloc/realloc in the parser.
2063 */
2064
init_param_array(Prepared_statement * stmt)2065 static bool init_param_array(Prepared_statement *stmt)
2066 {
2067 LEX *lex= stmt->lex;
2068 if ((stmt->param_count= lex->param_list.elements))
2069 {
2070 if (stmt->param_count > (uint) UINT_MAX16)
2071 {
2072 /* Error code to be defined in 5.0 */
2073 my_message(ER_PS_MANY_PARAM, ER(ER_PS_MANY_PARAM), MYF(0));
2074 return TRUE;
2075 }
2076 Item_param **to;
2077 List_iterator<Item_param> param_iterator(lex->param_list);
2078 /* Use thd->mem_root as it points at statement mem_root */
2079 stmt->param_array= (Item_param **)
2080 alloc_root(stmt->thd->mem_root,
2081 sizeof(Item_param*) * stmt->param_count);
2082 if (!stmt->param_array)
2083 return TRUE;
2084 for (to= stmt->param_array;
2085 to < stmt->param_array + stmt->param_count;
2086 ++to)
2087 {
2088 *to= param_iterator++;
2089 }
2090 }
2091 return FALSE;
2092 }
2093
2094
2095 /**
2096 COM_STMT_PREPARE handler.
2097
2098 Given a query string with parameter markers, create a prepared
2099 statement from it and send PS info back to the client.
2100
2101 If parameter markers are found in the query, then store the information
2102 using Item_param along with maintaining a list in lex->param_array, so
2103 that a fast and direct retrieval can be made without going through all
2104 field items.
2105
2106 @param thd thread handle
2107 @param query query to be prepared
2108 @param length query string length, including ignored
2109 trailing NULL or quote char.
2110
2111 @note
2112 This function parses the query and sends the total number of parameters
2113 and resultset metadata information back to client (if any), without
2114 executing the query i.e. without any log/disk writes. This allows the
2115 queries to be re-executed without re-parsing during execute.
2116
2117 @return
2118 none: in case of success a new statement id and metadata is sent
2119 to the client, otherwise an error message is set in THD.
2120 */
2121
mysqld_stmt_prepare(THD * thd,const char * query,uint length)2122 void mysqld_stmt_prepare(THD *thd, const char *query, uint length)
2123 {
2124 Protocol *save_protocol= thd->get_protocol();
2125 Prepared_statement *stmt;
2126 DBUG_ENTER("mysqld_stmt_prepare");
2127
2128 DBUG_PRINT("prep_query", ("%s", query));
2129
2130 /* First of all clear possible warnings from the previous command */
2131 mysql_reset_thd_for_next_command(thd);
2132
2133 if (! (stmt= new Prepared_statement(thd)))
2134 DBUG_VOID_RETURN; /* out of memory: error is set in Sql_alloc */
2135
2136 if (thd->stmt_map.insert(thd, stmt))
2137 {
2138 /*
2139 The error is set in the insert. The statement itself
2140 will be also deleted there (this is how the hash works).
2141 */
2142 DBUG_VOID_RETURN;
2143 }
2144
2145 // set the current client capabilities before switching the protocol
2146 thd->protocol_binary.set_client_capabilities(
2147 thd->get_protocol()->get_client_capabilities());
2148
2149 thd->set_protocol(&thd->protocol_binary);
2150
2151 /* Create PS table entry, set query text after rewrite. */
2152 stmt->m_prepared_stmt= MYSQL_CREATE_PS(stmt, stmt->id,
2153 thd->m_statement_psi,
2154 stmt->name().str, stmt->name().length,
2155 NULL, 0);
2156
2157 if (stmt->prepare(query, length))
2158 {
2159 /* Delete this stmt stats from PS table. */
2160 MYSQL_DESTROY_PS(stmt->m_prepared_stmt);
2161 /* Statement map deletes statement on erase */
2162 thd->stmt_map.erase(stmt);
2163 }
2164
2165 thd->set_protocol(save_protocol);
2166
2167 sp_cache_enforce_limit(thd->sp_proc_cache, stored_program_cache_size);
2168 sp_cache_enforce_limit(thd->sp_func_cache, stored_program_cache_size);
2169
2170 /* check_prepared_statement sends the metadata packet in case of success */
2171 DBUG_VOID_RETURN;
2172 }
2173
2174 /**
2175 Get an SQL statement text from a user variable or from plain text.
2176
2177 If the statement is plain text, just assign the
2178 pointers, otherwise allocate memory in thd->mem_root and copy
2179 the contents of the variable, possibly with character
2180 set conversion.
2181
2182 @param[in] lex main lex
2183 @param[out] query_len length of the SQL statement (is set only
2184 in case of success)
2185
2186 @retval
2187 non-zero success
2188 @retval
2189 0 in case of error (out of memory)
2190 */
2191
get_dynamic_sql_string(LEX * lex,size_t * query_len)2192 static const char *get_dynamic_sql_string(LEX *lex, size_t *query_len)
2193 {
2194 THD *thd= lex->thd;
2195 char *query_str= 0;
2196
2197 if (lex->prepared_stmt_code_is_varref)
2198 {
2199 /* This is PREPARE stmt FROM or EXECUTE IMMEDIATE @var. */
2200 String str;
2201 const CHARSET_INFO *to_cs= thd->variables.collation_connection;
2202 bool needs_conversion;
2203 user_var_entry *entry;
2204 String *var_value= &str;
2205 size_t unused;
2206 size_t len;
2207
2208 /* Protects thd->user_vars */
2209 mysql_mutex_lock(&thd->LOCK_thd_data);
2210
2211 entry= (user_var_entry*)my_hash_search(&thd->user_vars,
2212 (uchar*)lex->prepared_stmt_code.str,
2213 lex->prepared_stmt_code.length);
2214
2215 /*
2216 Convert @var contents to string in connection character set. Although
2217 it is known that int/real/NULL value cannot be a valid query we still
2218 convert it for error messages to be uniform.
2219 */
2220 if ((entry != NULL) && entry->ptr())
2221 {
2222 my_bool is_var_null;
2223 var_value= entry->val_str(&is_var_null, &str, NOT_FIXED_DEC);
2224
2225 mysql_mutex_unlock(&thd->LOCK_thd_data);
2226
2227 /*
2228 NULL value of variable checked early as entry->value so here
2229 we can't get NULL in normal conditions
2230 */
2231 assert(!is_var_null);
2232 if (!var_value)
2233 goto end;
2234 }
2235 else
2236 {
2237 mysql_mutex_unlock(&thd->LOCK_thd_data);
2238
2239 /*
2240 variable absent or equal to NULL, so we need to set variable to
2241 something reasonable to get a readable error message during parsing
2242 */
2243 str.set(STRING_WITH_LEN("NULL"), &my_charset_latin1);
2244 }
2245
2246 needs_conversion= String::needs_conversion(var_value->length(),
2247 var_value->charset(), to_cs,
2248 &unused);
2249
2250 len= (needs_conversion ? var_value->length() * to_cs->mbmaxlen :
2251 var_value->length());
2252 if (!(query_str= (char*) alloc_root(thd->mem_root, len+1)))
2253 goto end;
2254
2255 if (needs_conversion)
2256 {
2257 uint dummy_errors;
2258 len= copy_and_convert(query_str, len, to_cs, var_value->ptr(),
2259 var_value->length(), var_value->charset(),
2260 &dummy_errors);
2261 }
2262 else
2263 memcpy(query_str, var_value->ptr(), var_value->length());
2264 query_str[len]= '\0'; // Safety (mostly for debug)
2265 *query_len= len;
2266 }
2267 else
2268 {
2269 query_str= lex->prepared_stmt_code.str;
2270 *query_len= lex->prepared_stmt_code.length;
2271 }
2272 end:
2273 return query_str;
2274 }
2275
2276
2277 /**
2278 SQLCOM_PREPARE implementation.
2279
2280 Prepare an SQL prepared statement. This is called from
2281 mysql_execute_command and should therefore behave like an
2282 ordinary query (e.g. should not reset any global THD data).
2283
2284 @param thd thread handle
2285
2286 @return
2287 none: in case of success, OK packet is sent to the client,
2288 otherwise an error message is set in THD
2289 */
2290
mysql_sql_stmt_prepare(THD * thd)2291 void mysql_sql_stmt_prepare(THD *thd)
2292 {
2293 LEX *lex= thd->lex;
2294 const LEX_CSTRING &name= lex->prepared_stmt_name;
2295 Prepared_statement *stmt;
2296 const char *query;
2297 size_t query_len= 0;
2298 DBUG_ENTER("mysql_sql_stmt_prepare");
2299
2300 if ((stmt= thd->stmt_map.find_by_name(name)))
2301 {
2302 /*
2303 If there is a statement with the same name, remove it. It is ok to
2304 remove old and fail to insert a new one at the same time.
2305 */
2306 if (stmt->is_in_use())
2307 {
2308 my_error(ER_PS_NO_RECURSION, MYF(0));
2309 DBUG_VOID_RETURN;
2310 }
2311
2312 MYSQL_DESTROY_PS(stmt->m_prepared_stmt);
2313 stmt->deallocate();
2314 }
2315
2316 if (! (query= get_dynamic_sql_string(lex, &query_len)) ||
2317 ! (stmt= new Prepared_statement(thd)))
2318 {
2319 DBUG_VOID_RETURN; /* out of memory */
2320 }
2321
2322 stmt->set_sql_prepare();
2323
2324 /* Set the name first, insert should know that this statement has a name */
2325 if (stmt->set_name(name))
2326 {
2327 delete stmt;
2328 DBUG_VOID_RETURN;
2329 }
2330
2331 if (thd->stmt_map.insert(thd, stmt))
2332 {
2333 /* The statement is deleted and an error is set if insert fails */
2334 DBUG_VOID_RETURN;
2335 }
2336
2337 /* Create PS table entry, set query text after rewrite. */
2338 stmt->m_prepared_stmt= MYSQL_CREATE_PS(stmt, stmt->id,
2339 thd->m_statement_psi,
2340 stmt->name().str, stmt->name().length,
2341 NULL, 0);
2342
2343 if (stmt->prepare(query, query_len))
2344 {
2345 /* Delete this stmt stats from PS table. */
2346 MYSQL_DESTROY_PS(stmt->m_prepared_stmt);
2347 /* Statement map deletes the statement on erase */
2348 thd->stmt_map.erase(stmt);
2349 }
2350 else
2351 {
2352 /* send the boolean tracker in the OK packet when
2353 @@session_track_state_change is set to ON */
2354 if (thd->session_tracker.get_tracker(SESSION_STATE_CHANGE_TRACKER)->is_enabled())
2355 thd->session_tracker.get_tracker(SESSION_STATE_CHANGE_TRACKER)->mark_as_changed(thd, NULL);
2356 my_ok(thd, 0L, 0L, "Statement prepared");
2357 }
2358
2359 DBUG_VOID_RETURN;
2360 }
2361
2362 /**
2363 Reinit prepared statement/stored procedure before execution. Resets the LEX
2364 object.
2365
2366
2367 @todo
2368 When the new table structure is ready, then have a status bit
2369 to indicate the table is altered, and re-do the setup_*
2370 and open the tables back.
2371
2372 @retval false OK.
2373 @retval true Error.
2374 */
2375
reinit_stmt_before_use(THD * thd,LEX * lex)2376 bool reinit_stmt_before_use(THD *thd, LEX *lex)
2377 {
2378 SELECT_LEX *sl= lex->all_selects_list;
2379 DBUG_ENTER("reinit_stmt_before_use");
2380
2381 // Default to READ access for every field that is resolved
2382 thd->mark_used_columns= MARK_COLUMNS_READ;
2383
2384 /*
2385 THD::derived_tables_processing is not reset if derived table resolving fails
2386 for the previous sub-statement. Hence resetting it here.
2387 */
2388 thd->derived_tables_processing= false;
2389
2390 /*
2391 We have to update "thd" pointer in LEX, all its units and in LEX::result,
2392 since statements which belong to trigger body are associated with TABLE
2393 object and because of this can be used in different threads.
2394 */
2395 lex->thd= thd;
2396
2397 if (lex->m_sql_cmd != NULL)
2398 lex->m_sql_cmd->cleanup(thd);
2399
2400 for (; sl; sl= sl->next_select_in_list())
2401 {
2402 if (!sl->first_execution)
2403 {
2404 /* see unique_table() */
2405 sl->exclude_from_table_unique_test= FALSE;
2406
2407 /*
2408 These must be reset before every new preparation.
2409 @note done here and not in st_select_lex::prepare() since for
2410 multi-table UPDATE and DELETE, derived tables are merged into
2411 the outer query block before ::prepare() is called.
2412 */
2413 sl->cond_count= 0;
2414 sl->between_count= 0;
2415 sl->max_equal_elems= 0;
2416
2417 if (sl->where_cond())
2418 {
2419 assert(sl->where_cond()->real_item()); // no dangling 'ref'
2420 sl->where_cond()->cleanup();
2421 }
2422 if (sl->having_cond())
2423 {
2424 assert(sl->having_cond()->real_item());
2425 sl->having_cond()->cleanup();
2426 }
2427 assert(sl->join == 0);
2428 ORDER *order;
2429 /* Fix GROUP list */
2430 if (sl->group_list_ptrs && sl->group_list_ptrs->size() > 0)
2431 {
2432 for (uint ix= 0; ix < sl->group_list_ptrs->size() - 1; ++ix)
2433 {
2434 order= sl->group_list_ptrs->at(ix);
2435 order->next= sl->group_list_ptrs->at(ix+1);
2436 }
2437 }
2438 for (order= sl->group_list.first; order; order= order->next)
2439 order->item= &order->item_ptr;
2440 /* Fix ORDER list */
2441 if (sl->order_list_ptrs && sl->order_list_ptrs->size() > 0)
2442 {
2443 for (uint ix= 0; ix < sl->order_list_ptrs->size() - 1; ++ix)
2444 {
2445 order= sl->order_list_ptrs->at(ix);
2446 order->next= sl->order_list_ptrs->at(ix+1);
2447 }
2448 }
2449 for (order= sl->order_list.first; order; order= order->next)
2450 order->item= &order->item_ptr;
2451 }
2452 {
2453 SELECT_LEX_UNIT *unit= sl->master_unit();
2454 unit->unclean();
2455 unit->types.empty();
2456 /* for derived tables & PS (which can't be reset by Item_subquery) */
2457 unit->reinit_exec_mechanism();
2458 unit->set_thd(thd);
2459 }
2460 }
2461
2462 /*
2463 TODO: When the new table structure is ready, then have a status bit
2464 to indicate the table is altered, and re-do the setup_*
2465 and open the tables back.
2466 */
2467 /*
2468 NOTE: We should reset whole table list here including all tables added
2469 by prelocking algorithm (it is not a problem for substatements since
2470 they have their own table list).
2471 Another note: this loop uses query_tables so does not see TABLE_LISTs
2472 which represent join nests.
2473 */
2474 for (TABLE_LIST *tables= lex->query_tables;
2475 tables;
2476 tables= tables->next_global)
2477 {
2478 tables->reinit_before_use(thd);
2479 }
2480
2481 /* Reset MDL tickets for procedures/functions */
2482 for (Sroutine_hash_entry *rt= thd->lex->sroutines_list.first;
2483 rt; rt= rt->next)
2484 rt->mdl_request.ticket= NULL;
2485
2486 /*
2487 Cleanup of the special case of DELETE t1, t2 FROM t1, t2, t3 ...
2488 (multi-delete). We do a full clean up, although at the moment all we
2489 need to clean in the tables of MULTI-DELETE list is 'table' member.
2490 */
2491 for (TABLE_LIST *tables= lex->auxiliary_table_list.first;
2492 tables;
2493 tables= tables->next_global)
2494 {
2495 tables->reinit_before_use(thd);
2496 }
2497 lex->set_current_select(lex->select_lex);
2498
2499 // restore leaf tables used in INSERT ... SELECT
2500 if (lex->insert_table)
2501 lex->select_lex->leaf_tables= lex->insert_table->first_leaf_table();
2502
2503 if (lex->result)
2504 {
2505 lex->result->cleanup();
2506 lex->result->set_thd(thd);
2507 }
2508 lex->allow_sum_func= 0;
2509 lex->in_sum_func= NULL;
2510
2511 if (unlikely(lex->is_broken()))
2512 {
2513 // Force a Reprepare, to get a fresh LEX
2514 Reprepare_observer *reprepare_observer= thd->get_reprepare_observer();
2515 if (reprepare_observer &&
2516 reprepare_observer->report_error(thd))
2517 {
2518 assert(thd->is_error());
2519 DBUG_RETURN(true);
2520 }
2521 }
2522
2523 DBUG_RETURN(false);
2524 }
2525
2526
2527 /**
2528 Clears parameters from data left from previous execution or long data.
2529
2530 @param stmt prepared statement for which parameters should
2531 be reset
2532 */
2533
reset_stmt_params(Prepared_statement * stmt)2534 static void reset_stmt_params(Prepared_statement *stmt)
2535 {
2536 Item_param **item= stmt->param_array;
2537 Item_param **end= item + stmt->param_count;
2538 for (;item < end ; ++item)
2539 (**item).reset();
2540 }
2541
2542
2543 /**
2544 COM_STMT_EXECUTE handler: execute a previously prepared statement.
2545
2546 If there are any parameters, then replace parameter markers with the
2547 data supplied from the client, and then execute the statement.
2548 This function uses binary protocol to send a possible result set
2549 to the client.
2550
2551 @param thd current thread
2552 @param stmt_id statement id
2553 @param flags flags mask
2554 @param params parameter types and data, if any
2555 @param params_length packet length, including the terminator character.
2556
2557 @return
2558 none: in case of success OK packet or a result set is sent to the
2559 client, otherwise an error message is set in THD.
2560 */
2561
mysqld_stmt_execute(THD * thd,ulong stmt_id,ulong flags,uchar * params,ulong params_length)2562 void mysqld_stmt_execute(THD *thd, ulong stmt_id, ulong flags, uchar *params,
2563 ulong params_length)
2564 {
2565 /* Query text for binary, general or slow log, if any of them is open */
2566 String expanded_query;
2567 Prepared_statement *stmt;
2568 Protocol *save_protocol= thd->get_protocol();
2569 bool open_cursor;
2570 DBUG_ENTER("mysqld_stmt_execute");
2571
2572 /* First of all clear possible warnings from the previous command */
2573 mysql_reset_thd_for_next_command(thd);
2574
2575 if (!(stmt= thd->stmt_map.find(stmt_id)))
2576 {
2577 char llbuf[22];
2578 my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), static_cast<int>(sizeof(llbuf)),
2579 llstr(stmt_id, llbuf), "mysqld_stmt_execute");
2580 DBUG_VOID_RETURN;
2581 }
2582
2583
2584
2585 #if defined(ENABLED_PROFILING)
2586 thd->profiling.set_query_source(stmt->m_query_string.str,
2587 stmt->m_query_string.length);
2588 #endif
2589
2590 DBUG_PRINT("info",("stmt: 0x%lx", (long) stmt));
2591
2592 open_cursor= MY_TEST(flags & (ulong) CURSOR_TYPE_READ_ONLY);
2593
2594 // set the current client capabilities before switching the protocol
2595 thd->protocol_binary.set_client_capabilities(
2596 thd->get_protocol()->get_client_capabilities());
2597 thd->set_protocol(&thd->protocol_binary);
2598
2599 MYSQL_EXECUTE_PS(thd->m_statement_psi, stmt->m_prepared_stmt);
2600
2601 stmt->execute_loop(&expanded_query, open_cursor, params,
2602 params + params_length);
2603 thd->set_protocol(save_protocol);
2604
2605 sp_cache_enforce_limit(thd->sp_proc_cache, stored_program_cache_size);
2606 sp_cache_enforce_limit(thd->sp_func_cache, stored_program_cache_size);
2607
2608 /* Close connection socket; for use with client testing (Bug#43560). */
2609 DBUG_EXECUTE_IF(
2610 "close_conn_after_stmt_execute", thd->get_protocol()->shutdown(););
2611
2612 DBUG_VOID_RETURN;
2613 }
2614
2615
2616 /**
2617 SQLCOM_EXECUTE implementation.
2618
2619 Execute prepared statement using parameter values from
2620 lex->prepared_stmt_params and send result to the client using
2621 text protocol. This is called from mysql_execute_command and
2622 therefore should behave like an ordinary query (e.g. not change
2623 global THD data, such as warning count, server status, etc).
2624 This function uses text protocol to send a possible result set.
2625
2626 @param thd thread handle
2627
2628 @return
2629 none: in case of success, OK (or result set) packet is sent to the
2630 client, otherwise an error is set in THD
2631 */
2632
mysql_sql_stmt_execute(THD * thd)2633 void mysql_sql_stmt_execute(THD *thd)
2634 {
2635 LEX *lex= thd->lex;
2636 Prepared_statement *stmt;
2637 const LEX_CSTRING &name= lex->prepared_stmt_name;
2638 /* Query text for binary, general or slow log, if any of them is open */
2639 String expanded_query;
2640 DBUG_ENTER("mysql_sql_stmt_execute");
2641 DBUG_PRINT("info", ("EXECUTE: %.*s\n", (int) name.length, name.str));
2642
2643 if (!(stmt= thd->stmt_map.find_by_name(name)))
2644 {
2645 my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0),
2646 static_cast<int>(name.length), name.str, "EXECUTE");
2647 DBUG_VOID_RETURN;
2648 }
2649
2650 if (stmt->param_count != lex->prepared_stmt_params.elements)
2651 {
2652 my_error(ER_WRONG_ARGUMENTS, MYF(0), "EXECUTE");
2653 DBUG_VOID_RETURN;
2654 }
2655
2656 DBUG_PRINT("info",("stmt: 0x%lx", (long) stmt));
2657
2658 MYSQL_EXECUTE_PS(thd->m_statement_psi, stmt->m_prepared_stmt);
2659
2660 (void) stmt->execute_loop(&expanded_query, FALSE, NULL, NULL);
2661
2662 DBUG_VOID_RETURN;
2663 }
2664
2665
2666 /**
2667 COM_STMT_FETCH handler: fetches requested amount of rows from cursor.
2668
2669 @param thd Thread handle
2670 @param stmt_id Packet from client (with stmt_id & num_rows)
2671 @param num_rows Length of packet
2672 */
2673
mysqld_stmt_fetch(THD * thd,ulong stmt_id,ulong num_rows)2674 void mysqld_stmt_fetch(THD *thd, ulong stmt_id, ulong num_rows)
2675 {
2676 Prepared_statement *stmt;
2677 Server_side_cursor *cursor;
2678 DBUG_ENTER("mysqld_stmt_fetch");
2679
2680 /* First of all clear possible warnings from the previous command */
2681 mysql_reset_thd_for_next_command(thd);
2682 thd->status_var.com_stmt_fetch++;
2683 if (!(stmt= thd->stmt_map.find(stmt_id)))
2684 {
2685 char llbuf[22];
2686 my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), static_cast<int>(sizeof(llbuf)),
2687 llstr(stmt_id, llbuf), "mysqld_stmt_fetch");
2688 DBUG_VOID_RETURN;
2689 }
2690
2691 cursor= stmt->cursor;
2692 if (!cursor)
2693 {
2694 my_error(ER_STMT_HAS_NO_OPEN_CURSOR, MYF(0), stmt_id);
2695 DBUG_VOID_RETURN;
2696 }
2697
2698 thd->stmt_arena= stmt;
2699 Statement_backup stmt_backup;
2700 stmt_backup.set_thd_to_ps(thd, stmt);
2701
2702 cursor->fetch(num_rows);
2703
2704 if (!cursor->is_open())
2705 {
2706 stmt->close_cursor();
2707 reset_stmt_params(stmt);
2708 }
2709
2710 stmt_backup.restore_thd(thd, stmt);
2711 thd->stmt_arena= thd;
2712
2713 DBUG_VOID_RETURN;
2714 }
2715
2716
2717 /**
2718 Reset a prepared statement in case there was a recoverable error.
2719
2720 This function resets statement to the state it was right after prepare.
2721 It can be used to:
2722 - clear an error happened during mysqld_stmt_send_long_data
2723 - cancel long data stream for all placeholders without
2724 having to call mysqld_stmt_execute.
2725 - close an open cursor
2726 Sends 'OK' packet in case of success (statement was reset)
2727 or 'ERROR' packet (unrecoverable error/statement not found/etc).
2728
2729 @param thd Thread handle
2730 @param stmt_id Stmt id
2731 */
2732
mysqld_stmt_reset(THD * thd,ulong stmt_id)2733 void mysqld_stmt_reset(THD *thd, ulong stmt_id)
2734 {
2735 Prepared_statement *stmt;
2736 DBUG_ENTER("mysqld_stmt_reset");
2737
2738 /* First of all clear possible warnings from the previous command */
2739 mysql_reset_thd_for_next_command(thd);
2740
2741 thd->status_var.com_stmt_reset++;
2742 if (!(stmt= thd->stmt_map.find(stmt_id)))
2743 {
2744 char llbuf[22];
2745 my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), static_cast<int>(sizeof(llbuf)),
2746 llstr(stmt_id, llbuf), "mysqld_stmt_reset");
2747 DBUG_VOID_RETURN;
2748 }
2749
2750 stmt->close_cursor();
2751
2752 /*
2753 Clear parameters from data which could be set by
2754 mysqld_stmt_send_long_data() call.
2755 */
2756 reset_stmt_params(stmt);
2757
2758 stmt->state= Query_arena::STMT_PREPARED;
2759
2760 query_logger.general_log_print(thd, thd->get_command(), NullS);
2761
2762 my_ok(thd);
2763
2764 DBUG_VOID_RETURN;
2765 }
2766
2767
2768 /**
2769 Delete a prepared statement from memory.
2770
2771 @note
2772 we don't send any reply to this command.
2773 */
2774
mysqld_stmt_close(THD * thd,ulong stmt_id)2775 void mysqld_stmt_close(THD *thd, ulong stmt_id)
2776 {
2777 Prepared_statement *stmt;
2778 DBUG_ENTER("mysqld_stmt_close");
2779
2780 thd->get_stmt_da()->disable_status();
2781
2782 if (!(stmt= thd->stmt_map.find(stmt_id)))
2783 DBUG_VOID_RETURN;
2784
2785 /*
2786 The only way currently a statement can be deallocated when it's
2787 in use is from within Dynamic SQL.
2788 */
2789 assert(! stmt->is_in_use());
2790 MYSQL_DESTROY_PS(stmt->m_prepared_stmt);
2791 stmt->deallocate();
2792 query_logger.general_log_print(thd, thd->get_command(), NullS);
2793
2794 DBUG_VOID_RETURN;
2795 }
2796
2797
2798 /**
2799 SQLCOM_DEALLOCATE implementation.
2800
2801 Close an SQL prepared statement. As this can be called from Dynamic
2802 SQL, we should be careful to not close a statement that is currently
2803 being executed.
2804
2805 @return
2806 none: OK packet is sent in case of success, otherwise an error
2807 message is set in THD
2808 */
2809
mysql_sql_stmt_close(THD * thd)2810 void mysql_sql_stmt_close(THD *thd)
2811 {
2812 Prepared_statement* stmt;
2813 const LEX_CSTRING &name= thd->lex->prepared_stmt_name;
2814 DBUG_PRINT("info", ("DEALLOCATE PREPARE: %.*s\n", (int) name.length,
2815 name.str));
2816
2817 if (! (stmt= thd->stmt_map.find_by_name(name)))
2818 my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0),
2819 static_cast<int>(name.length), name.str, "DEALLOCATE PREPARE");
2820 else if (stmt->is_in_use())
2821 my_error(ER_PS_NO_RECURSION, MYF(0));
2822 else
2823 {
2824 MYSQL_DESTROY_PS(stmt->m_prepared_stmt);
2825 stmt->deallocate();
2826 if (thd->session_tracker.get_tracker(SESSION_STATE_CHANGE_TRACKER)->is_enabled())
2827 thd->session_tracker.get_tracker(SESSION_STATE_CHANGE_TRACKER)->mark_as_changed(thd, NULL);
2828 my_ok(thd);
2829 }
2830 }
2831
2832
2833 /**
2834 Handle long data in pieces from client.
2835
2836 Get a part of a long data. To make the protocol efficient, we are
2837 not sending any return packets here. If something goes wrong, then
2838 we will send the error on 'execute' We assume that the client takes
2839 care of checking that all parts are sent to the server. (No checking
2840 that we get a 'end of column' in the server is performed).
2841
2842 @param thd Thread handle
2843 @param stmt_id Stmt id
2844 @param param_number Number of parameters
2845 @param str String to append
2846 @param length Length of string (including end \\0)
2847 */
2848
mysql_stmt_get_longdata(THD * thd,ulong stmt_id,uint param_number,uchar * str,ulong length)2849 void mysql_stmt_get_longdata(THD *thd, ulong stmt_id, uint param_number,
2850 uchar *str, ulong length)
2851 {
2852 Prepared_statement *stmt;
2853 Item_param *param;
2854 DBUG_ENTER("mysql_stmt_get_longdata");
2855
2856 thd->status_var.com_stmt_send_long_data++;
2857
2858 thd->get_stmt_da()->disable_status();
2859
2860 if (!(stmt=thd->stmt_map.find(stmt_id)))
2861 DBUG_VOID_RETURN;
2862
2863 #ifndef EMBEDDED_LIBRARY
2864 if (param_number >= stmt->param_count)
2865 {
2866 /* Error will be sent in execute call */
2867 stmt->state= Query_arena::STMT_ERROR;
2868 stmt->last_errno= ER_WRONG_ARGUMENTS;
2869 sprintf(stmt->last_error, ER(ER_WRONG_ARGUMENTS),
2870 "mysqld_stmt_send_long_data");
2871 DBUG_VOID_RETURN;
2872 }
2873 #endif
2874
2875 param= stmt->param_array[param_number];
2876
2877 Diagnostics_area new_stmt_da(false);
2878 thd->push_diagnostics_area(&new_stmt_da);
2879
2880 #ifndef EMBEDDED_LIBRARY
2881 param->set_longdata((char*)str, length);
2882 #else
2883 param->set_longdata(thd->extra_data, thd->extra_length);
2884 #endif
2885 if (thd->get_stmt_da()->is_error())
2886 {
2887 stmt->state= Query_arena::STMT_ERROR;
2888 stmt->last_errno= thd->get_stmt_da()->mysql_errno();
2889 my_snprintf(stmt->last_error, sizeof(stmt->last_error), "%.*s",
2890 MYSQL_ERRMSG_SIZE - 1, thd->get_stmt_da()->message_text());
2891 }
2892 thd->pop_diagnostics_area();
2893
2894 query_logger.general_log_print(thd, thd->get_command(), NullS);
2895
2896 DBUG_VOID_RETURN;
2897 }
2898
2899
2900 /***************************************************************************
2901 Select_fetch_protocol_binary
2902 ****************************************************************************/
2903
Query_fetch_protocol_binary(THD * thd_arg)2904 Query_fetch_protocol_binary::Query_fetch_protocol_binary(THD *thd_arg)
2905 :protocol(thd_arg)
2906 {}
2907
send_result_set_metadata(List<Item> & list,uint flags)2908 bool Query_fetch_protocol_binary::send_result_set_metadata(List<Item> &list,
2909 uint flags)
2910 {
2911 bool rc;
2912 Protocol *save_protocol= thd->get_protocol();
2913
2914 protocol.set_client_capabilities(
2915 thd->get_protocol()->get_client_capabilities());
2916 /*
2917 Protocol::send_result_set_metadata caches the information about column types:
2918 this information is later used to send data. Therefore, the same
2919 dedicated Protocol object must be used for all operations with
2920 a cursor.
2921 */
2922 thd->set_protocol(&protocol);
2923 rc= Query_result_send::send_result_set_metadata(list, flags);
2924 thd->set_protocol(save_protocol);
2925
2926 return rc;
2927 }
2928
send_eof()2929 bool Query_fetch_protocol_binary::send_eof()
2930 {
2931 /*
2932 Don't send EOF if we're in error condition (which implies we've already
2933 sent or are sending an error)
2934 */
2935 if (thd->is_error())
2936 return true;
2937
2938 ::my_eof(thd);
2939 return false;
2940 }
2941
2942
send_data(List<Item> & fields)2943 bool Query_fetch_protocol_binary::send_data(List<Item> &fields)
2944 {
2945 Protocol *save_protocol= thd->get_protocol();
2946 bool rc;
2947
2948 // set the current client capabilities before switching the protocol
2949 protocol.set_client_capabilities(
2950 thd->get_protocol()->get_client_capabilities());
2951 thd->set_protocol(&protocol);
2952 rc= Query_result_send::send_data(fields);
2953 thd->set_protocol(save_protocol);
2954 return rc;
2955 }
2956
2957 /*******************************************************************
2958 * Reprepare_observer
2959 *******************************************************************/
2960 /** Push an error to the error stack and return TRUE for now. */
2961
2962 bool
report_error(THD * thd)2963 Reprepare_observer::report_error(THD *thd)
2964 {
2965 /*
2966 This 'error' is purely internal to the server:
2967 - No exception handler is invoked,
2968 - No condition is added in the condition area (warn_list).
2969 The Diagnostics Area is set to an error status to enforce
2970 that this thread execution stops and returns to the caller,
2971 backtracking all the way to Prepared_statement::execute_loop().
2972
2973 As the DA has not yet been reset at this point, we'll need to
2974 reset the previous statement's result status first.
2975 Test with rpl_sp_effects and friends.
2976 */
2977 thd->get_stmt_da()->reset_diagnostics_area();
2978 thd->get_stmt_da()->set_error_status(ER_NEED_REPREPARE);
2979 m_invalidated= TRUE;
2980 m_attempt++;
2981
2982 return TRUE;
2983 }
2984
2985
2986 /*******************************************************************
2987 * Server_runnable
2988 *******************************************************************/
2989
~Server_runnable()2990 Server_runnable::~Server_runnable()
2991 {
2992 }
2993
2994 ///////////////////////////////////////////////////////////////////////////
2995
2996 Execute_sql_statement::
Execute_sql_statement(LEX_STRING sql_text)2997 Execute_sql_statement(LEX_STRING sql_text)
2998 :m_sql_text(sql_text)
2999 {}
3000
3001
3002 /**
3003 Parse and execute a statement. Does not prepare the query.
3004
3005 Allows to execute a statement from within another statement.
3006 The main property of the implementation is that it does not
3007 affect the environment -- i.e. you can run many
3008 executions without having to cleanup/reset THD in between.
3009 */
3010
3011 bool
execute_server_code(THD * thd)3012 Execute_sql_statement::execute_server_code(THD *thd)
3013 {
3014 sql_digest_state *parent_digest;
3015 PSI_statement_locker *parent_locker;
3016 bool error;
3017
3018 if (alloc_query(thd, m_sql_text.str, m_sql_text.length))
3019 return TRUE;
3020
3021 Parser_state parser_state;
3022 if (parser_state.init(thd, thd->query().str, thd->query().length))
3023 return TRUE;
3024
3025 parser_state.m_lip.multi_statements= FALSE;
3026 lex_start(thd);
3027
3028 parent_digest= thd->m_digest;
3029 parent_locker= thd->m_statement_psi;
3030 thd->m_digest= NULL;
3031 thd->m_statement_psi= NULL;
3032 error= parse_sql(thd, &parser_state, NULL) || thd->is_error();
3033 thd->m_digest= parent_digest;
3034 thd->m_statement_psi= parent_locker;
3035
3036 if (error)
3037 goto end;
3038
3039 thd->lex->set_trg_event_type_for_tables();
3040
3041 parent_locker= thd->m_statement_psi;
3042 thd->m_statement_psi= NULL;
3043
3044 /*
3045 Rewrite first (if needed); execution might replace passwords
3046 with hashes in situ without flagging it, and then we'd make
3047 a hash of that hash.
3048 */
3049 rewrite_query_if_needed(thd);
3050 log_execute_line(thd);
3051
3052 error= mysql_execute_command(thd) ;
3053 thd->m_statement_psi= parent_locker;
3054
3055 end:
3056 lex_end(thd->lex);
3057
3058 return error;
3059 }
3060
3061 /***************************************************************************
3062 Prepared_statement
3063 ****************************************************************************/
3064
Prepared_statement(THD * thd_arg)3065 Prepared_statement::Prepared_statement(THD *thd_arg)
3066 :Query_arena(&main_mem_root, STMT_INITIALIZED),
3067 thd(thd_arg),
3068 param_array(NULL),
3069 cursor(NULL),
3070 param_count(0),
3071 last_errno(0),
3072 id(++thd_arg->statement_id_counter),
3073 lex(NULL),
3074 m_query_string(NULL_CSTR),
3075 m_prepared_stmt(NULL),
3076 result(thd_arg),
3077 flags((uint) IS_IN_USE),
3078 with_log(false),
3079 m_name(NULL_CSTR),
3080 m_db(NULL_CSTR)
3081 {
3082 init_sql_alloc(key_memory_prepared_statement_main_mem_root,
3083 &main_mem_root, thd_arg->variables.query_alloc_block_size,
3084 thd_arg->variables.query_prealloc_size);
3085 *last_error= '\0';
3086 }
3087
3088
close_cursor()3089 void Prepared_statement::close_cursor()
3090 {
3091 delete cursor;
3092 cursor= NULL;
3093 }
3094
3095
setup_set_params()3096 void Prepared_statement::setup_set_params()
3097 {
3098 /*
3099 Note: BUG#25843 applies here too (query cache lookup uses thd->db, not
3100 db from "prepare" time).
3101 */
3102 if (thd->variables.query_cache_type == 0 ||
3103 query_cache.query_cache_size == 0) // we won't expand the query
3104 lex->safe_to_cache_query= FALSE; // so don't cache it at Execution
3105
3106 /*
3107 Decide if we have to expand the query (because we must write it to logs or
3108 because we want to look it up in the query cache) or not.
3109 We don't have to substitute the params when bin-logging DML in RBL.
3110 */
3111 if ((mysql_bin_log.is_open() && is_update_query(lex->sql_command) &&
3112 (!thd->is_current_stmt_binlog_format_row() ||
3113 ((sql_command_flags[lex->sql_command] & CF_AUTO_COMMIT_TRANS) ==
3114 CF_AUTO_COMMIT_TRANS))) ||
3115 opt_general_log || opt_slow_log ||
3116 (lex->sql_command == SQLCOM_SELECT &&
3117 lex->safe_to_cache_query &&
3118 !lex->describe)
3119 #ifndef EMBEDDED_LIBRARY
3120 || is_global_audit_mask_set()
3121 #endif
3122 )
3123 {
3124 with_log= true;
3125 }
3126 }
3127
3128
3129 /**
3130 Destroy this prepared statement, cleaning up all used memory
3131 and resources.
3132
3133 This is called from ::deallocate() to handle COM_STMT_CLOSE and
3134 DEALLOCATE PREPARE or when THD ends and all prepared statements are freed.
3135 */
3136
~Prepared_statement()3137 Prepared_statement::~Prepared_statement()
3138 {
3139 DBUG_ENTER("Prepared_statement::~Prepared_statement");
3140 DBUG_PRINT("enter",("stmt: 0x%lx cursor: 0x%lx",
3141 (long) this, (long) cursor));
3142 delete cursor;
3143 /*
3144 We have to call free on the items even if cleanup is called as some items,
3145 like Item_param, don't free everything until free_items()
3146 */
3147 free_items();
3148 if (lex)
3149 {
3150 assert(lex->sphead == NULL);
3151 lex_end(lex);
3152 delete lex->result;
3153 delete (st_lex_local *) lex; // TRASH memory
3154 }
3155 free_root(&main_mem_root, MYF(0));
3156 DBUG_VOID_RETURN;
3157 }
3158
3159
cleanup_stmt()3160 void Prepared_statement::cleanup_stmt()
3161 {
3162 DBUG_ENTER("Prepared_statement::cleanup_stmt");
3163 DBUG_PRINT("enter",("stmt: 0x%lx", (long) this));
3164
3165 cleanup_items(free_list);
3166 thd->cleanup_after_query();
3167 thd->rollback_item_tree_changes();
3168
3169 DBUG_VOID_RETURN;
3170 }
3171
3172
set_name(const LEX_CSTRING & name_arg)3173 bool Prepared_statement::set_name(const LEX_CSTRING &name_arg)
3174 {
3175 m_name.length= name_arg.length;
3176 m_name.str= static_cast<char*>(memdup_root(mem_root, name_arg.str,
3177 name_arg.length));
3178 return m_name.str == NULL;
3179 }
3180
3181
3182 /**
3183 Remember the current database.
3184
3185 We must reset/restore the current database during execution of
3186 a prepared statement since it affects execution environment:
3187 privileges, @@character_set_database, and other.
3188
3189 @return Returns an error if out of memory.
3190 */
3191
3192 bool
set_db(const LEX_CSTRING & db_arg)3193 Prepared_statement::set_db(const LEX_CSTRING &db_arg)
3194 {
3195 /* Remember the current database. */
3196 if (db_arg.str && db_arg.length)
3197 {
3198 m_db.str= this->strmake(db_arg.str, db_arg.length);
3199 m_db.length= db_arg.length;
3200 }
3201 else
3202 {
3203 m_db= NULL_CSTR;
3204 }
3205 return db_arg.str != NULL && m_db.str == NULL;
3206 }
3207
3208 /**************************************************************************
3209 Common parts of mysql_[sql]_stmt_prepare, mysql_[sql]_stmt_execute.
3210 Essentially, these functions do all the magic of preparing/executing
3211 a statement, leaving network communication, input data handling and
3212 global THD state management to the caller.
3213 ***************************************************************************/
3214
3215
3216 /**
3217 Parse statement text, validate the statement, and prepare it for execution.
3218
3219 You should not change global THD state in this function, if at all
3220 possible: it may be called from any context, e.g. when executing
3221 a COM_* command, and SQLCOM_* command, or a stored procedure.
3222
3223 @param query_str statement text
3224 @param query_length
3225
3226 @note
3227 Precondition:
3228 The caller must ensure that thd->change_list and thd->free_list
3229 is empty: this function will not back them up but will free
3230 in the end of its execution.
3231
3232 @note
3233 Postcondition:
3234 thd->mem_root contains unused memory allocated during validation.
3235 */
3236
prepare(const char * query_str,size_t query_length)3237 bool Prepared_statement::prepare(const char *query_str, size_t query_length)
3238 {
3239 bool error;
3240 Query_arena arena_backup;
3241 Query_arena *old_stmt_arena;
3242 sql_digest_state *parent_digest= thd->m_digest;
3243 PSI_statement_locker *parent_locker= thd->m_statement_psi;
3244 unsigned char *token_array= NULL;
3245
3246 DBUG_ENTER("Prepared_statement::prepare");
3247 /*
3248 If this is an SQLCOM_PREPARE, we also increase Com_prepare_sql.
3249 However, it seems handy if com_stmt_prepare is increased always,
3250 no matter what kind of prepare is processed.
3251 */
3252 thd->status_var.com_stmt_prepare++;
3253
3254 if (! (lex= new (mem_root) st_lex_local))
3255 DBUG_RETURN(TRUE);
3256
3257 if (set_db(thd->db()))
3258 DBUG_RETURN(TRUE);
3259
3260 /*
3261 alloc_query() uses thd->memroot && thd->query, so we should call
3262 both of backup_statement() and backup_query_arena() here.
3263 */
3264 Statement_backup stmt_backup;
3265 stmt_backup.set_thd_to_ps(thd, this);
3266 thd->set_n_backup_active_arena(this, &arena_backup);
3267
3268 if (alloc_query(thd, query_str, query_length))
3269 {
3270 stmt_backup.restore_thd(thd, this);
3271 thd->restore_active_arena(this, &arena_backup);
3272 DBUG_RETURN(TRUE);
3273 }
3274
3275 if (max_digest_length > 0)
3276 {
3277 token_array= (unsigned char*) thd->alloc(max_digest_length);
3278 }
3279
3280 old_stmt_arena= thd->stmt_arena;
3281 thd->stmt_arena= this;
3282
3283 Parser_state parser_state;
3284 if (parser_state.init(thd, thd->query().str, thd->query().length))
3285 {
3286 stmt_backup.restore_thd(thd, this);
3287 thd->restore_active_arena(this, &arena_backup);
3288 thd->stmt_arena= old_stmt_arena;
3289 DBUG_RETURN(TRUE);
3290 }
3291
3292 parser_state.m_lip.stmt_prepare_mode= TRUE;
3293 parser_state.m_lip.multi_statements= FALSE;
3294
3295 lex_start(thd);
3296 lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_PREPARE;
3297
3298 thd->m_digest= NULL;
3299 thd->m_statement_psi= NULL;
3300
3301 sql_digest_state digest;
3302 digest.reset(token_array, max_digest_length);
3303 thd->m_digest= &digest;
3304
3305 enable_digest_if_any_plugin_needs_it(thd, &parser_state);
3306 #ifndef EMBEDDED_LIBRARY
3307 if (is_audit_plugin_class_active(thd, MYSQL_AUDIT_GENERAL_CLASS))
3308 parser_state.m_input.m_compute_digest= true;
3309 #endif
3310
3311 thd->m_parser_state = &parser_state;
3312 invoke_pre_parse_rewrite_plugins(thd);
3313 thd->m_parser_state = NULL;
3314
3315 error= thd->is_error();
3316
3317 if (!error)
3318 {
3319 error = parse_sql(thd, &parser_state, NULL) ||
3320 thd->is_error() ||
3321 init_param_array(this);
3322
3323 if (!error)
3324 { // We've just created the statement maybe there is a rewrite
3325 invoke_post_parse_rewrite_plugins(thd, true);
3326 error = init_param_array(this);
3327 }
3328 }
3329
3330 lex->set_trg_event_type_for_tables();
3331
3332 /*
3333 Pre-clear the diagnostics area unless a warning was thrown
3334 during parsing.
3335 */
3336 if (thd->lex->keep_diagnostics != DA_KEEP_PARSE_ERROR)
3337 thd->get_stmt_da()->reset_condition_info(thd);
3338
3339 /*
3340 While doing context analysis of the query (in check_prepared_statement)
3341 we allocate a lot of additional memory: for open tables, JOINs, derived
3342 tables, etc. Let's save a snapshot of current parse tree to the
3343 statement and restore original THD. In cases when some tree
3344 transformation can be reused on execute, we set again thd->mem_root from
3345 stmt->mem_root (see setup_wild for one place where we do that).
3346 */
3347 thd->restore_active_arena(this, &arena_backup);
3348
3349 /*
3350 If called from a stored procedure, ensure that we won't rollback
3351 external changes when cleaning up after validation.
3352 */
3353 assert(thd->change_list.is_empty());
3354
3355 /*
3356 Marker used to release metadata locks acquired while the prepared
3357 statement is being checked.
3358 */
3359 MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint();
3360
3361 /*
3362 The only case where we should have items in the thd->free_list is
3363 after stmt->set_params_from_vars(), which may in some cases create
3364 Item_null objects.
3365 */
3366
3367 if (error == 0)
3368 error= check_prepared_statement(this);
3369
3370 /*
3371 Currently CREATE PROCEDURE/TRIGGER/EVENT are prohibited in prepared
3372 statements: ensure we have no memory leak here if by someone tries
3373 to PREPARE stmt FROM "CREATE PROCEDURE ..."
3374 */
3375 assert(lex->sphead == NULL || error != 0);
3376 /* The order is important */
3377 lex->unit->cleanup(true);
3378 lex->clear_values_map();
3379
3380 /* No need to commit statement transaction, it's not started. */
3381 assert(thd->get_transaction()->is_empty(Transaction_ctx::STMT));
3382
3383 close_thread_tables(thd);
3384 thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
3385
3386 /*
3387 Transaction rollback was requested since MDL deadlock was discovered
3388 while trying to open tables. Rollback transaction in all storage
3389 engines including binary log and release all locks.
3390
3391 Once dynamic SQL is allowed as substatements the below if-statement
3392 has to be adjusted to not do rollback in substatement.
3393 */
3394 assert(! thd->in_sub_stmt);
3395 if (thd->transaction_rollback_request)
3396 {
3397 trans_rollback_implicit(thd);
3398 thd->mdl_context.release_transactional_locks();
3399 }
3400
3401 lex_end(lex);
3402
3403 rewrite_query_if_needed(thd);
3404
3405 if (thd->rewritten_query().length())
3406 {
3407 MYSQL_SET_PS_TEXT(m_prepared_stmt,
3408 thd->rewritten_query().ptr(),
3409 thd->rewritten_query().length());
3410 }
3411 else
3412 {
3413 MYSQL_SET_PS_TEXT(m_prepared_stmt,
3414 thd->query().str,
3415 thd->query().length);
3416 }
3417
3418 cleanup_stmt();
3419 stmt_backup.restore_thd(thd, this);
3420 thd->stmt_arena= old_stmt_arena;
3421
3422 if (error == 0)
3423 {
3424 setup_set_params();
3425 lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_PREPARE;
3426 state= Query_arena::STMT_PREPARED;
3427 flags&= ~ (uint) IS_IN_USE;
3428
3429 /*
3430 Log COM_STMT_PREPARE to the general log. Note, that in case of SQL
3431 prepared statements this causes two records to be output:
3432
3433 Query PREPARE stmt from @user_variable
3434 Prepare <statement SQL text>
3435
3436 This is considered user-friendly, since in the second log Entry
3437 we output the actual statement text rather than the variable name.
3438
3439 Rewriting/password obfuscation:
3440
3441 - If we're preparing from a string literal rather than from a
3442 variable, the literal is elided in the "Query" log line, as
3443 it may contain a password. (As we've parsed the PREPARE statement,
3444 but not the statement to prepare yet, we don't know at that point.)
3445 Eliding the literal is fine, as we'll print it in the next log line
3446 ("Prepare"), anyway.
3447
3448 - Any passwords in the "Prepare" line should be substituted with their
3449 hashes, or a notice.
3450
3451 Do not print anything if this is an SQL prepared statement and
3452 we're inside a stored procedure (also called Dynamic SQL) --
3453 sub-statements inside stored procedures are not logged into
3454 the general log.
3455 */
3456 if (thd->sp_runtime_ctx == NULL)
3457 {
3458 if (thd->rewritten_query().length())
3459 query_logger.general_log_write(thd, COM_STMT_PREPARE,
3460 thd->rewritten_query().ptr(),
3461 thd->rewritten_query().length());
3462 else
3463 query_logger.general_log_write(thd, COM_STMT_PREPARE,
3464 m_query_string.str,
3465 m_query_string.length);
3466
3467 /* audit plugins can return an error */
3468 error |= thd->is_error();
3469 }
3470 }
3471 thd->m_digest= parent_digest;
3472
3473 thd->m_statement_psi= parent_locker;
3474
3475 DBUG_RETURN(error);
3476 }
3477
3478
3479 /**
3480 Assign parameter values either from variables, in case of SQL PS
3481 or from the execute packet.
3482
3483 @param expanded_query a container with the original SQL statement.
3484 '?' placeholders will be replaced with
3485 their values in case of success.
3486 The result is used for logging and replication
3487 @param packet pointer to execute packet.
3488 NULL in case of SQL PS
3489 @param packet_end end of the packet. NULL in case of SQL PS
3490
3491 @todo Use a paremeter source class family instead of 'if's, and
3492 support stored procedure variables.
3493
3494 @retval TRUE an error occurred when assigning a parameter (likely
3495 a conversion error or out of memory, or malformed packet)
3496 @retval FALSE success
3497 */
3498
3499 bool
set_parameters(String * expanded_query,uchar * packet,uchar * packet_end)3500 Prepared_statement::set_parameters(String *expanded_query,
3501 uchar *packet, uchar *packet_end)
3502 {
3503 bool is_sql_ps= packet == NULL;
3504 bool res= FALSE;
3505
3506 if (is_sql_ps)
3507 {
3508 /* SQL prepared statement */
3509 res= insert_params_from_vars(thd->lex->prepared_stmt_params,
3510 expanded_query);
3511 }
3512 else if (param_count)
3513 {
3514 #ifndef EMBEDDED_LIBRARY
3515 uchar *null_array= packet;
3516 res= (setup_conversion_functions(this, &packet, packet_end) ||
3517 insert_params(null_array, packet, packet_end, expanded_query));
3518 #else
3519 /*
3520 In embedded library we re-install conversion routines each time
3521 we set parameters, and also we don't need to parse packet.
3522 So we do it in one function.
3523 */
3524 res= emb_insert_params(expanded_query);
3525 #endif
3526 }
3527 if (res)
3528 {
3529 my_error(ER_WRONG_ARGUMENTS, MYF(0),
3530 is_sql_ps ? "EXECUTE" : "mysqld_stmt_execute");
3531 reset_stmt_params(this);
3532 }
3533 return res;
3534 }
3535
3536 #ifdef WITH_WSREP
3537 void wsrep_replay_transaction(THD *thd);
3538 #endif /* WITH_WSREP */
3539 /**
3540 Execute a prepared statement. Re-prepare it a limited number
3541 of times if necessary.
3542
3543 Try to execute a prepared statement. If there is a metadata
3544 validation error, prepare a new copy of the prepared statement,
3545 swap the old and the new statements, and try again.
3546 If there is a validation error again, repeat the above, but
3547 perform not more than a maximum number of times. Reprepare_observer
3548 ensures that a prepared statement execution is retried not more than a
3549 maximum number of times.
3550
3551 @note We have to try several times in a loop since we
3552 release metadata locks on tables after prepared statement
3553 prepare. Therefore, a DDL statement may sneak in between prepare
3554 and execute of a new statement. If a prepared statement execution
3555 is retried for a maximum number of times then we give up.
3556
3557
3558 @return TRUE if an error, FALSE if success
3559 @retval TRUE either statement execution is retried for
3560 a maximum number of times or some general error.
3561 @retval FALSE successfully executed the statement, perhaps
3562 after having reprepared it a few times.
3563 */
3564
3565 bool
execute_loop(String * expanded_query,bool open_cursor,uchar * packet,uchar * packet_end)3566 Prepared_statement::execute_loop(String *expanded_query,
3567 bool open_cursor,
3568 uchar *packet,
3569 uchar *packet_end)
3570 {
3571 Reprepare_observer reprepare_observer;
3572 bool error;
3573
3574 /* Check if we got an error when sending long data */
3575 if (state == Query_arena::STMT_ERROR)
3576 {
3577 my_message(last_errno, last_error, MYF(0));
3578 return TRUE;
3579 }
3580
3581 assert(!thd->get_stmt_da()->is_set());
3582
3583 if (set_parameters(expanded_query, packet, packet_end))
3584 return TRUE;
3585
3586 if (unlikely(thd->security_context()->password_expired() &&
3587 !lex->is_set_password_sql))
3588 {
3589 my_error(ER_MUST_CHANGE_PASSWORD, MYF(0));
3590 return true;
3591 }
3592
3593 reexecute:
3594 /*
3595 If the free_list is not empty, we'll wrongly free some externally
3596 allocated items when cleaning up after validation of the prepared
3597 statement.
3598 */
3599 assert(thd->free_list == NULL);
3600
3601 /*
3602 Install the metadata observer. If some metadata version is
3603 different from prepare time and an observer is installed,
3604 the observer method will be invoked to push an error into
3605 the error stack.
3606 */
3607 Reprepare_observer *stmt_reprepare_observer= NULL;
3608
3609 if (sql_command_flags[lex->sql_command] & CF_REEXECUTION_FRAGILE)
3610 {
3611 reprepare_observer.reset_reprepare_observer();
3612 stmt_reprepare_observer = &reprepare_observer;
3613 }
3614
3615 thd->push_reprepare_observer(stmt_reprepare_observer);
3616
3617 error= execute(expanded_query, open_cursor) || thd->is_error();
3618
3619 #ifdef WITH_WSREP
3620 bool observer_popped = false;
3621 mysql_mutex_lock(&thd->LOCK_wsrep_thd);
3622 switch (thd->wsrep_conflict_state)
3623 {
3624 case CERT_FAILURE:
3625 WSREP_DEBUG("PS execute fail for CERT_FAILURE: thd: %u err: %d",
3626 thd->thread_id(), thd->get_stmt_da()->mysql_errno() );
3627 thd->wsrep_conflict_state = NO_CONFLICT;
3628 mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
3629 break;
3630
3631 case MUST_REPLAY:
3632 thd->pop_reprepare_observer();
3633 observer_popped= true;
3634 (void)wsrep_replay_transaction(thd);
3635 thd->wsrep_conflict_state= REPLAYED;
3636 mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
3637 break;
3638 default:
3639 mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
3640 break;
3641 }
3642 if (!observer_popped)
3643 {
3644 #endif /* WITH_WSREP */
3645 thd->pop_reprepare_observer();
3646 #ifdef WITH_WSREP
3647 }
3648 #endif /* WITH_WSREP */
3649
3650 if ((sql_command_flags[lex->sql_command] & CF_REEXECUTION_FRAGILE) &&
3651 error && !thd->is_fatal_error && !thd->killed &&
3652 reprepare_observer.is_invalidated() &&
3653 reprepare_observer.can_retry())
3654 {
3655 assert(thd->get_stmt_da()->mysql_errno() == ER_NEED_REPREPARE);
3656 thd->clear_error();
3657
3658 error= reprepare();
3659
3660 if (! error) /* Success */
3661 goto reexecute;
3662 }
3663 reset_stmt_params(this);
3664
3665 return error;
3666 }
3667
3668
3669 bool
execute_server_runnable(Server_runnable * server_runnable)3670 Prepared_statement::execute_server_runnable(Server_runnable *server_runnable)
3671 {
3672 Query_arena arena_backup;
3673 bool error;
3674 Query_arena *save_stmt_arena= thd->stmt_arena;
3675 Item_change_list save_change_list;
3676 thd->change_list.move_elements_to(&save_change_list);
3677
3678 state= STMT_CONVENTIONAL_EXECUTION;
3679
3680 if (!(lex= new (mem_root) st_lex_local))
3681 return TRUE;
3682
3683 Statement_backup stmt_backup;
3684 stmt_backup.set_thd_to_ps(thd, this);
3685 thd->set_n_backup_active_arena(this, &arena_backup);
3686 thd->stmt_arena= this;
3687
3688 error= server_runnable->execute_server_code(thd);
3689
3690 thd->cleanup_after_query();
3691
3692 thd->restore_active_arena(this, &arena_backup);
3693 stmt_backup.restore_thd(thd, this);
3694 thd->stmt_arena= save_stmt_arena;
3695
3696 save_change_list.move_elements_to(&thd->change_list);
3697
3698 /* Items and memory will freed in destructor */
3699
3700 return error;
3701 }
3702
3703
3704 /**
3705 Reprepare this prepared statement.
3706
3707 Currently this is implemented by creating a new prepared
3708 statement, preparing it with the original query and then
3709 swapping the new statement and the original one.
3710
3711 @retval TRUE an error occurred. Possible errors include
3712 incompatibility of new and old result set
3713 metadata
3714 @retval FALSE success, the statement has been reprepared
3715 */
3716
3717 bool
reprepare()3718 Prepared_statement::reprepare()
3719 {
3720 char saved_cur_db_name_buf[NAME_LEN+1];
3721 LEX_STRING saved_cur_db_name=
3722 { saved_cur_db_name_buf, sizeof(saved_cur_db_name_buf) };
3723 bool cur_db_changed;
3724 bool error;
3725
3726 Prepared_statement copy(thd);
3727
3728 copy.set_sql_prepare(); /* To suppress sending metadata to the client. */
3729
3730 thd->status_var.com_stmt_reprepare++;
3731
3732 if (mysql_opt_change_db(thd, m_db, &saved_cur_db_name, TRUE,
3733 &cur_db_changed))
3734 return TRUE;
3735
3736 error= ((m_name.str && copy.set_name(m_name)) ||
3737 copy.prepare(m_query_string.str, m_query_string.length) ||
3738 validate_metadata(©));
3739
3740 if (cur_db_changed)
3741 mysql_change_db(thd, to_lex_cstring(saved_cur_db_name), TRUE);
3742
3743 if (! error)
3744 {
3745 copy.m_prepared_stmt= m_prepared_stmt;
3746 /* Update reprepare count for this prepared statement in P_S table. */
3747 MYSQL_REPREPARE_PS(copy.m_prepared_stmt);
3748
3749 swap_prepared_statement(©);
3750 swap_parameter_array(param_array, copy.param_array, param_count);
3751 #ifndef NDEBUG
3752 is_reprepared= TRUE;
3753 #endif
3754 /*
3755 Clear possible warnings during reprepare, it has to be completely
3756 transparent to the user. We use clear_warning_info() since
3757 there were no separate query id issued for re-prepare.
3758 Sic: we can't simply silence warnings during reprepare, because if
3759 it's failed, we need to return all the warnings to the user.
3760 */
3761 thd->get_stmt_da()->reset_condition_info(thd);
3762 }
3763 return error;
3764 }
3765
3766
3767 /**
3768 Validate statement result set metadata (if the statement returns
3769 a result set).
3770
3771 Currently we only check that the number of columns of the result
3772 set did not change.
3773 This is a helper method used during re-prepare.
3774
3775 @param[in] copy the re-prepared prepared statement to verify
3776 the metadata of
3777
3778 @retval TRUE error, ER_PS_REBIND is reported
3779 @retval FALSE statement return no or compatible metadata
3780 */
3781
3782
validate_metadata(Prepared_statement * copy)3783 bool Prepared_statement::validate_metadata(Prepared_statement *copy)
3784 {
3785 /**
3786 If this is an SQL prepared statement or EXPLAIN,
3787 return FALSE -- the metadata of the original SELECT,
3788 if any, has not been sent to the client.
3789 */
3790 if (is_sql_prepare() || lex->describe)
3791 return FALSE;
3792
3793 if (lex->select_lex->item_list.elements !=
3794 copy->lex->select_lex->item_list.elements)
3795 {
3796 /** Column counts mismatch, update the client */
3797 thd->server_status|= SERVER_STATUS_METADATA_CHANGED;
3798 }
3799
3800 return FALSE;
3801 }
3802
3803
3804 /**
3805 Replace the original prepared statement with a prepared copy.
3806
3807 This is a private helper that is used as part of statement
3808 reprepare
3809
3810 @return This function does not return any errors.
3811 */
3812
3813 void
swap_prepared_statement(Prepared_statement * copy)3814 Prepared_statement::swap_prepared_statement(Prepared_statement *copy)
3815 {
3816 Query_arena tmp_arena;
3817
3818 /* Swap memory roots. */
3819 swap_variables(MEM_ROOT, main_mem_root, copy->main_mem_root);
3820
3821 /* Swap the arenas */
3822 tmp_arena.set_query_arena(this);
3823 set_query_arena(copy);
3824 copy->set_query_arena(&tmp_arena);
3825
3826 /* Swap the statement attributes */
3827 swap_variables(LEX *, lex, copy->lex);
3828 swap_variables(LEX_CSTRING, m_query_string, copy->m_query_string);
3829
3830 /* Swap mem_roots back, they must continue pointing at the main_mem_roots */
3831 swap_variables(MEM_ROOT *, mem_root, copy->mem_root);
3832 /*
3833 Swap the old and the new parameters array. The old array
3834 is allocated in the old arena.
3835 */
3836 swap_variables(Item_param **, param_array, copy->param_array);
3837 /* Don't swap flags: the copy has IS_SQL_PREPARE always set. */
3838 /* swap_variables(uint, flags, copy->flags); */
3839 /* Swap names, the old name is allocated in the wrong memory root */
3840 swap_variables(LEX_CSTRING, m_name, copy->m_name);
3841 /* Ditto */
3842 swap_variables(LEX_CSTRING, m_db, copy->m_db);
3843
3844 assert(param_count == copy->param_count);
3845 assert(thd == copy->thd);
3846 last_error[0]= '\0';
3847 last_errno= 0;
3848 }
3849
3850
3851 /**
3852 Execute a prepared statement.
3853
3854 You should not change global THD state in this function, if at all
3855 possible: it may be called from any context, e.g. when executing
3856 a COM_* command, and SQLCOM_* command, or a stored procedure.
3857
3858 @param expanded_query A query for binlogging which has all parameter
3859 markers ('?') replaced with their actual values.
3860 @param open_cursor True if an attempt to open a cursor should be made.
3861 Currenlty used only in the binary protocol.
3862
3863 @note
3864 Preconditions, postconditions.
3865 - See the comment for Prepared_statement::prepare().
3866
3867 @retval
3868 FALSE ok
3869 @retval
3870 TRUE Error
3871 */
3872
execute(String * expanded_query,bool open_cursor)3873 bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
3874 {
3875 Query_arena *old_stmt_arena;
3876 char saved_cur_db_name_buf[NAME_LEN+1];
3877 LEX_STRING saved_cur_db_name=
3878 { saved_cur_db_name_buf, sizeof(saved_cur_db_name_buf) };
3879 bool cur_db_changed;
3880
3881 thd->status_var.com_stmt_execute++;
3882
3883 /*
3884 Reset the diagnostics area.
3885
3886 For regular statements, this would have happened in the parsing
3887 stage.
3888
3889 SQL prepared statements (SQLCOM_EXECUTE) also have a parsing
3890 stage first (where we find out it's EXECUTE ... [USING ...]).
3891
3892 However, ps-protocol prepared statements have no parsing stage for
3893 COM_STMT_EXECUTE before coming here, so we reset the condition info
3894 here. Since diagnostics statements can't be prepared, we don't need
3895 to make an exception for them.
3896 */
3897 thd->get_stmt_da()->reset_condition_info(thd);
3898
3899 if (flags & (uint) IS_IN_USE)
3900 {
3901 my_error(ER_PS_NO_RECURSION, MYF(0));
3902 return TRUE;
3903 }
3904
3905 /*
3906 For SHOW VARIABLES lex->result is NULL, as it's a non-SELECT
3907 command. For such queries we don't return an error and don't
3908 open a cursor -- the client library will recognize this case and
3909 materialize the result set.
3910 For SELECT statements lex->result is created in
3911 check_prepared_statement. lex->result->simple_select() is FALSE
3912 in INSERT ... SELECT and similar commands.
3913 */
3914
3915 if (open_cursor && lex->result && lex->result->check_simple_select())
3916 {
3917 DBUG_PRINT("info",("Cursor asked for not SELECT stmt"));
3918 return TRUE;
3919 }
3920
3921 /* In case the command has a call to SP which re-uses this statement name */
3922 flags|= IS_IN_USE;
3923
3924 close_cursor();
3925
3926 /*
3927 If the free_list is not empty, we'll wrongly free some externally
3928 allocated items when cleaning up after execution of this statement.
3929 */
3930 assert(thd->change_list.is_empty());
3931
3932 /*
3933 The only case where we should have items in the thd->free_list is
3934 after stmt->set_params_from_vars(), which may in some cases create
3935 Item_null objects.
3936 */
3937
3938 Statement_backup stmt_backup;
3939 stmt_backup.set_thd_to_ps(thd, this);
3940
3941 /*
3942 Change the current database (if needed).
3943
3944 Force switching, because the database of the prepared statement may be
3945 NULL (prepared statements can be created while no current database
3946 selected).
3947 */
3948 if (mysql_opt_change_db(thd, m_db, &saved_cur_db_name, TRUE,
3949 &cur_db_changed))
3950 {
3951 flags&= ~ (uint) IS_IN_USE;
3952 mysql_mutex_lock(&thd->LOCK_thd_data);
3953 thd->lex= stmt_backup.lex();
3954 mysql_mutex_unlock(&thd->LOCK_thd_data);
3955 return TRUE;
3956 }
3957
3958 /* Allocate query. */
3959
3960 if (expanded_query->length() &&
3961 alloc_query(thd, (char*) expanded_query->ptr(),
3962 expanded_query->length()))
3963 {
3964 my_error(ER_OUTOFMEMORY, MYF(ME_FATALERROR), expanded_query->length());
3965 flags&= ~ (uint) IS_IN_USE;
3966 mysql_mutex_lock(&thd->LOCK_thd_data);
3967 thd->lex= stmt_backup.lex();
3968 mysql_mutex_unlock(&thd->LOCK_thd_data);
3969 return TRUE;
3970 }
3971
3972 /*
3973 At first execution of prepared statement we may perform logical
3974 transformations of the query tree. Such changes should be performed
3975 on the parse tree of current prepared statement and new items should
3976 be allocated in its memory root. Set the appropriate pointer in THD
3977 to the arena of the statement.
3978 */
3979 old_stmt_arena= thd->stmt_arena;
3980 thd->stmt_arena= this;
3981 bool error= reinit_stmt_before_use(thd, lex);
3982
3983 /*
3984 Set a hint so mysql_execute_command() won't clear the DA *again*,
3985 thereby discarding any conditions we might raise in here
3986 (e.g. "database we prepared with no longer exists", ER_BAD_DB_ERROR).
3987 */
3988 thd->lex->keep_diagnostics= DA_KEEP_PARSE_ERROR;
3989
3990 if (!error)
3991 {
3992 // Execute
3993
3994 if (open_cursor)
3995 {
3996 lex->safe_to_cache_query= 0;
3997 error= mysql_open_cursor(thd, &result, &cursor);
3998 }
3999 else
4000 {
4001 /*
4002 Try to find it in the query cache, if not, execute it.
4003 Note that multi-statements cannot exist here (they are not supported in
4004 prepared statements).
4005 */
4006 if (query_cache.send_result_to_client(thd, thd->query()) <= 0)
4007 {
4008 MYSQL_QUERY_EXEC_START(const_cast<char*>(thd->query().str),
4009 thd->thread_id(),
4010 (char *) (thd->db().str != NULL ?
4011 thd->db().str : ""),
4012 (char *) thd->security_context()->priv_user().str,
4013 (char *) thd->security_context()->host_or_ip().str,
4014 1);
4015
4016 /*
4017 Log COM_STMT_EXECUTE to the general log. Note, that in case of SQL
4018 prepared statements this causes two records to be output:
4019
4020 Query EXECUTE <statement name>
4021 Execute <statement SQL text>
4022
4023 This is considered user-friendly, since in the
4024 second log entry we output values of parameter markers.
4025
4026 Rewriting/password obfuscation:
4027
4028 - Any passwords in the "Execute" line should be substituted with
4029 their hashes, or a notice.
4030
4031 Rewrite first (if needed); execution might replace passwords
4032 with hashes in situ without flagging it, and then we'd make
4033 a hash of that hash.
4034 */
4035 rewrite_query_if_needed(thd);
4036 log_execute_line(thd);
4037 thd->binlog_need_explicit_defaults_ts= lex->binlog_need_explicit_defaults_ts;
4038 error= mysql_execute_command(thd, true);
4039 MYSQL_QUERY_EXEC_DONE(error);
4040 }
4041 }
4042 }
4043
4044 /*
4045 Restore the current database (if changed).
4046
4047 Force switching back to the saved current database (if changed),
4048 because it may be NULL. In this case, mysql_change_db() would generate
4049 an error.
4050 */
4051
4052 if (cur_db_changed)
4053 mysql_change_db(thd, to_lex_cstring(saved_cur_db_name), true);
4054
4055 /* Assert that if an error, no cursor is open */
4056 assert(! (error && cursor));
4057
4058 if (! cursor)
4059 cleanup_stmt();
4060
4061 thd->lex->release_plugins();
4062
4063 /*
4064 Expanded query is needed for slow logging, so we want thd->query
4065 to point at it even after we restore from backup. This is ok, as
4066 expanded query was allocated in thd->mem_root.
4067 */
4068 mysql_mutex_lock(&thd->LOCK_thd_data);
4069 thd->lex= stmt_backup.lex();
4070
4071 mysql_mutex_unlock(&thd->LOCK_thd_data);
4072
4073 thd->stmt_arena= old_stmt_arena;
4074
4075 if (state == Query_arena::STMT_PREPARED)
4076 state= Query_arena::STMT_EXECUTED;
4077
4078 if (error == 0 && this->lex->sql_command == SQLCOM_CALL)
4079 {
4080 if (is_sql_prepare())
4081 thd->protocol_text.send_out_parameters(&this->lex->param_list);
4082 else
4083 thd->get_protocol_classic()->send_out_parameters(&this->lex->param_list);
4084 }
4085
4086 flags&= ~ (uint) IS_IN_USE;
4087 return error;
4088 }
4089
4090
4091 /** Common part of DEALLOCATE PREPARE and mysqld_stmt_close. */
4092
deallocate()4093 void Prepared_statement::deallocate()
4094 {
4095 /* We account deallocate in the same manner as mysqld_stmt_close */
4096 thd->status_var.com_stmt_close++;
4097 /* Statement map calls delete stmt on erase */
4098 thd->stmt_map.erase(this);
4099 }
4100
4101
4102 /***************************************************************************
4103 * Ed_result_set
4104 ***************************************************************************/
4105 /**
4106 Use operator delete to free memory of Ed_result_set.
4107 Accessing members of a class after the class has been destroyed
4108 is a violation of the C++ standard but is commonly used in the
4109 server code.
4110 */
4111
operator delete(void * ptr,size_t size)4112 void Ed_result_set::operator delete(void *ptr, size_t size) throw ()
4113 {
4114 if (ptr)
4115 {
4116 /*
4117 Make a stack copy, otherwise free_root() will attempt to
4118 write to freed memory.
4119 */
4120 MEM_ROOT own_root= ((Ed_result_set*) ptr)->m_mem_root;
4121 free_root(&own_root, MYF(0));
4122 }
4123 }
4124
4125
4126 /**
4127 Initialize an instance of Ed_result_set.
4128
4129 Instances of the class, as well as all result set rows, are
4130 always allocated in the memory root passed over as the second
4131 argument. In the constructor, we take over ownership of the
4132 memory root. It will be freed when the class is destroyed.
4133
4134 sic: Ed_result_est is not designed to be allocated on stack.
4135 */
4136
Ed_result_set(List<Ed_row> * rows_arg,size_t column_count_arg,MEM_ROOT * mem_root_arg)4137 Ed_result_set::Ed_result_set(List<Ed_row> *rows_arg,
4138 size_t column_count_arg,
4139 MEM_ROOT *mem_root_arg)
4140 :m_mem_root(*mem_root_arg),
4141 m_column_count(column_count_arg),
4142 m_rows(rows_arg),
4143 m_next_rset(NULL)
4144 {
4145 /* Take over responsibility for the memory */
4146 clear_alloc_root(mem_root_arg);
4147 }
4148
4149 /***************************************************************************
4150 * Ed_result_set
4151 ***************************************************************************/
4152
4153 /**
4154 Create a new "execute direct" connection.
4155 */
4156
Ed_connection(THD * thd)4157 Ed_connection::Ed_connection(THD *thd)
4158 :m_diagnostics_area(false),
4159 m_thd(thd),
4160 m_rsets(0),
4161 m_current_rset(0)
4162 {
4163 }
4164
4165
4166 /**
4167 Free all result sets of the previous statement, if any,
4168 and reset warnings and errors.
4169
4170 Called before execution of the next query.
4171 */
4172
4173 void
free_old_result()4174 Ed_connection::free_old_result()
4175 {
4176 while (m_rsets)
4177 {
4178 Ed_result_set *rset= m_rsets->m_next_rset;
4179 delete m_rsets;
4180 m_rsets= rset;
4181 }
4182 m_current_rset= m_rsets;
4183 m_diagnostics_area.reset_diagnostics_area();
4184 m_diagnostics_area.reset_condition_info(m_thd);
4185 }
4186
4187
4188 /**
4189 A simple wrapper that uses a helper class to execute SQL statements.
4190 */
4191
4192 bool
execute_direct(LEX_STRING sql_text)4193 Ed_connection::execute_direct(LEX_STRING sql_text)
4194 {
4195 Execute_sql_statement execute_sql_statement(sql_text);
4196 DBUG_PRINT("ed_query", ("%s", sql_text.str));
4197
4198 return execute_direct(&execute_sql_statement);
4199 }
4200
4201
4202 /**
4203 Execute a fragment of server functionality without an effect on
4204 thd, and store results in memory.
4205
4206 Conventions:
4207 - the code fragment must finish with OK, EOF or ERROR.
4208 - the code fragment doesn't have to close thread tables,
4209 free memory, commit statement transaction or do any other
4210 cleanup that is normally done in the end of dispatch_command().
4211
4212 @param server_runnable A code fragment to execute.
4213 */
4214
execute_direct(Server_runnable * server_runnable)4215 bool Ed_connection::execute_direct(Server_runnable *server_runnable)
4216 {
4217 bool rc= FALSE;
4218 Protocol_local protocol_local(m_thd, this);
4219 Prepared_statement stmt(m_thd);
4220 Protocol *save_protocol= m_thd->get_protocol();
4221
4222 DBUG_ENTER("Ed_connection::execute_direct");
4223
4224 free_old_result(); /* Delete all data from previous execution, if any */
4225
4226 m_thd->set_protocol(&protocol_local);
4227 m_thd->push_diagnostics_area(&m_diagnostics_area);
4228
4229 rc= stmt.execute_server_runnable(server_runnable);
4230 m_thd->send_statement_status();
4231
4232 m_thd->set_protocol(save_protocol);
4233 m_thd->pop_diagnostics_area();
4234 /*
4235 Protocol_local makes use of m_current_rset to keep
4236 track of the last result set, while adding result sets to the end.
4237 Reset it to point to the first result set instead.
4238 */
4239 m_current_rset= m_rsets;
4240
4241 /*
4242 Reset rewritten (for password obfuscation etc.) query after
4243 internal call from NDB etc. Without this, a rewritten query
4244 would get "stuck" in SHOW PROCESSLIST.
4245 */
4246 m_thd->reset_rewritten_query();
4247 m_thd->reset_query_for_display();
4248
4249 DBUG_RETURN(rc);
4250 }
4251
4252
4253 /**
4254 A helper method that is called only during execution.
4255
4256 Although Ed_connection doesn't support multi-statements,
4257 a statement may generate many result sets. All subsequent
4258 result sets are appended to the end.
4259
4260 @pre This is called only by Protocol_local.
4261 */
4262
4263 void
add_result_set(Ed_result_set * ed_result_set)4264 Ed_connection::add_result_set(Ed_result_set *ed_result_set)
4265 {
4266 if (m_rsets)
4267 {
4268 m_current_rset->m_next_rset= ed_result_set;
4269 /* While appending, use m_current_rset as a pointer to the tail. */
4270 m_current_rset= ed_result_set;
4271 }
4272 else
4273 m_current_rset= m_rsets= ed_result_set;
4274 }
4275
4276
4277 /**
4278 Release ownership of the current result set to the client.
4279
4280 Since we use a simple linked list for result sets,
4281 this method uses a linear search of the previous result
4282 set to exclude the released instance from the list.
4283
4284 @todo Use double-linked list, when this is really used.
4285
4286 XXX: This has never been tested with more than one result set!
4287
4288 @pre There must be a result set.
4289 */
4290
4291 Ed_result_set *
store_result_set()4292 Ed_connection::store_result_set()
4293 {
4294 Ed_result_set *ed_result_set;
4295
4296 assert(m_current_rset);
4297
4298 if (m_current_rset == m_rsets)
4299 {
4300 /* Assign the return value */
4301 ed_result_set= m_current_rset;
4302 /* Exclude the return value from the list. */
4303 m_current_rset= m_rsets= m_rsets->m_next_rset;
4304 }
4305 else
4306 {
4307 Ed_result_set *prev_rset= m_rsets;
4308 /* Assign the return value. */
4309 ed_result_set= m_current_rset;
4310
4311 /* Exclude the return value from the list */
4312 while (prev_rset->m_next_rset != m_current_rset)
4313 prev_rset= ed_result_set->m_next_rset;
4314 m_current_rset= prev_rset->m_next_rset= m_current_rset->m_next_rset;
4315 }
4316 ed_result_set->m_next_rset= NULL; /* safety */
4317
4318 return ed_result_set;
4319 }
4320
4321 /*************************************************************************
4322 * Protocol_local
4323 **************************************************************************/
4324
Protocol_local(THD * thd,Ed_connection * ed_connection)4325 Protocol_local::Protocol_local(THD *thd, Ed_connection *ed_connection):
4326 m_connection(ed_connection),
4327 m_rset(NULL),
4328 m_column_count(0),
4329 m_current_row(NULL),
4330 m_current_column(NULL),
4331 m_send_metadata(false),
4332 m_thd(thd)
4333 {
4334 clear_alloc_root(&m_rset_root);
4335 }
4336
4337 /**
4338 A helper function to add the current row to the current result
4339 set. Called in @sa start_row(), when a new row is started,
4340 and in send_eof(), when the result set is finished.
4341 */
4342
opt_add_row_to_rset()4343 void Protocol_local::opt_add_row_to_rset()
4344 {
4345 if (m_current_row)
4346 {
4347 /* Add the old row to the result set */
4348 Ed_row *ed_row= new (&m_rset_root) Ed_row(m_current_row, m_column_count);
4349 if (ed_row)
4350 m_rset->push_back(ed_row, &m_rset_root);
4351 }
4352 }
4353
4354
4355 /**
4356 Add a NULL column to the current row.
4357 */
4358
store_null()4359 bool Protocol_local::store_null()
4360 {
4361 if (m_current_column == NULL)
4362 return TRUE; /* start_row() failed to allocate memory. */
4363
4364 memset(m_current_column, 0, sizeof(*m_current_column));
4365 ++m_current_column;
4366 return FALSE;
4367 }
4368
4369
4370 /**
4371 A helper method to add any column to the current row
4372 in its binary form.
4373
4374 Allocates memory for the data in the result set memory root.
4375 */
4376
store_column(const void * data,size_t length)4377 bool Protocol_local::store_column(const void *data, size_t length)
4378 {
4379 if (m_current_column == NULL)
4380 return TRUE; /* start_row() failed to allocate memory. */
4381 /*
4382 alloc_root() automatically aligns memory, so we don't need to
4383 do any extra alignment if we're pointing to, say, an integer.
4384 */
4385 m_current_column->str= (char*) memdup_root(&m_rset_root,
4386 data,
4387 length + 1 /* Safety */);
4388 if (! m_current_column->str)
4389 return TRUE;
4390 m_current_column->str[length]= '\0'; /* Safety */
4391 m_current_column->length= length;
4392 ++m_current_column;
4393 return FALSE;
4394 }
4395
4396
4397 /**
4398 Store a string value in a result set column, optionally
4399 having converted it to character_set_results.
4400 */
4401
4402 bool
store_string(const char * str,size_t length,const CHARSET_INFO * src_cs,const CHARSET_INFO * dst_cs)4403 Protocol_local::store_string(const char *str, size_t length,
4404 const CHARSET_INFO *src_cs,
4405 const CHARSET_INFO *dst_cs)
4406 {
4407 /* Store with conversion */
4408 uint error_unused;
4409
4410 if (dst_cs && !my_charset_same(src_cs, dst_cs) &&
4411 src_cs != &my_charset_bin &&
4412 dst_cs != &my_charset_bin)
4413 {
4414 if (convert->copy(str, length, src_cs, dst_cs, &error_unused))
4415 return TRUE;
4416 str= convert->ptr();
4417 length= convert->length();
4418 }
4419 return store_column(str, length);
4420 }
4421
4422
4423 /** Store a tiny int as is (1 byte) in a result set column. */
4424
store_tiny(longlong value)4425 bool Protocol_local::store_tiny(longlong value)
4426 {
4427 char v= (char) value;
4428 return store_column(&v, 1);
4429 }
4430
4431
4432 /** Store a short as is (2 bytes, host order) in a result set column. */
4433
store_short(longlong value)4434 bool Protocol_local::store_short(longlong value)
4435 {
4436 int16 v= (int16) value;
4437 return store_column(&v, 2);
4438 }
4439
4440
4441 /** Store a "long" as is (4 bytes, host order) in a result set column. */
4442
store_long(longlong value)4443 bool Protocol_local::store_long(longlong value)
4444 {
4445 int32 v= (int32) value;
4446 return store_column(&v, 4);
4447 }
4448
4449
4450 /** Store a "longlong" as is (8 bytes, host order) in a result set column. */
4451
store_longlong(longlong value,bool unsigned_flag)4452 bool Protocol_local::store_longlong(longlong value, bool unsigned_flag)
4453 {
4454 int64 v= (int64) value;
4455 return store_column(&v, 8);
4456 }
4457
4458
4459 /** Store a decimal in string format in a result set column */
4460
store_decimal(const my_decimal * value,uint prec,uint dec)4461 bool Protocol_local::store_decimal(const my_decimal *value, uint prec,
4462 uint dec)
4463 {
4464 char buf[DECIMAL_MAX_STR_LENGTH];
4465 String str(buf, sizeof (buf), &my_charset_bin);
4466 int rc;
4467
4468 rc= my_decimal2string(E_DEC_FATAL_ERROR, value, prec, dec, '0', &str);
4469
4470 if (rc)
4471 return TRUE;
4472
4473 return store_column(str.ptr(), str.length());
4474 }
4475
4476
4477 /** Convert to cs_results and store a string. */
4478
store(const char * str,size_t length,const CHARSET_INFO * src_cs)4479 bool Protocol_local::store(const char *str, size_t length,
4480 const CHARSET_INFO *src_cs)
4481 {
4482 const CHARSET_INFO *dst_cs;
4483
4484 dst_cs= m_connection->m_thd->variables.character_set_results;
4485 return store_string(str, length, src_cs, dst_cs);
4486 }
4487
4488
4489 /** Store a string. */
4490
store(const char * str,size_t length,const CHARSET_INFO * src_cs,const CHARSET_INFO * dst_cs)4491 bool Protocol_local::store(const char *str, size_t length,
4492 const CHARSET_INFO *src_cs,
4493 const CHARSET_INFO *dst_cs)
4494 {
4495 return store_string(str, length, src_cs, dst_cs);
4496 }
4497
4498
4499 /* Store MYSQL_TIME (in binary format) */
4500
store(MYSQL_TIME * time,uint precision MY_ATTRIBUTE ((unused)))4501 bool Protocol_local::store(MYSQL_TIME *time,
4502 uint precision MY_ATTRIBUTE((unused)))
4503 {
4504 return store_column(time, sizeof(MYSQL_TIME));
4505 }
4506
4507
4508 /** Store MYSQL_TIME (in binary format) */
4509
store_date(MYSQL_TIME * time)4510 bool Protocol_local::store_date(MYSQL_TIME *time)
4511 {
4512 return store_column(time, sizeof(MYSQL_TIME));
4513 }
4514
4515
4516 /** Store MYSQL_TIME (in binary format) */
4517
store_time(MYSQL_TIME * time,uint precision MY_ATTRIBUTE ((unused)))4518 bool Protocol_local::store_time(MYSQL_TIME *time,
4519 uint precision MY_ATTRIBUTE((unused)))
4520 {
4521 return store_column(time, sizeof(MYSQL_TIME));
4522 }
4523
4524
4525 /* Store a floating point number, as is. */
4526
store(float value,uint32 decimals,String * buffer)4527 bool Protocol_local::store(float value, uint32 decimals, String *buffer)
4528 {
4529 return store_column(&value, sizeof(float));
4530 }
4531
4532
4533 /* Store a double precision number, as is. */
4534
store(double value,uint32 decimals,String * buffer)4535 bool Protocol_local::store(double value, uint32 decimals, String *buffer)
4536 {
4537 return store_column(&value, sizeof (double));
4538 }
4539
4540
4541 /* Store a Field. */
4542
store(Proto_field * field)4543 bool Protocol_local::store(Proto_field *field)
4544 {
4545 return field->send_binary(this);
4546 }
4547
4548
4549
4550 /** Called for statements that don't have a result set, at statement end. */
4551
4552 bool
send_ok(uint server_status,uint statement_warn_count,ulonglong affected_rows,ulonglong last_insert_id,const char * message)4553 Protocol_local::send_ok(uint server_status, uint statement_warn_count,
4554 ulonglong affected_rows, ulonglong last_insert_id,
4555 const char *message)
4556 {
4557 /*
4558 Just make sure nothing is sent to the client, we have grabbed
4559 the status information in the connection Diagnostics Area.
4560 */
4561 return FALSE;
4562 }
4563
4564
4565 /**
4566 Called at the end of a result set. Append a complete
4567 result set to the list in Ed_connection.
4568
4569 Don't send anything to the client, but instead finish
4570 building of the result set at hand.
4571 */
4572
send_eof(uint server_status,uint statement_warn_count)4573 bool Protocol_local::send_eof(uint server_status, uint statement_warn_count)
4574 {
4575 Ed_result_set *ed_result_set;
4576
4577 assert(m_rset);
4578
4579 opt_add_row_to_rset();
4580 m_current_row= 0;
4581
4582 ed_result_set= new (&m_rset_root) Ed_result_set(m_rset, m_column_count,
4583 &m_rset_root);
4584
4585 m_rset= NULL;
4586
4587 if (! ed_result_set)
4588 return TRUE;
4589
4590 /* In case of successful allocation memory ownership was transferred. */
4591 assert(!alloc_root_inited(&m_rset_root));
4592
4593 /*
4594 Link the created Ed_result_set instance into the list of connection
4595 result sets. Never fails.
4596 */
4597 m_connection->add_result_set(ed_result_set);
4598 return FALSE;
4599 }
4600
4601
4602 /** Called to send an error to the client at the end of a statement. */
4603
4604 bool
send_error(uint sql_errno,const char * err_msg,const char *)4605 Protocol_local::send_error(uint sql_errno, const char *err_msg, const char*)
4606 {
4607 /*
4608 Just make sure that nothing is sent to the client (default
4609 implementation).
4610 */
4611 return FALSE;
4612 }
4613
4614
4615 int
read_packet()4616 Protocol_local::read_packet()
4617 {
4618 return 0;
4619 }
4620
4621 ulong
get_client_capabilities()4622 Protocol_local::get_client_capabilities()
4623 {
4624 return 0;
4625 }
4626
4627 bool
has_client_capability(unsigned long client_capability)4628 Protocol_local::has_client_capability(unsigned long client_capability)
4629 {
4630 return false;
4631 }
4632
connection_alive()4633 bool Protocol_local::connection_alive()
4634 {
4635 return false;
4636 }
4637
end_partial_result_set()4638 void Protocol_local::end_partial_result_set() {}
4639
4640 int
shutdown(bool server_shutdown)4641 Protocol_local::shutdown(bool server_shutdown)
4642 {
4643 return 0;
4644 }
4645
4646 /**
4647 Called between two result set rows.
4648
4649 Prepare structures to fill result set rows.
4650 Unfortunately, we can't return an error here. If memory allocation
4651 fails, we'll have to return an error later. And so is done
4652 in methods such as @sa store_column().
4653 */
4654 void
start_row()4655 Protocol_local::start_row()
4656 {
4657 DBUG_ENTER("Protocol_local::start_row");
4658 assert(alloc_root_inited(&m_rset_root));
4659
4660 opt_add_row_to_rset();
4661 /* Start a new row. */
4662 m_current_row=
4663 (Ed_column *) alloc_root(&m_rset_root, sizeof(Ed_column) * m_column_count);
4664 m_current_column= m_current_row;
4665 DBUG_VOID_RETURN;
4666 }
4667
4668 /**
4669 In "real" protocols this is called to finish a result set row.
4670 Unused in the local implementation.
4671 */
end_row()4672 bool Protocol_local::end_row()
4673 {
4674 DBUG_ENTER("Protocol_local::end_row");
4675 DBUG_RETURN(FALSE);
4676 }
4677
get_rw_status()4678 uint Protocol_local::get_rw_status()
4679 {
4680 return 0;
4681 }
4682
start_result_metadata(uint num_cols,uint flags,const CHARSET_INFO * charset)4683 bool Protocol_local::start_result_metadata(uint num_cols, uint flags,
4684 const CHARSET_INFO *charset)
4685 {
4686 return 0;
4687 }
4688
end_result_metadata()4689 bool Protocol_local::end_result_metadata() { return false; }
4690
4691 bool
send_field_metadata(Send_field * field,const CHARSET_INFO * charset)4692 Protocol_local::send_field_metadata(Send_field *field,
4693 const CHARSET_INFO *charset)
4694 {
4695 return false;
4696 }
4697
get_compression()4698 bool Protocol_local::get_compression() { return false; }
4699
get_command(COM_DATA * com_data,enum_server_command * cmd)4700 int Protocol_local::get_command(COM_DATA *com_data, enum_server_command *cmd)
4701 {
4702 return -1;
4703 }
4704