1 /* Copyright (c) 2002, 2015, Oracle and/or its affiliates.
2 Copyright (c) 2008, 2021, MariaDB
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
16
17 /**
18 @file
19
20 This file contains the implementation of prepared statements.
21
22 When one prepares a statement:
23
24 - Server gets the query from client with command 'COM_STMT_PREPARE';
25 in the following format:
26 [COM_STMT_PREPARE:1] [query]
27 - Parse the query and recognize any parameter markers '?' and
28 store its information list in lex->param_list
29 - Allocate a new statement for this prepare; and keep this in
30 'thd->stmt_map'.
31 - Without executing the query, return back to client the total
32 number of parameters along with result-set metadata information
33 (if any) in the following format:
34 @verbatim
35 [STMT_ID:4]
36 [Column_count:2]
37 [Param_count:2]
38 [Params meta info (stubs only for now)] (if Param_count > 0)
39 [Columns meta info] (if Column_count > 0)
40 @endverbatim
41
42 During prepare the tables used in a statement are opened, but no
43 locks are acquired. Table opening will block any DDL during the
44 operation, and we do not need any locks as we neither read nor
45 modify any data during prepare. Tables are closed after prepare
46 finishes.
47
48 When one executes a statement:
49
50 - Server gets the command 'COM_STMT_EXECUTE' to execute the
51 previously prepared query. If there are any parameter markers, then the
52 client will send the data in the following format:
53 @verbatim
54 [COM_STMT_EXECUTE:1]
55 [STMT_ID:4]
56 [NULL_BITS:(param_count+7)/8)]
57 [TYPES_SUPPLIED_BY_CLIENT(0/1):1]
58 [[length]data]
59 [[length]data] .. [[length]data].
60 @endverbatim
61 (Note: Except for string/binary types; all other types will not be
62 supplied with length field)
63 - If it is a first execute or types of parameters were altered by client,
64 then setup the conversion routines.
65 - Assign parameter items from the supplied data.
66 - Execute the query without re-parsing and send back the results
67 to client
68
69 During execution of prepared statement tables are opened and locked
70 the same way they would for normal (non-prepared) statement
71 execution. Tables are unlocked and closed after the execution.
72
73 When one supplies long data for a placeholder:
74
75 - Server gets the long data in pieces with command type
76 'COM_STMT_SEND_LONG_DATA'.
77 - The packet received will have the format as:
78 [COM_STMT_SEND_LONG_DATA:1][STMT_ID:4][parameter_number:2][data]
79 - data from the packet is appended to the long data value buffer for this
80 placeholder.
81 - It's up to the client to stop supplying data chunks at any point. The
82 server doesn't care; also, the server doesn't notify the client whether
83 it got the data or not; if there is any error, then it will be returned
84 at statement execute.
85 */
86
87 #include "mariadb.h" /* NO_EMBEDDED_ACCESS_CHECKS */
88 #include "sql_priv.h"
89 #include "unireg.h"
90 #include "sql_class.h" // set_var.h: THD
91 #include "set_var.h"
92 #include "sql_prepare.h"
93 #include "sql_parse.h" // insert_precheck, update_precheck, delete_precheck
94 #include "sql_base.h" // open_normal_and_derived_tables
95 #include "sql_cache.h" // query_cache_*
96 #include "sql_view.h" // create_view_precheck
97 #include "sql_delete.h" // mysql_prepare_delete
98 #include "sql_select.h" // for JOIN
99 #include "sql_insert.h" // upgrade_lock_type_for_insert, mysql_prepare_insert
100 #include "sql_update.h" // mysql_prepare_update
101 #include "sql_db.h" // mysql_opt_change_db, mysql_change_db
102 #include "sql_acl.h" // *_ACL
103 #include "sql_derived.h" // mysql_derived_prepare,
104 // mysql_handle_derived
105 #include "sql_cte.h"
106 #include "sql_cursor.h"
107 #include "sql_show.h"
108 #include "sql_repl.h"
109 #include "slave.h"
110 #include "sp_head.h"
111 #include "sp.h"
112 #include "sp_cache.h"
113 #include "sql_handler.h" // mysql_ha_rm_tables
114 #include "probes_mysql.h"
115 #include "opt_trace.h"
116 #ifdef EMBEDDED_LIBRARY
117 /* include MYSQL_BIND headers */
118 #include <mysql.h>
119 #else
120 #include <mysql_com.h>
121 /* Constants defining bits in parameter type flags. Flags are read from high byte of short value */
122 static const uint PARAMETER_FLAG_UNSIGNED= 128U << 8;
123 #endif
124 #include "lock.h" // MYSQL_OPEN_FORCE_SHARED_MDL
125 #include "log_event.h" // class Log_event
126 #include "sql_handler.h"
127 #include "transaction.h" // trans_rollback_implicit
128 #ifdef WITH_WSREP
129 #include "wsrep_mysqld.h"
130 #include "wsrep_trans_observer.h"
131 #endif /* WITH_WSREP */
132
133 /**
134 A result class used to send cursor rows using the binary protocol.
135 */
136
137 class Select_fetch_protocol_binary: public select_send
138 {
139 Protocol_binary protocol;
140 public:
141 Select_fetch_protocol_binary(THD *thd);
142 virtual bool send_result_set_metadata(List<Item> &list, uint flags);
143 virtual int send_data(List<Item> &items);
144 virtual bool send_eof();
145 #ifdef EMBEDDED_LIBRARY
begin_dataset()146 void begin_dataset()
147 {
148 protocol.begin_dataset();
149 }
150 #endif
151 };
152
153 /****************************************************************************/
154
155 /**
156 Prepared_statement: a statement that can contain placeholders.
157 */
158
159 class Prepared_statement: public Statement
160 {
161 public:
162 enum flag_values
163 {
164 IS_IN_USE= 1,
165 IS_SQL_PREPARE= 2
166 };
167
168 THD *thd;
169 Select_fetch_protocol_binary result;
170 Item_param **param_array;
171 Server_side_cursor *cursor;
172 uchar *packet;
173 uchar *packet_end;
174 uint param_count;
175 uint last_errno;
176 uint flags;
177 char last_error[MYSQL_ERRMSG_SIZE];
178 my_bool iterations;
179 my_bool start_param;
180 my_bool read_types;
181 #ifndef EMBEDDED_LIBRARY
182 bool (*set_params)(Prepared_statement *st, uchar *data, uchar *data_end,
183 uchar *read_pos, String *expanded_query);
184 bool (*set_bulk_params)(Prepared_statement *st,
185 uchar **read_pos, uchar *data_end, bool reset);
186 #else
187 bool (*set_params_data)(Prepared_statement *st, String *expanded_query);
188 /*TODO: add bulk support for builtin server */
189 #endif
190 bool (*set_params_from_actual_params)(Prepared_statement *stmt,
191 List<Item> &list,
192 String *expanded_query);
193 public:
194 Prepared_statement(THD *thd_arg);
195 virtual ~Prepared_statement();
196 void setup_set_params();
197 virtual Query_arena::Type type() const;
198 virtual void cleanup_stmt();
199 bool set_name(const LEX_CSTRING *name);
close_cursor()200 inline void close_cursor() { delete cursor; cursor= 0; }
is_in_use()201 inline bool is_in_use() { return flags & (uint) IS_IN_USE; }
is_sql_prepare() const202 inline bool is_sql_prepare() const { return flags & (uint) IS_SQL_PREPARE; }
set_sql_prepare()203 void set_sql_prepare() { flags|= (uint) IS_SQL_PREPARE; }
204 bool prepare(const char *packet, uint packet_length);
205 bool execute_loop(String *expanded_query,
206 bool open_cursor,
207 uchar *packet_arg, uchar *packet_end_arg);
208 bool execute_bulk_loop(String *expanded_query,
209 bool open_cursor,
210 uchar *packet_arg, uchar *packet_end_arg);
211 bool execute_server_runnable(Server_runnable *server_runnable);
212 my_bool set_bulk_parameters(bool reset);
bulk_iterations()213 bool bulk_iterations() { return iterations; };
214 /* Destroy this statement */
215 void deallocate();
216 bool execute_immediate(const char *query, uint query_length);
217 private:
218 /**
219 The memory root to allocate parsed tree elements (instances of Item,
220 SELECT_LEX and other classes).
221 */
222 MEM_ROOT main_mem_root;
223 sql_mode_t m_sql_mode;
224 private:
225 bool set_db(const LEX_CSTRING *db);
226 bool set_parameters(String *expanded_query,
227 uchar *packet, uchar *packet_end);
228 bool execute(String *expanded_query, bool open_cursor);
229 void deallocate_immediate();
230 bool reprepare();
231 bool validate_metadata(Prepared_statement *copy);
232 void swap_prepared_statement(Prepared_statement *copy);
233 };
234
235 /**
236 Execute one SQL statement in an isolated context.
237 */
238
239 class Execute_sql_statement: public Server_runnable
240 {
241 public:
242 Execute_sql_statement(LEX_STRING sql_text);
243 virtual bool execute_server_code(THD *thd);
244 private:
245 LEX_STRING m_sql_text;
246 };
247
248
249 class Ed_connection;
250
251 /**
252 Protocol_local: a helper class to intercept the result
253 of the data written to the network.
254 */
255
256 class Protocol_local :public Protocol
257 {
258 public:
259 Protocol_local(THD *thd, Ed_connection *ed_connection);
~Protocol_local()260 ~Protocol_local() { free_root(&m_rset_root, MYF(0)); }
261 protected:
262 virtual void prepare_for_resend();
263 virtual bool write();
264 virtual bool store_null();
265 virtual bool store_tiny(longlong from);
266 virtual bool store_short(longlong from);
267 virtual bool store_long(longlong from);
268 virtual bool store_longlong(longlong from, bool unsigned_flag);
269 virtual bool store_decimal(const my_decimal *);
270 virtual bool store(const char *from, size_t length, CHARSET_INFO *cs);
271 virtual bool store(const char *from, size_t length,
272 CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
273 virtual bool store(MYSQL_TIME *time, int decimals);
274 virtual bool store_date(MYSQL_TIME *time);
275 virtual bool store_time(MYSQL_TIME *time, int decimals);
276 virtual bool store(float value, uint32 decimals, String *buffer);
277 virtual bool store(double value, uint32 decimals, String *buffer);
278 virtual bool store(Field *field);
279
280 virtual bool send_result_set_metadata(List<Item> *list, uint flags);
281 virtual bool send_out_parameters(List<Item_param> *sp_params);
282 #ifdef EMBEDDED_LIBRARY
283 void remove_last_row();
284 #endif
type()285 virtual enum enum_protocol_type type() { return PROTOCOL_LOCAL; };
286
287 virtual bool send_ok(uint server_status, uint statement_warn_count,
288 ulonglong affected_rows, ulonglong last_insert_id,
289 const char *message, bool skip_flush);
290
291 virtual bool send_eof(uint server_status, uint statement_warn_count);
292 virtual bool send_error(uint sql_errno, const char *err_msg, const char* sqlstate);
293 private:
294 bool store_string(const char *str, size_t length,
295 CHARSET_INFO *src_cs, CHARSET_INFO *dst_cs);
296
297 bool store_column(const void *data, size_t length);
298 void opt_add_row_to_rset();
299 private:
300 Ed_connection *m_connection;
301 MEM_ROOT m_rset_root;
302 List<Ed_row> *m_rset;
303 size_t m_column_count;
304 Ed_column *m_current_row;
305 Ed_column *m_current_column;
306 };
307
308 /******************************************************************************
309 Implementation
310 ******************************************************************************/
311
312
is_param_null(const uchar * pos,ulong param_no)313 inline bool is_param_null(const uchar *pos, ulong param_no)
314 {
315 return pos[param_no/8] & (1 << (param_no & 7));
316 }
317
318 /**
319 Find a prepared statement in the statement map by id.
320
321 Try to find a prepared statement and set THD error if it's not found.
322
323 @param thd thread handle
324 @param id statement id
325 @param where the place from which this function is called (for
326 error reporting).
327
328 @return
329 0 if the statement was not found, a pointer otherwise.
330 */
331
332 static Prepared_statement *
find_prepared_statement(THD * thd,ulong id)333 find_prepared_statement(THD *thd, ulong id)
334 {
335 /*
336 To strictly separate namespaces of SQL prepared statements and C API
337 prepared statements find() will return 0 if there is a named prepared
338 statement with such id.
339
340 LAST_STMT_ID is special value which mean last prepared statement ID
341 (it was made for COM_MULTI to allow prepare and execute a statement
342 in the same command but usage is not limited by COM_MULTI only).
343 */
344 Statement *stmt= ((id == LAST_STMT_ID) ?
345 thd->last_stmt :
346 thd->stmt_map.find(id));
347
348 if (stmt == 0 || stmt->type() != Query_arena::PREPARED_STATEMENT)
349 return NULL;
350
351 return (Prepared_statement *) stmt;
352 }
353
354
355 /**
356 Send prepared statement id and metadata to the client after prepare.
357
358 @todo
359 Fix this nasty upcast from List<Item_param> to List<Item>
360
361 @return
362 0 in case of success, 1 otherwise
363 */
364
365 #ifndef EMBEDDED_LIBRARY
send_prep_stmt(Prepared_statement * stmt,uint columns)366 static bool send_prep_stmt(Prepared_statement *stmt, uint columns)
367 {
368 NET *net= &stmt->thd->net;
369 uchar buff[12];
370 uint tmp;
371 int error;
372 THD *thd= stmt->thd;
373 DBUG_ENTER("send_prep_stmt");
374 DBUG_PRINT("enter",("stmt->id: %lu columns: %d param_count: %d",
375 stmt->id, columns, stmt->param_count));
376
377 buff[0]= 0; /* OK packet indicator */
378 int4store(buff+1, stmt->id);
379 int2store(buff+5, columns);
380 int2store(buff+7, stmt->param_count);
381 buff[9]= 0; // Guard against a 4.1 client
382 tmp= MY_MIN(stmt->thd->get_stmt_da()->current_statement_warn_count(), 65535);
383 int2store(buff+10, tmp);
384
385 /*
386 Send types and names of placeholders to the client
387 XXX: fix this nasty upcast from List<Item_param> to List<Item>
388 */
389 error= my_net_write(net, buff, sizeof(buff));
390 if (stmt->param_count && likely(!error))
391 {
392 error= thd->protocol_text.send_result_set_metadata((List<Item> *)
393 &stmt->lex->param_list,
394 Protocol::SEND_EOF);
395 }
396
397 if (likely(!error))
398 {
399 /* Flag that a response has already been sent */
400 thd->get_stmt_da()->disable_status();
401 }
402
403 DBUG_RETURN(error);
404 }
405 #else
send_prep_stmt(Prepared_statement * stmt,uint columns)406 static bool send_prep_stmt(Prepared_statement *stmt,
407 uint columns __attribute__((unused)))
408 {
409 THD *thd= stmt->thd;
410
411 thd->client_stmt_id= stmt->id;
412 thd->client_param_count= stmt->param_count;
413 thd->clear_error();
414 thd->get_stmt_da()->disable_status();
415
416 return 0;
417 }
418 #endif /*!EMBEDDED_LIBRARY*/
419
420
421 #ifndef EMBEDDED_LIBRARY
422
423 /**
424 Read the length of the parameter data and return it back to
425 the caller.
426
427 Read data length, position the packet to the first byte after it,
428 and return the length to the caller.
429
430 @param packet a pointer to the data
431 @param len remaining packet length
432
433 @return
434 Length of data piece.
435 */
436
get_param_length(uchar ** packet,ulong len)437 static ulong get_param_length(uchar **packet, ulong len)
438 {
439 uchar *pos= *packet;
440 if (len < 1)
441 return 0;
442 if (*pos < 251)
443 {
444 (*packet)++;
445 return (ulong) *pos;
446 }
447 if (len < 3)
448 return 0;
449 if (*pos == 252)
450 {
451 (*packet)+=3;
452 return (ulong) uint2korr(pos+1);
453 }
454 if (len < 4)
455 return 0;
456 if (*pos == 253)
457 {
458 (*packet)+=4;
459 return (ulong) uint3korr(pos+1);
460 }
461 if (len < 5)
462 return 0;
463 (*packet)+=9; // Must be 254 when here
464 /*
465 In our client-server protocol all numbers bigger than 2^24
466 stored as 8 bytes with uint8korr. Here we always know that
467 parameter length is less than 2^4 so don't look at the second
468 4 bytes. But still we need to obey the protocol hence 9 in the
469 assignment above.
470 */
471 return (ulong) uint4korr(pos+1);
472 }
473 #else
474 #define get_param_length(packet, len) len
475 #endif /*!EMBEDDED_LIBRARY*/
476
477 /**
478 Data conversion routines.
479
480 All these functions read the data from pos, convert it to requested
481 type and assign to param; pos is advanced to predefined length.
482
483 Make a note that the NULL handling is examined at first execution
484 (i.e. when input types altered) and for all subsequent executions
485 we don't read any values for this.
486
487 @param pos input data buffer
488 @param len length of data in the buffer
489 */
490
set_param_tiny(uchar ** pos,ulong len)491 void Item_param::set_param_tiny(uchar **pos, ulong len)
492 {
493 #ifndef EMBEDDED_LIBRARY
494 if (len < 1)
495 return;
496 #endif
497 int8 value= (int8) **pos;
498 set_int(unsigned_flag ? (longlong) ((uint8) value) :
499 (longlong) value, 4);
500 *pos+= 1;
501 }
502
set_param_short(uchar ** pos,ulong len)503 void Item_param::set_param_short(uchar **pos, ulong len)
504 {
505 int16 value;
506 #ifndef EMBEDDED_LIBRARY
507 if (len < 2)
508 return;
509 value= sint2korr(*pos);
510 #else
511 shortget(value, *pos);
512 #endif
513 set_int(unsigned_flag ? (longlong) ((uint16) value) :
514 (longlong) value, 6);
515 *pos+= 2;
516 }
517
set_param_int32(uchar ** pos,ulong len)518 void Item_param::set_param_int32(uchar **pos, ulong len)
519 {
520 int32 value;
521 #ifndef EMBEDDED_LIBRARY
522 if (len < 4)
523 return;
524 value= sint4korr(*pos);
525 #else
526 longget(value, *pos);
527 #endif
528 set_int(unsigned_flag ? (longlong) ((uint32) value) :
529 (longlong) value, 11);
530 *pos+= 4;
531 }
532
set_param_int64(uchar ** pos,ulong len)533 void Item_param::set_param_int64(uchar **pos, ulong len)
534 {
535 longlong value;
536 #ifndef EMBEDDED_LIBRARY
537 if (len < 8)
538 return;
539 value= (longlong) sint8korr(*pos);
540 #else
541 longlongget(value, *pos);
542 #endif
543 set_int(value, 21);
544 *pos+= 8;
545 }
546
set_param_float(uchar ** pos,ulong len)547 void Item_param::set_param_float(uchar **pos, ulong len)
548 {
549 float data;
550 #ifndef EMBEDDED_LIBRARY
551 if (len < 4)
552 return;
553 float4get(data,*pos);
554 #else
555 floatget(data, *pos);
556 #endif
557 set_double((double) data);
558 *pos+= 4;
559 }
560
set_param_double(uchar ** pos,ulong len)561 void Item_param::set_param_double(uchar **pos, ulong len)
562 {
563 double data;
564 #ifndef EMBEDDED_LIBRARY
565 if (len < 8)
566 return;
567 float8get(data,*pos);
568 #else
569 doubleget(data, *pos);
570 #endif
571 set_double((double) data);
572 *pos+= 8;
573 }
574
set_param_decimal(uchar ** pos,ulong len)575 void Item_param::set_param_decimal(uchar **pos, ulong len)
576 {
577 ulong length= get_param_length(pos, len);
578 set_decimal((char*)*pos, length);
579 *pos+= length;
580 }
581
582 #ifndef EMBEDDED_LIBRARY
583
584 /*
585 Read date/time/datetime parameter values from network (binary
586 protocol). See writing counterparts of these functions in
587 libmysql.c (store_param_{time,date,datetime}).
588 */
589
590 /**
591 @todo
592 Add warning 'Data truncated' here
593 */
set_param_time(uchar ** pos,ulong len)594 void Item_param::set_param_time(uchar **pos, ulong len)
595 {
596 MYSQL_TIME tm;
597 ulong length= get_param_length(pos, len);
598
599 if (length >= 8)
600 {
601 uchar *to= *pos;
602 uint day;
603
604 tm.neg= (bool) to[0];
605 day= (uint) sint4korr(to+1);
606 tm.hour= (uint) to[5] + day * 24;
607 tm.minute= (uint) to[6];
608 tm.second= (uint) to[7];
609 tm.second_part= (length > 8) ? (ulong) sint4korr(to+8) : 0;
610 if (tm.hour > 838)
611 {
612 /* TODO: add warning 'Data truncated' here */
613 tm.hour= 838;
614 tm.minute= 59;
615 tm.second= 59;
616 }
617 tm.day= tm.year= tm.month= 0;
618 }
619 else
620 set_zero_time(&tm, MYSQL_TIMESTAMP_TIME);
621 set_time(&tm, MYSQL_TIMESTAMP_TIME, MAX_TIME_FULL_WIDTH);
622 *pos+= length;
623 }
624
set_param_datetime(uchar ** pos,ulong len)625 void Item_param::set_param_datetime(uchar **pos, ulong len)
626 {
627 MYSQL_TIME tm;
628 ulong length= get_param_length(pos, len);
629
630 if (length >= 4)
631 {
632 uchar *to= *pos;
633
634 tm.neg= 0;
635 tm.year= (uint) sint2korr(to);
636 tm.month= (uint) to[2];
637 tm.day= (uint) to[3];
638 if (length > 4)
639 {
640 tm.hour= (uint) to[4];
641 tm.minute= (uint) to[5];
642 tm.second= (uint) to[6];
643 }
644 else
645 tm.hour= tm.minute= tm.second= 0;
646
647 tm.second_part= (length > 7) ? (ulong) sint4korr(to+7) : 0;
648 }
649 else
650 set_zero_time(&tm, MYSQL_TIMESTAMP_DATETIME);
651 set_time(&tm, MYSQL_TIMESTAMP_DATETIME, MAX_DATETIME_WIDTH);
652 *pos+= length;
653 }
654
655
set_param_date(uchar ** pos,ulong len)656 void Item_param::set_param_date(uchar **pos, ulong len)
657 {
658 MYSQL_TIME tm;
659 ulong length= get_param_length(pos, len);
660
661 if (length >= 4)
662 {
663 uchar *to= *pos;
664
665 tm.year= (uint) sint2korr(to);
666 tm.month= (uint) to[2];
667 tm.day= (uint) to[3];
668
669 tm.hour= tm.minute= tm.second= 0;
670 tm.second_part= 0;
671 tm.neg= 0;
672 }
673 else
674 set_zero_time(&tm, MYSQL_TIMESTAMP_DATE);
675 set_time(&tm, MYSQL_TIMESTAMP_DATE, MAX_DATE_WIDTH);
676 *pos+= length;
677 }
678
679 #else/*!EMBEDDED_LIBRARY*/
680 /**
681 @todo
682 Add warning 'Data truncated' here
683 */
set_param_time(uchar ** pos,ulong len)684 void Item_param::set_param_time(uchar **pos, ulong len)
685 {
686 MYSQL_TIME tm= *((MYSQL_TIME*)*pos);
687 tm.hour+= tm.day * 24;
688 tm.day= tm.year= tm.month= 0;
689 if (tm.hour > 838)
690 {
691 /* TODO: add warning 'Data truncated' here */
692 tm.hour= 838;
693 tm.minute= 59;
694 tm.second= 59;
695 }
696 set_time(&tm, MYSQL_TIMESTAMP_TIME, MAX_TIME_WIDTH);
697 }
698
set_param_datetime(uchar ** pos,ulong len)699 void Item_param::set_param_datetime(uchar **pos, ulong len)
700 {
701 MYSQL_TIME tm= *((MYSQL_TIME*)*pos);
702 tm.neg= 0;
703 set_time(&tm, MYSQL_TIMESTAMP_DATETIME, MAX_DATETIME_WIDTH);
704 }
705
set_param_date(uchar ** pos,ulong len)706 void Item_param::set_param_date(uchar **pos, ulong len)
707 {
708 MYSQL_TIME *to= (MYSQL_TIME*)*pos;
709 set_time(to, MYSQL_TIMESTAMP_DATE, MAX_DATE_WIDTH);
710 }
711 #endif /*!EMBEDDED_LIBRARY*/
712
713
set_param_str(uchar ** pos,ulong len)714 void Item_param::set_param_str(uchar **pos, ulong len)
715 {
716 ulong length= get_param_length(pos, len);
717 if (length == 0 && m_empty_string_is_null)
718 set_null();
719 else
720 {
721 if (length > len)
722 length= len;
723 /*
724 We use &my_charset_bin here. Conversion and setting real character
725 sets will be done in Item_param::convert_str_value(), after the
726 original value is appended to the query used for logging.
727 */
728 set_str((const char *) *pos, length, &my_charset_bin, &my_charset_bin);
729 *pos+= length;
730 }
731 }
732
733
734 #undef get_param_length
735
736
setup_conversion(THD * thd,uchar param_type)737 void Item_param::setup_conversion(THD *thd, uchar param_type)
738 {
739 const Type_handler *h=
740 Type_handler::get_handler_by_field_type((enum_field_types) param_type);
741 /*
742 The client library ensures that we won't get any unexpected typecodes
743 in the bound parameter. Translating unknown typecodes to
744 &type_handler_string lets us to handle malformed packets as well.
745 */
746 if (!h)
747 h= &type_handler_string;
748 set_handler(h);
749 h->Item_param_setup_conversion(thd, this);
750 }
751
752
setup_conversion_blob(THD * thd)753 void Item_param::setup_conversion_blob(THD *thd)
754 {
755 value.cs_info.character_set_of_placeholder= &my_charset_bin;
756 value.cs_info.character_set_client= thd->variables.character_set_client;
757 DBUG_ASSERT(thd->variables.character_set_client);
758 value.cs_info.final_character_set_of_str_value= &my_charset_bin;
759 m_empty_string_is_null= thd->variables.sql_mode & MODE_EMPTY_STRING_IS_NULL;
760 }
761
762
setup_conversion_string(THD * thd,CHARSET_INFO * fromcs)763 void Item_param::setup_conversion_string(THD *thd, CHARSET_INFO *fromcs)
764 {
765 value.cs_info.set(thd, fromcs);
766 m_empty_string_is_null= thd->variables.sql_mode & MODE_EMPTY_STRING_IS_NULL;
767 /*
768 Exact value of max_length is not known unless data is converted to
769 charset of connection, so we have to set it later.
770 */
771 }
772
773 #ifndef EMBEDDED_LIBRARY
774
775 /**
776 Routines to assign parameters from data supplied by the client.
777
778 Update the parameter markers by reading data from the packet and
779 and generate a valid query for logging.
780
781 @note
782 This function, along with other _with_log functions is called when one of
783 binary, slow or general logs is open. Logging of prepared statements in
784 all cases is performed by means of conventional queries: if parameter
785 data was supplied from C API, each placeholder in the query is
786 replaced with its actual value; if we're logging a [Dynamic] SQL
787 prepared statement, parameter markers are replaced with variable names.
788 Example:
789 @verbatim
790 mysqld_stmt_prepare("UPDATE t1 SET a=a*1.25 WHERE a=?")
791 --> general logs gets [Prepare] UPDATE t1 SET a*1.25 WHERE a=?"
792 mysqld_stmt_execute(stmt);
793 --> general and binary logs get
794 [Execute] UPDATE t1 SET a*1.25 WHERE a=1"
795 @endverbatim
796
797 If a statement has been prepared using SQL syntax:
798 @verbatim
799 PREPARE stmt FROM "UPDATE t1 SET a=a*1.25 WHERE a=?"
800 --> general log gets
801 [Query] PREPARE stmt FROM "UPDATE ..."
802 EXECUTE stmt USING @a
803 --> general log gets
804 [Query] EXECUTE stmt USING @a;
805 @endverbatim
806
807 @retval
808 0 if success
809 @retval
810 1 otherwise
811 */
812
insert_params_with_log(Prepared_statement * stmt,uchar * null_array,uchar * read_pos,uchar * data_end,String * query)813 static bool insert_params_with_log(Prepared_statement *stmt, uchar *null_array,
814 uchar *read_pos, uchar *data_end,
815 String *query)
816 {
817 THD *thd= stmt->thd;
818 Item_param **begin= stmt->param_array;
819 Item_param **end= begin + stmt->param_count;
820 Copy_query_with_rewrite acc(thd, stmt->query(), stmt->query_length(), query);
821 DBUG_ENTER("insert_params_with_log");
822
823 for (Item_param **it= begin; it < end; ++it)
824 {
825 Item_param *param= *it;
826 if (!param->has_long_data_value())
827 {
828 if (is_param_null(null_array, (uint) (it - begin)))
829 param->set_null();
830 else
831 {
832 if (read_pos >= data_end)
833 DBUG_RETURN(1);
834 param->set_param_func(&read_pos, (uint) (data_end - read_pos));
835 if (param->has_no_value())
836 DBUG_RETURN(1);
837
838 if (param->limit_clause_param && !param->has_int_value())
839 {
840 if (param->set_limit_clause_param(param->val_int()))
841 DBUG_RETURN(1);
842 }
843 }
844 }
845 /*
846 A long data stream was supplied for this parameter marker.
847 This was done after prepare, prior to providing a placeholder
848 type (the types are supplied at execute). Check that the
849 supplied type of placeholder can accept a data stream.
850 */
851 else if (!param->type_handler()->is_param_long_data_type())
852 DBUG_RETURN(1);
853
854 if (acc.append(param))
855 DBUG_RETURN(1);
856
857 if (param->convert_str_value(thd))
858 DBUG_RETURN(1); /* out of memory */
859
860 param->sync_clones();
861 }
862 if (acc.finalize())
863 DBUG_RETURN(1);
864
865 DBUG_RETURN(0);
866 }
867
868
insert_params(Prepared_statement * stmt,uchar * null_array,uchar * read_pos,uchar * data_end,String * expanded_query)869 static bool insert_params(Prepared_statement *stmt, uchar *null_array,
870 uchar *read_pos, uchar *data_end,
871 String *expanded_query)
872 {
873 Item_param **begin= stmt->param_array;
874 Item_param **end= begin + stmt->param_count;
875
876 DBUG_ENTER("insert_params");
877
878 for (Item_param **it= begin; it < end; ++it)
879 {
880 Item_param *param= *it;
881 param->indicator= STMT_INDICATOR_NONE; // only for bulk parameters
882 if (!param->has_long_data_value())
883 {
884 if (is_param_null(null_array, (uint) (it - begin)))
885 param->set_null();
886 else
887 {
888 if (read_pos >= data_end)
889 DBUG_RETURN(1);
890 param->set_param_func(&read_pos, (uint) (data_end - read_pos));
891 if (param->has_no_value())
892 DBUG_RETURN(1);
893 }
894 }
895 /*
896 A long data stream was supplied for this parameter marker.
897 This was done after prepare, prior to providing a placeholder
898 type (the types are supplied at execute). Check that the
899 supplied type of placeholder can accept a data stream.
900 */
901 else if (!param->type_handler()->is_param_long_data_type())
902 DBUG_RETURN(1);
903 if (param->convert_str_value(stmt->thd))
904 DBUG_RETURN(1); /* out of memory */
905 param->sync_clones();
906 }
907 DBUG_RETURN(0);
908 }
909
910
insert_bulk_params(Prepared_statement * stmt,uchar ** read_pos,uchar * data_end,bool reset)911 static bool insert_bulk_params(Prepared_statement *stmt,
912 uchar **read_pos, uchar *data_end,
913 bool reset)
914 {
915 Item_param **begin= stmt->param_array;
916 Item_param **end= begin + stmt->param_count;
917
918 DBUG_ENTER("insert_params");
919
920 for (Item_param **it= begin; it < end; ++it)
921 {
922 Item_param *param= *it;
923 if (reset)
924 param->reset();
925 if (!param->has_long_data_value())
926 {
927 param->indicator= (enum_indicator_type) *((*read_pos)++);
928 if ((*read_pos) > data_end)
929 DBUG_RETURN(1);
930 switch (param->indicator)
931 {
932 case STMT_INDICATOR_NONE:
933 if ((*read_pos) >= data_end)
934 DBUG_RETURN(1);
935 param->set_param_func(read_pos, (uint) (data_end - (*read_pos)));
936 if (param->has_no_value())
937 DBUG_RETURN(1);
938 if (param->convert_str_value(stmt->thd))
939 DBUG_RETURN(1); /* out of memory */
940 break;
941 case STMT_INDICATOR_NULL:
942 param->set_null();
943 break;
944 case STMT_INDICATOR_DEFAULT:
945 param->set_default();
946 break;
947 case STMT_INDICATOR_IGNORE:
948 param->set_ignore();
949 break;
950 }
951 }
952 else
953 DBUG_RETURN(1); // long is not supported here
954 param->sync_clones();
955 }
956 DBUG_RETURN(0);
957 }
958
959
960 /**
961 Checking if parameter type and flags are valid
962
963 @param typecode ushort value with type in low byte, and flags in high byte
964
965 @retval true this parameter is wrong
966 @retval false this parameter is OK
967 */
968
969 static bool
parameter_type_sanity_check(ushort typecode)970 parameter_type_sanity_check(ushort typecode)
971 {
972 /* Checking if type in lower byte is valid */
973 switch (typecode & 0xff) {
974 case MYSQL_TYPE_DECIMAL:
975 case MYSQL_TYPE_NEWDECIMAL:
976 case MYSQL_TYPE_TINY:
977 case MYSQL_TYPE_SHORT:
978 case MYSQL_TYPE_LONG:
979 case MYSQL_TYPE_LONGLONG:
980 case MYSQL_TYPE_INT24:
981 case MYSQL_TYPE_YEAR:
982 case MYSQL_TYPE_BIT:
983 case MYSQL_TYPE_FLOAT:
984 case MYSQL_TYPE_DOUBLE:
985 case MYSQL_TYPE_NULL:
986 case MYSQL_TYPE_VARCHAR:
987 case MYSQL_TYPE_TINY_BLOB:
988 case MYSQL_TYPE_MEDIUM_BLOB:
989 case MYSQL_TYPE_LONG_BLOB:
990 case MYSQL_TYPE_BLOB:
991 case MYSQL_TYPE_VAR_STRING:
992 case MYSQL_TYPE_STRING:
993 case MYSQL_TYPE_ENUM:
994 case MYSQL_TYPE_SET:
995 case MYSQL_TYPE_GEOMETRY:
996 case MYSQL_TYPE_TIMESTAMP:
997 case MYSQL_TYPE_DATE:
998 case MYSQL_TYPE_TIME:
999 case MYSQL_TYPE_DATETIME:
1000 case MYSQL_TYPE_NEWDATE:
1001 break;
1002 /*
1003 This types normally cannot be sent by client, so maybe it'd be
1004 better to treat them like an error here.
1005 */
1006 case MYSQL_TYPE_TIMESTAMP2:
1007 case MYSQL_TYPE_TIME2:
1008 case MYSQL_TYPE_DATETIME2:
1009 default:
1010 return true;
1011 };
1012
1013 // In Flags in high byte only unsigned bit may be set
1014 if (typecode & ((~PARAMETER_FLAG_UNSIGNED) & 0x0000ff00))
1015 {
1016 return true;
1017 }
1018 return false;
1019 }
1020
1021 static bool
set_conversion_functions(Prepared_statement * stmt,uchar ** data)1022 set_conversion_functions(Prepared_statement *stmt, uchar **data)
1023 {
1024 uchar *read_pos= *data;
1025
1026 DBUG_ENTER("set_conversion_functions");
1027 /*
1028 First execute or types altered by the client, setup the
1029 conversion routines for all parameters (one time)
1030 */
1031 Item_param **it= stmt->param_array;
1032 Item_param **end= it + stmt->param_count;
1033 THD *thd= stmt->thd;
1034 for (; it < end; ++it)
1035 {
1036 ushort typecode;
1037
1038 /*
1039 stmt_execute_packet_sanity_check has already verified, that there
1040 are enough data in the packet for data types
1041 */
1042 typecode= sint2korr(read_pos);
1043 read_pos+= 2;
1044 if (parameter_type_sanity_check(typecode))
1045 {
1046 DBUG_RETURN(1);
1047 }
1048 (**it).unsigned_flag= MY_TEST(typecode & PARAMETER_FLAG_UNSIGNED);
1049 (*it)->setup_conversion(thd, (uchar) (typecode & 0xff));
1050 (*it)->sync_clones();
1051 }
1052 *data= read_pos;
1053 DBUG_RETURN(0);
1054 }
1055
1056
setup_conversion_functions(Prepared_statement * stmt,uchar ** data,bool bulk_protocol=0)1057 static bool setup_conversion_functions(Prepared_statement *stmt,
1058 uchar **data,
1059 bool bulk_protocol= 0)
1060 {
1061 /* skip null bits */
1062 uchar *read_pos= *data;
1063 if (!bulk_protocol)
1064 read_pos+= (stmt->param_count+7) / 8;
1065
1066 DBUG_ENTER("setup_conversion_functions");
1067
1068 if (*read_pos++) //types supplied / first execute
1069 {
1070 *data= read_pos;
1071 bool res= set_conversion_functions(stmt, data);
1072 DBUG_RETURN(res);
1073 }
1074 *data= read_pos;
1075 DBUG_RETURN(0);
1076 }
1077
1078 #else
1079
1080 //TODO: support bulk parameters
1081
1082 /**
1083 Embedded counterparts of parameter assignment routines.
1084
1085 The main difference between the embedded library and the server is
1086 that in embedded case we don't serialize/deserialize parameters data.
1087
1088 Additionally, for unknown reason, the client-side flag raised for
1089 changed types of placeholders is ignored and we simply setup conversion
1090 functions at each execute (TODO: fix).
1091 */
1092
emb_insert_params(Prepared_statement * stmt,String * expanded_query)1093 static bool emb_insert_params(Prepared_statement *stmt, String *expanded_query)
1094 {
1095 THD *thd= stmt->thd;
1096 Item_param **it= stmt->param_array;
1097 Item_param **end= it + stmt->param_count;
1098 MYSQL_BIND *client_param= stmt->thd->client_params;
1099
1100 DBUG_ENTER("emb_insert_params");
1101
1102 for (; it < end; ++it, ++client_param)
1103 {
1104 Item_param *param= *it;
1105 param->setup_conversion(thd, client_param->buffer_type);
1106 if (!param->has_long_data_value())
1107 {
1108 if (*client_param->is_null)
1109 param->set_null();
1110 else
1111 {
1112 uchar *buff= (uchar*) client_param->buffer;
1113 param->unsigned_flag= client_param->is_unsigned;
1114 param->set_param_func(&buff,
1115 client_param->length ?
1116 *client_param->length :
1117 client_param->buffer_length);
1118 if (param->has_no_value())
1119 DBUG_RETURN(1);
1120 }
1121 param->sync_clones();
1122 }
1123 if (param->convert_str_value(thd))
1124 DBUG_RETURN(1); /* out of memory */
1125 }
1126 DBUG_RETURN(0);
1127 }
1128
1129
emb_insert_params_with_log(Prepared_statement * stmt,String * query)1130 static bool emb_insert_params_with_log(Prepared_statement *stmt, String *query)
1131 {
1132 THD *thd= stmt->thd;
1133 Item_param **it= stmt->param_array;
1134 Item_param **end= it + stmt->param_count;
1135 MYSQL_BIND *client_param= thd->client_params;
1136 Copy_query_with_rewrite acc(thd, stmt->query(), stmt->query_length(), query);
1137 DBUG_ENTER("emb_insert_params_with_log");
1138
1139 for (; it < end; ++it, ++client_param)
1140 {
1141 Item_param *param= *it;
1142 param->setup_conversion(thd, client_param->buffer_type);
1143 if (!param->has_long_data_value())
1144 {
1145 if (*client_param->is_null)
1146 param->set_null();
1147 else
1148 {
1149 uchar *buff= (uchar*)client_param->buffer;
1150 param->unsigned_flag= client_param->is_unsigned;
1151 param->set_param_func(&buff,
1152 client_param->length ?
1153 *client_param->length :
1154 client_param->buffer_length);
1155 if (param->has_no_value())
1156 DBUG_RETURN(1);
1157 }
1158 }
1159 if (acc.append(param))
1160 DBUG_RETURN(1);
1161
1162 if (param->convert_str_value(thd))
1163 DBUG_RETURN(1); /* out of memory */
1164 param->sync_clones();
1165 }
1166 if (acc.finalize())
1167 DBUG_RETURN(1);
1168
1169 DBUG_RETURN(0);
1170 }
1171
1172 #endif /*!EMBEDDED_LIBRARY*/
1173
1174 /**
1175 Setup data conversion routines using an array of parameter
1176 markers from the original prepared statement.
1177 Swap the parameter data of the original prepared
1178 statement to the new one.
1179
1180 Used only when we re-prepare a prepared statement.
1181 There are two reasons for this function to exist:
1182
1183 1) In the binary client/server protocol, parameter metadata
1184 is sent only at first execute. Consequently, if we need to
1185 reprepare a prepared statement at a subsequent execution,
1186 we may not have metadata information in the packet.
1187 In that case we use the parameter array of the original
1188 prepared statement to setup parameter types of the new
1189 prepared statement.
1190
1191 2) In the binary client/server protocol, we may supply
1192 long data in pieces. When the last piece is supplied,
1193 we assemble the pieces and convert them from client
1194 character set to the connection character set. After
1195 that the parameter value is only available inside
1196 the parameter, the original pieces are lost, and thus
1197 we can only assign the corresponding parameter of the
1198 reprepared statement from the original value.
1199
1200 @param[out] param_array_dst parameter markers of the new statement
1201 @param[in] param_array_src parameter markers of the original
1202 statement
1203 @param[in] param_count total number of parameters. Is the
1204 same in src and dst arrays, since
1205 the statement query is the same
1206
1207 @return this function never fails
1208 */
1209
1210 static void
swap_parameter_array(Item_param ** param_array_dst,Item_param ** param_array_src,uint param_count)1211 swap_parameter_array(Item_param **param_array_dst,
1212 Item_param **param_array_src,
1213 uint param_count)
1214 {
1215 Item_param **dst= param_array_dst;
1216 Item_param **src= param_array_src;
1217 Item_param **end= param_array_dst + param_count;
1218
1219 for (; dst < end; ++src, ++dst)
1220 {
1221 (*dst)->set_param_type_and_swap_value(*src);
1222 (*dst)->sync_clones();
1223 (*src)->sync_clones();
1224 }
1225 }
1226
1227
1228 /**
1229 Assign prepared statement parameters from user variables.
1230
1231 @param stmt Statement
1232 @param params A list of parameters. Caller must ensure that number
1233 of parameters in the list is equal to number of statement
1234 parameters
1235 @param query Ignored
1236 */
1237
1238 static bool
insert_params_from_actual_params(Prepared_statement * stmt,List<Item> & params,String * query)1239 insert_params_from_actual_params(Prepared_statement *stmt,
1240 List<Item> ¶ms,
1241 String *query __attribute__((unused)))
1242 {
1243 Item_param **begin= stmt->param_array;
1244 Item_param **end= begin + stmt->param_count;
1245 List_iterator<Item> param_it(params);
1246 DBUG_ENTER("insert_params_from_actual_params");
1247
1248 for (Item_param **it= begin; it < end; ++it)
1249 {
1250 Item_param *param= *it;
1251 Item *ps_param= param_it++;
1252 if (ps_param->save_in_param(stmt->thd, param) ||
1253 param->convert_str_value(stmt->thd))
1254 DBUG_RETURN(1);
1255 param->sync_clones();
1256 }
1257 DBUG_RETURN(0);
1258 }
1259
1260
1261 /**
1262 Do the same as insert_params_from_actual_params
1263 but also construct query text for binary log.
1264
1265 @param stmt Prepared statement
1266 @param params A list of parameters. Caller must ensure that number of
1267 parameters in the list is equal to number of statement
1268 parameters
1269 @param query The query with parameter markers replaced with corresponding
1270 user variables that were used to execute the query.
1271 */
1272
1273 static bool
insert_params_from_actual_params_with_log(Prepared_statement * stmt,List<Item> & params,String * query)1274 insert_params_from_actual_params_with_log(Prepared_statement *stmt,
1275 List<Item> ¶ms,
1276 String *query)
1277 {
1278 Item_param **begin= stmt->param_array;
1279 Item_param **end= begin + stmt->param_count;
1280 List_iterator<Item> param_it(params);
1281 THD *thd= stmt->thd;
1282 Copy_query_with_rewrite acc(thd, stmt->query(), stmt->query_length(), query);
1283
1284 DBUG_ENTER("insert_params_from_actual_params_with_log");
1285
1286 for (Item_param **it= begin; it < end; ++it)
1287 {
1288 Item_param *param= *it;
1289 Item *ps_param= param_it++;
1290 if (ps_param->save_in_param(thd, param))
1291 DBUG_RETURN(1);
1292
1293 if (acc.append(param))
1294 DBUG_RETURN(1);
1295
1296 if (param->convert_str_value(thd))
1297 DBUG_RETURN(1);
1298
1299 param->sync_clones();
1300 }
1301 if (acc.finalize())
1302 DBUG_RETURN(1);
1303
1304 DBUG_RETURN(0);
1305 }
1306
1307 /**
1308 Validate INSERT statement.
1309
1310 @param stmt prepared statement
1311 @param tables global/local table list
1312
1313 @retval
1314 FALSE success
1315 @retval
1316 TRUE error, error message is set in THD
1317 */
1318
mysql_test_insert(Prepared_statement * stmt,TABLE_LIST * table_list,List<Item> & fields,List<List_item> & values_list,List<Item> & update_fields,List<Item> & update_values,enum_duplicates duplic)1319 static bool mysql_test_insert(Prepared_statement *stmt,
1320 TABLE_LIST *table_list,
1321 List<Item> &fields,
1322 List<List_item> &values_list,
1323 List<Item> &update_fields,
1324 List<Item> &update_values,
1325 enum_duplicates duplic)
1326 {
1327 THD *thd= stmt->thd;
1328 List_iterator_fast<List_item> its(values_list);
1329 List_item *values;
1330 DBUG_ENTER("mysql_test_insert");
1331
1332 /*
1333 Since INSERT DELAYED doesn't support temporary tables, we could
1334 not pre-open temporary tables for SQLCOM_INSERT / SQLCOM_REPLACE.
1335 Open them here instead.
1336 */
1337 if (table_list->lock_type != TL_WRITE_DELAYED)
1338 {
1339 if (thd->open_temporary_tables(table_list))
1340 goto error;
1341 }
1342
1343 if (insert_precheck(thd, table_list))
1344 goto error;
1345
1346 //upgrade_lock_type_for_insert(thd, &table_list->lock_type, duplic,
1347 // values_list.elements > 1);
1348 /*
1349 open temporary memory pool for temporary data allocated by derived
1350 tables & preparation procedure
1351 Note that this is done without locks (should not be needed as we will not
1352 access any data here)
1353 If we would use locks, then we have to ensure we are not using
1354 TL_WRITE_DELAYED as having two such locks can cause table corruption.
1355 */
1356 if (open_normal_and_derived_tables(thd, table_list,
1357 MYSQL_OPEN_FORCE_SHARED_MDL, DT_INIT))
1358 goto error;
1359
1360 if ((values= its++))
1361 {
1362 uint value_count;
1363 ulong counter= 0;
1364 Item *unused_conds= 0;
1365
1366 if (table_list->table)
1367 {
1368 // don't allocate insert_values
1369 table_list->table->insert_values=(uchar *)1;
1370 }
1371
1372 if (mysql_prepare_insert(thd, table_list, table_list->table,
1373 fields, values, update_fields, update_values,
1374 duplic, &unused_conds, FALSE))
1375 goto error;
1376
1377 value_count= values->elements;
1378 its.rewind();
1379
1380 if (table_list->lock_type == TL_WRITE_DELAYED &&
1381 !(table_list->table->file->ha_table_flags() & HA_CAN_INSERT_DELAYED))
1382 {
1383 my_error(ER_DELAYED_NOT_SUPPORTED, MYF(0), (table_list->view ?
1384 table_list->view_name.str :
1385 table_list->table_name.str));
1386 goto error;
1387 }
1388 while ((values= its++))
1389 {
1390 counter++;
1391 if (values->elements != value_count)
1392 {
1393 my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter);
1394 goto error;
1395 }
1396 if (setup_fields(thd, Ref_ptr_array(),
1397 *values, COLUMNS_READ, 0, NULL, 0))
1398 goto error;
1399 }
1400 }
1401 DBUG_RETURN(FALSE);
1402
1403 error:
1404 /* insert_values is cleared in open_table */
1405 DBUG_RETURN(TRUE);
1406 }
1407
1408
1409 /**
1410 Validate UPDATE statement.
1411
1412 @param stmt prepared statement
1413 @param tables list of tables used in this query
1414
1415 @todo
1416 - here we should send types of placeholders to the client.
1417
1418 @retval
1419 0 success
1420 @retval
1421 1 error, error message is set in THD
1422 @retval
1423 2 convert to multi_update
1424 */
1425
mysql_test_update(Prepared_statement * stmt,TABLE_LIST * table_list)1426 static int mysql_test_update(Prepared_statement *stmt,
1427 TABLE_LIST *table_list)
1428 {
1429 int res;
1430 THD *thd= stmt->thd;
1431 uint table_count= 0;
1432 TABLE_LIST *update_source_table;
1433 SELECT_LEX *select= stmt->lex->first_select_lex();
1434 #ifndef NO_EMBEDDED_ACCESS_CHECKS
1435 uint want_privilege;
1436 #endif
1437 DBUG_ENTER("mysql_test_update");
1438
1439 if (update_precheck(thd, table_list) ||
1440 open_tables(thd, &table_list, &table_count, MYSQL_OPEN_FORCE_SHARED_MDL))
1441 goto error;
1442
1443 if (mysql_handle_derived(thd->lex, DT_INIT))
1444 goto error;
1445
1446 if (((update_source_table= unique_table(thd, table_list,
1447 table_list->next_global, 0)) ||
1448 table_list->is_multitable()))
1449 {
1450 DBUG_ASSERT(update_source_table || table_list->view != 0);
1451 DBUG_PRINT("info", ("Switch to multi-update"));
1452 /* pass counter value */
1453 thd->lex->table_count= table_count;
1454 /* convert to multiupdate */
1455 DBUG_RETURN(2);
1456 }
1457
1458 /*
1459 thd->fill_derived_tables() is false here for sure (because it is
1460 preparation of PS, so we even do not check it).
1461 */
1462 if (table_list->handle_derived(thd->lex, DT_MERGE_FOR_INSERT))
1463 goto error;
1464 if (table_list->handle_derived(thd->lex, DT_PREPARE))
1465 goto error;
1466
1467 if (!table_list->single_table_updatable())
1468 {
1469 my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias.str, "UPDATE");
1470 goto error;
1471 }
1472
1473 #ifndef NO_EMBEDDED_ACCESS_CHECKS
1474 /* Force privilege re-checking for views after they have been opened. */
1475 want_privilege= (table_list->view ? UPDATE_ACL :
1476 table_list->grant.want_privilege);
1477 #endif
1478
1479 if (mysql_prepare_update(thd, table_list, &select->where,
1480 select->order_list.elements,
1481 select->order_list.first))
1482 goto error;
1483
1484 #ifndef NO_EMBEDDED_ACCESS_CHECKS
1485 table_list->grant.want_privilege= want_privilege;
1486 table_list->table->grant.want_privilege= want_privilege;
1487 table_list->register_want_access(want_privilege);
1488 #endif
1489 thd->lex->first_select_lex()->no_wrap_view_item= TRUE;
1490 res= setup_fields(thd, Ref_ptr_array(),
1491 select->item_list, MARK_COLUMNS_READ, 0, NULL, 0);
1492 thd->lex->first_select_lex()->no_wrap_view_item= FALSE;
1493 if (res)
1494 goto error;
1495 #ifndef NO_EMBEDDED_ACCESS_CHECKS
1496 /* Check values */
1497 table_list->grant.want_privilege=
1498 table_list->table->grant.want_privilege=
1499 (SELECT_ACL & ~table_list->table->grant.privilege);
1500 table_list->register_want_access(SELECT_ACL);
1501 #endif
1502 if (setup_fields(thd, Ref_ptr_array(),
1503 stmt->lex->value_list, COLUMNS_READ, 0, NULL, 0) ||
1504 check_unique_table(thd, table_list))
1505 goto error;
1506 /* TODO: here we should send types of placeholders to the client. */
1507 DBUG_RETURN(0);
1508 error:
1509 DBUG_RETURN(1);
1510 }
1511
1512
1513 /**
1514 Validate DELETE statement.
1515
1516 @param stmt prepared statement
1517 @param tables list of tables used in this query
1518
1519 @retval
1520 FALSE success
1521 @retval
1522 TRUE error, error message is set in THD
1523 */
1524
mysql_test_delete(Prepared_statement * stmt,TABLE_LIST * table_list)1525 static bool mysql_test_delete(Prepared_statement *stmt,
1526 TABLE_LIST *table_list)
1527 {
1528 uint table_count= 0;
1529 THD *thd= stmt->thd;
1530 LEX *lex= stmt->lex;
1531 bool delete_while_scanning;
1532 DBUG_ENTER("mysql_test_delete");
1533
1534 if (delete_precheck(thd, table_list) ||
1535 open_tables(thd, &table_list, &table_count, MYSQL_OPEN_FORCE_SHARED_MDL))
1536 goto error;
1537
1538 if (mysql_handle_derived(thd->lex, DT_INIT))
1539 goto error;
1540 if (mysql_handle_derived(thd->lex, DT_MERGE_FOR_INSERT))
1541 goto error;
1542 if (mysql_handle_derived(thd->lex, DT_PREPARE))
1543 goto error;
1544
1545 if (!table_list->single_table_updatable())
1546 {
1547 my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias.str, "DELETE");
1548 goto error;
1549 }
1550 if (!table_list->table || !table_list->table->is_created())
1551 {
1552 my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0),
1553 table_list->view_db.str, table_list->view_name.str);
1554 goto error;
1555 }
1556
1557 DBUG_RETURN(mysql_prepare_delete(thd, table_list,
1558 lex->first_select_lex()->with_wild,
1559 lex->first_select_lex()->item_list,
1560 &lex->first_select_lex()->where,
1561 &delete_while_scanning));
1562 error:
1563 DBUG_RETURN(TRUE);
1564 }
1565
1566
1567 /**
1568 Validate SELECT statement.
1569
1570 In case of success, if this query is not EXPLAIN, send column list info
1571 back to the client.
1572
1573 @param stmt prepared statement
1574 @param tables list of tables used in the query
1575
1576 @retval
1577 0 success
1578 @retval
1579 1 error, error message is set in THD
1580 @retval
1581 2 success, and statement metadata has been sent
1582 */
1583
mysql_test_select(Prepared_statement * stmt,TABLE_LIST * tables)1584 static int mysql_test_select(Prepared_statement *stmt,
1585 TABLE_LIST *tables)
1586 {
1587 THD *thd= stmt->thd;
1588 LEX *lex= stmt->lex;
1589 SELECT_LEX_UNIT *unit= &lex->unit;
1590 DBUG_ENTER("mysql_test_select");
1591
1592 lex->first_select_lex()->context.resolve_in_select_list= TRUE;
1593
1594 ulong privilege= lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL;
1595 if (tables)
1596 {
1597 if (check_table_access(thd, privilege, tables, FALSE, UINT_MAX, FALSE))
1598 goto error;
1599 }
1600 else if (check_access(thd, privilege, any_db, NULL, NULL, 0, 0))
1601 goto error;
1602
1603 if (!lex->result && !(lex->result= new (stmt->mem_root) select_send(thd)))
1604 {
1605 my_error(ER_OUTOFMEMORY, MYF(ME_FATAL),
1606 static_cast<int>(sizeof(select_send)));
1607 goto error;
1608 }
1609
1610 if (open_normal_and_derived_tables(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL,
1611 DT_INIT | DT_PREPARE))
1612 goto error;
1613
1614 thd->lex->used_tables= 0; // Updated by setup_fields
1615
1616 /*
1617 JOIN::prepare calls
1618 It is not SELECT COMMAND for sure, so setup_tables will be called as
1619 usual, and we pass 0 as setup_tables_done_option
1620 */
1621 if (unit->prepare(unit->derived, 0, 0))
1622 goto error;
1623 if (!lex->describe && !thd->lex->analyze_stmt && !stmt->is_sql_prepare())
1624 {
1625 /* Make copy of item list, as change_columns may change it */
1626 SELECT_LEX_UNIT* master_unit= unit->first_select()->master_unit();
1627 bool is_union_op=
1628 master_unit->is_unit_op() || master_unit->fake_select_lex;
1629
1630 List<Item> fields(is_union_op ? unit->item_list :
1631 lex->first_select_lex()->item_list);
1632
1633 /* Change columns if a procedure like analyse() */
1634 if (unit->last_procedure && unit->last_procedure->change_columns(thd, fields))
1635 goto error;
1636
1637 /*
1638 We can use lex->result as it should've been prepared in
1639 unit->prepare call above.
1640 */
1641 if (send_prep_stmt(stmt, lex->result->field_count(fields)) ||
1642 lex->result->send_result_set_metadata(fields, Protocol::SEND_EOF) ||
1643 thd->protocol->flush())
1644 goto error;
1645 DBUG_RETURN(2);
1646 }
1647 DBUG_RETURN(0);
1648 error:
1649 DBUG_RETURN(1);
1650 }
1651
1652
1653 /**
1654 Validate and prepare for execution DO statement expressions.
1655
1656 @param stmt prepared statement
1657 @param tables list of tables used in this query
1658 @param values list of expressions
1659
1660 @retval
1661 FALSE success
1662 @retval
1663 TRUE error, error message is set in THD
1664 */
1665
mysql_test_do_fields(Prepared_statement * stmt,TABLE_LIST * tables,List<Item> * values)1666 static bool mysql_test_do_fields(Prepared_statement *stmt,
1667 TABLE_LIST *tables,
1668 List<Item> *values)
1669 {
1670 THD *thd= stmt->thd;
1671
1672 DBUG_ENTER("mysql_test_do_fields");
1673 if (tables && check_table_access(thd, SELECT_ACL, tables, FALSE,
1674 UINT_MAX, FALSE))
1675 DBUG_RETURN(TRUE);
1676
1677 if (open_normal_and_derived_tables(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL,
1678 DT_INIT | DT_PREPARE))
1679 DBUG_RETURN(TRUE);
1680 DBUG_RETURN(setup_fields(thd, Ref_ptr_array(),
1681 *values, COLUMNS_READ, 0, NULL, 0));
1682 }
1683
1684
1685 /**
1686 Validate and prepare for execution SET statement expressions.
1687
1688 @param stmt prepared statement
1689 @param tables list of tables used in this query
1690 @param values list of expressions
1691
1692 @retval
1693 FALSE success
1694 @retval
1695 TRUE error, error message is set in THD
1696 */
1697
mysql_test_set_fields(Prepared_statement * stmt,TABLE_LIST * tables,List<set_var_base> * var_list)1698 static bool mysql_test_set_fields(Prepared_statement *stmt,
1699 TABLE_LIST *tables,
1700 List<set_var_base> *var_list)
1701 {
1702 DBUG_ENTER("mysql_test_set_fields");
1703 List_iterator_fast<set_var_base> it(*var_list);
1704 THD *thd= stmt->thd;
1705 set_var_base *var;
1706
1707 if ((tables &&
1708 check_table_access(thd, SELECT_ACL, tables, FALSE, UINT_MAX, FALSE)) ||
1709 open_normal_and_derived_tables(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL,
1710 DT_INIT | DT_PREPARE))
1711 goto error;
1712
1713 while ((var= it++))
1714 {
1715 if (var->light_check(thd))
1716 goto error;
1717 }
1718 DBUG_RETURN(FALSE);
1719 error:
1720 DBUG_RETURN(TRUE);
1721 }
1722
1723
1724 /**
1725 Validate and prepare for execution CALL statement expressions.
1726
1727 @param stmt prepared statement
1728 @param tables list of tables used in this query
1729 @param value_list list of expressions
1730
1731 @retval FALSE success
1732 @retval TRUE error, error message is set in THD
1733 */
1734
mysql_test_call_fields(Prepared_statement * stmt,TABLE_LIST * tables,List<Item> * value_list)1735 static bool mysql_test_call_fields(Prepared_statement *stmt,
1736 TABLE_LIST *tables,
1737 List<Item> *value_list)
1738 {
1739 DBUG_ENTER("mysql_test_call_fields");
1740
1741 List_iterator<Item> it(*value_list);
1742 THD *thd= stmt->thd;
1743 Item *item;
1744
1745 if ((tables &&
1746 check_table_access(thd, SELECT_ACL, tables, FALSE, UINT_MAX, FALSE)) ||
1747 open_normal_and_derived_tables(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL,
1748 DT_INIT | DT_PREPARE))
1749 goto err;
1750
1751 while ((item= it++))
1752 {
1753 if (item->fix_fields_if_needed(thd, it.ref()))
1754 goto err;
1755 }
1756 DBUG_RETURN(FALSE);
1757 err:
1758 DBUG_RETURN(TRUE);
1759 }
1760
1761
1762 /**
1763 Check internal SELECT of the prepared command.
1764
1765 @param stmt prepared statement
1766 @param specific_prepare function of command specific prepare
1767 @param setup_tables_done_option options to be passed to LEX::unit.prepare()
1768
1769 @note
1770 This function won't directly open tables used in select. They should
1771 be opened either by calling function (and in this case you probably
1772 should use select_like_stmt_test_with_open()) or by
1773 "specific_prepare" call (like this happens in case of multi-update).
1774
1775 @retval
1776 FALSE success
1777 @retval
1778 TRUE error, error message is set in THD
1779 */
1780
select_like_stmt_test(Prepared_statement * stmt,int (* specific_prepare)(THD * thd),ulong setup_tables_done_option)1781 static bool select_like_stmt_test(Prepared_statement *stmt,
1782 int (*specific_prepare)(THD *thd),
1783 ulong setup_tables_done_option)
1784 {
1785 DBUG_ENTER("select_like_stmt_test");
1786 THD *thd= stmt->thd;
1787 LEX *lex= stmt->lex;
1788
1789 lex->first_select_lex()->context.resolve_in_select_list= TRUE;
1790
1791 if (specific_prepare && (*specific_prepare)(thd))
1792 DBUG_RETURN(TRUE);
1793
1794 thd->lex->used_tables= 0; // Updated by setup_fields
1795
1796 /* Calls JOIN::prepare */
1797 DBUG_RETURN(lex->unit.prepare(lex->unit.derived, 0, setup_tables_done_option));
1798 }
1799
1800 /**
1801 Check internal SELECT of the prepared command (with opening of used
1802 tables).
1803
1804 @param stmt prepared statement
1805 @param tables list of tables to be opened
1806 before calling specific_prepare function
1807 @param specific_prepare function of command specific prepare
1808 @param setup_tables_done_option options to be passed to LEX::unit.prepare()
1809
1810 @retval
1811 FALSE success
1812 @retval
1813 TRUE error
1814 */
1815
1816 static bool
select_like_stmt_test_with_open(Prepared_statement * stmt,TABLE_LIST * tables,int (* specific_prepare)(THD * thd),ulong setup_tables_done_option)1817 select_like_stmt_test_with_open(Prepared_statement *stmt,
1818 TABLE_LIST *tables,
1819 int (*specific_prepare)(THD *thd),
1820 ulong setup_tables_done_option)
1821 {
1822 uint table_count= 0;
1823 DBUG_ENTER("select_like_stmt_test_with_open");
1824
1825 /*
1826 We should not call LEX::unit.cleanup() after this
1827 open_normal_and_derived_tables() call because we don't allow
1828 prepared EXPLAIN yet so derived tables will clean up after
1829 themself.
1830 */
1831 THD *thd= stmt->thd;
1832 if (open_tables(thd, &tables, &table_count, MYSQL_OPEN_FORCE_SHARED_MDL))
1833 DBUG_RETURN(TRUE);
1834
1835 DBUG_RETURN(select_like_stmt_test(stmt, specific_prepare,
1836 setup_tables_done_option));
1837 }
1838
1839
1840 /**
1841 Validate and prepare for execution CREATE TABLE statement.
1842
1843 @param stmt prepared statement
1844 @param tables list of tables used in this query
1845
1846 @retval
1847 FALSE success
1848 @retval
1849 TRUE error, error message is set in THD
1850 */
1851
mysql_test_create_table(Prepared_statement * stmt)1852 static bool mysql_test_create_table(Prepared_statement *stmt)
1853 {
1854 DBUG_ENTER("mysql_test_create_table");
1855 THD *thd= stmt->thd;
1856 LEX *lex= stmt->lex;
1857 SELECT_LEX *select_lex= lex->first_select_lex();
1858 bool res= FALSE;
1859 bool link_to_local;
1860 TABLE_LIST *create_table= lex->query_tables;
1861 TABLE_LIST *tables= lex->create_last_non_select_table->next_global;
1862
1863 if (create_table_precheck(thd, tables, create_table))
1864 DBUG_RETURN(TRUE);
1865
1866 if (select_lex->item_list.elements)
1867 {
1868 /* Base table and temporary table are not in the same name space. */
1869 if (!lex->create_info.tmp_table())
1870 create_table->open_type= OT_BASE_ONLY;
1871
1872 if (open_normal_and_derived_tables(stmt->thd, lex->query_tables,
1873 MYSQL_OPEN_FORCE_SHARED_MDL,
1874 DT_INIT | DT_PREPARE))
1875 DBUG_RETURN(TRUE);
1876
1877 select_lex->context.resolve_in_select_list= TRUE;
1878
1879 lex->unlink_first_table(&link_to_local);
1880
1881 res= select_like_stmt_test(stmt, 0, 0);
1882
1883 lex->link_first_table_back(create_table, link_to_local);
1884 }
1885 else
1886 {
1887 /*
1888 Check that the source table exist, and also record
1889 its metadata version. Even though not strictly necessary,
1890 we validate metadata of all CREATE TABLE statements,
1891 which keeps metadata validation code simple.
1892 */
1893 if (open_normal_and_derived_tables(stmt->thd, lex->query_tables,
1894 MYSQL_OPEN_FORCE_SHARED_MDL,
1895 DT_INIT | DT_PREPARE))
1896 DBUG_RETURN(TRUE);
1897 }
1898
1899 DBUG_RETURN(res);
1900 }
1901
1902
send_stmt_metadata(THD * thd,Prepared_statement * stmt,List<Item> * fields)1903 static int send_stmt_metadata(THD *thd, Prepared_statement *stmt, List<Item> *fields)
1904 {
1905 if (stmt->is_sql_prepare())
1906 return 0;
1907
1908 if (send_prep_stmt(stmt, fields->elements) ||
1909 thd->protocol->send_result_set_metadata(fields, Protocol::SEND_EOF) ||
1910 thd->protocol->flush())
1911 return 1;
1912
1913 return 2;
1914 }
1915
1916
1917 /**
1918 Validate and prepare for execution SHOW CREATE TABLE statement.
1919
1920 @param stmt prepared statement
1921 @param tables list of tables used in this query
1922
1923 @retval
1924 FALSE success
1925 @retval
1926 TRUE error, error message is set in THD
1927 */
1928
mysql_test_show_create_table(Prepared_statement * stmt,TABLE_LIST * tables)1929 static int mysql_test_show_create_table(Prepared_statement *stmt,
1930 TABLE_LIST *tables)
1931 {
1932 DBUG_ENTER("mysql_test_show_create_table");
1933 THD *thd= stmt->thd;
1934 List<Item> fields;
1935 char buff[2048];
1936 String buffer(buff, sizeof(buff), system_charset_info);
1937
1938 if (mysqld_show_create_get_fields(thd, tables, &fields, &buffer))
1939 DBUG_RETURN(1);
1940
1941 DBUG_RETURN(send_stmt_metadata(thd, stmt, &fields));
1942 }
1943
1944
1945 /**
1946 Validate and prepare for execution SHOW CREATE DATABASE statement.
1947
1948 @param stmt prepared statement
1949
1950 @retval
1951 FALSE success
1952 @retval
1953 TRUE error, error message is set in THD
1954 */
1955
mysql_test_show_create_db(Prepared_statement * stmt)1956 static int mysql_test_show_create_db(Prepared_statement *stmt)
1957 {
1958 DBUG_ENTER("mysql_test_show_create_db");
1959 THD *thd= stmt->thd;
1960 List<Item> fields;
1961
1962 mysqld_show_create_db_get_fields(thd, &fields);
1963
1964 DBUG_RETURN(send_stmt_metadata(thd, stmt, &fields));
1965 }
1966
1967
1968 #ifndef NO_EMBEDDED_ACCESS_CHECKS
1969 /**
1970 Validate and prepare for execution SHOW GRANTS statement.
1971
1972 @param stmt prepared statement
1973
1974 @retval
1975 FALSE success
1976 @retval
1977 TRUE error, error message is set in THD
1978 */
1979
mysql_test_show_grants(Prepared_statement * stmt)1980 static int mysql_test_show_grants(Prepared_statement *stmt)
1981 {
1982 DBUG_ENTER("mysql_test_show_grants");
1983 THD *thd= stmt->thd;
1984 List<Item> fields;
1985 char buff[1024];
1986 const char *username= NULL, *hostname= NULL, *rolename= NULL, *end;
1987
1988 if (get_show_user(thd, thd->lex->grant_user, &username, &hostname, &rolename))
1989 DBUG_RETURN(1);
1990
1991 if (username)
1992 end= strxmov(buff,"Grants for ",username,"@",hostname, NullS);
1993 else if (rolename)
1994 end= strxmov(buff,"Grants for ",rolename, NullS);
1995 else
1996 DBUG_RETURN(1);
1997
1998 mysql_show_grants_get_fields(thd, &fields, buff, (uint)(end - buff));
1999 DBUG_RETURN(send_stmt_metadata(thd, stmt, &fields));
2000 }
2001 #endif /*NO_EMBEDDED_ACCESS_CHECKS*/
2002
2003
2004 #ifndef EMBEDDED_LIBRARY
2005 /**
2006 Validate and prepare for execution SHOW SLAVE STATUS statement.
2007
2008 @param stmt prepared statement
2009
2010 @retval
2011 FALSE success
2012 @retval
2013 TRUE error, error message is set in THD
2014 */
2015
mysql_test_show_slave_status(Prepared_statement * stmt)2016 static int mysql_test_show_slave_status(Prepared_statement *stmt)
2017 {
2018 DBUG_ENTER("mysql_test_show_slave_status");
2019 THD *thd= stmt->thd;
2020 List<Item> fields;
2021
2022 show_master_info_get_fields(thd, &fields, thd->lex->verbose, 0);
2023
2024 DBUG_RETURN(send_stmt_metadata(thd, stmt, &fields));
2025 }
2026
2027
2028 /**
2029 Validate and prepare for execution SHOW MASTER STATUS statement.
2030
2031 @param stmt prepared statement
2032
2033 @retval
2034 FALSE success
2035 @retval
2036 TRUE error, error message is set in THD
2037 */
2038
mysql_test_show_master_status(Prepared_statement * stmt)2039 static int mysql_test_show_master_status(Prepared_statement *stmt)
2040 {
2041 DBUG_ENTER("mysql_test_show_master_status");
2042 THD *thd= stmt->thd;
2043 List<Item> fields;
2044
2045 show_binlog_info_get_fields(thd, &fields);
2046
2047 DBUG_RETURN(send_stmt_metadata(thd, stmt, &fields));
2048 }
2049
2050
2051 /**
2052 Validate and prepare for execution SHOW BINLOGS statement.
2053
2054 @param stmt prepared statement
2055
2056 @retval
2057 FALSE success
2058 @retval
2059 TRUE error, error message is set in THD
2060 */
2061
mysql_test_show_binlogs(Prepared_statement * stmt)2062 static int mysql_test_show_binlogs(Prepared_statement *stmt)
2063 {
2064 DBUG_ENTER("mysql_test_show_binlogs");
2065 THD *thd= stmt->thd;
2066 List<Item> fields;
2067
2068 show_binlogs_get_fields(thd, &fields);
2069
2070 DBUG_RETURN(send_stmt_metadata(thd, stmt, &fields));
2071 }
2072
2073 #endif /* EMBEDDED_LIBRARY */
2074
2075
2076 /**
2077 Validate and prepare for execution SHOW CREATE PROC/FUNC statement.
2078
2079 @param stmt prepared statement
2080
2081 @retval
2082 FALSE success
2083 @retval
2084 TRUE error, error message is set in THD
2085 */
2086
mysql_test_show_create_routine(Prepared_statement * stmt,const Sp_handler * sph)2087 static int mysql_test_show_create_routine(Prepared_statement *stmt,
2088 const Sp_handler *sph)
2089 {
2090 DBUG_ENTER("mysql_test_show_binlogs");
2091 THD *thd= stmt->thd;
2092 List<Item> fields;
2093
2094 sp_head::show_create_routine_get_fields(thd, sph, &fields);
2095
2096 DBUG_RETURN(send_stmt_metadata(thd, stmt, &fields));
2097 }
2098
2099
2100 /**
2101 @brief Validate and prepare for execution CREATE VIEW statement
2102
2103 @param stmt prepared statement
2104
2105 @note This function handles create view commands.
2106
2107 @retval FALSE Operation was a success.
2108 @retval TRUE An error occurred.
2109 */
2110
mysql_test_create_view(Prepared_statement * stmt)2111 static bool mysql_test_create_view(Prepared_statement *stmt)
2112 {
2113 DBUG_ENTER("mysql_test_create_view");
2114 THD *thd= stmt->thd;
2115 LEX *lex= stmt->lex;
2116 bool res= TRUE;
2117 /* Skip first table, which is the view we are creating */
2118 bool link_to_local;
2119 TABLE_LIST *view= lex->unlink_first_table(&link_to_local);
2120 TABLE_LIST *tables= lex->query_tables;
2121
2122 if (create_view_precheck(thd, tables, view, lex->create_view->mode))
2123 goto err;
2124
2125 /*
2126 Since we can't pre-open temporary tables for SQLCOM_CREATE_VIEW,
2127 (see mysql_create_view) we have to do it here instead.
2128 */
2129 if (thd->open_temporary_tables(tables))
2130 goto err;
2131
2132 lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW;
2133 if (open_normal_and_derived_tables(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL,
2134 DT_INIT | DT_PREPARE))
2135 goto err;
2136
2137 res= select_like_stmt_test(stmt, 0, 0);
2138
2139 err:
2140 /* put view back for PS rexecuting */
2141 lex->link_first_table_back(view, link_to_local);
2142 DBUG_RETURN(res);
2143 }
2144
2145
2146 /*
2147 Validate and prepare for execution a multi update statement.
2148
2149 @param stmt prepared statement
2150 @param tables list of tables used in this query
2151 @param converted converted to multi-update from usual update
2152
2153 @retval
2154 FALSE success
2155 @retval
2156 TRUE error, error message is set in THD
2157 */
2158
mysql_test_multiupdate(Prepared_statement * stmt,TABLE_LIST * tables,bool converted)2159 static bool mysql_test_multiupdate(Prepared_statement *stmt,
2160 TABLE_LIST *tables,
2161 bool converted)
2162 {
2163 /* if we switched from normal update, rights are checked */
2164 if (!converted && multi_update_precheck(stmt->thd, tables))
2165 return TRUE;
2166
2167 return select_like_stmt_test(stmt, &mysql_multi_update_prepare,
2168 OPTION_SETUP_TABLES_DONE);
2169 }
2170
2171
2172 /**
2173 Validate and prepare for execution a multi delete statement.
2174
2175 @param stmt prepared statement
2176 @param tables list of tables used in this query
2177
2178 @retval
2179 FALSE success
2180 @retval
2181 TRUE error, error message in THD is set.
2182 */
2183
mysql_test_multidelete(Prepared_statement * stmt,TABLE_LIST * tables)2184 static bool mysql_test_multidelete(Prepared_statement *stmt,
2185 TABLE_LIST *tables)
2186 {
2187 THD *thd= stmt->thd;
2188
2189 thd->lex->current_select= thd->lex->first_select_lex();
2190 if (add_item_to_list(thd, new (thd->mem_root)
2191 Item_null(thd)))
2192 {
2193 my_error(ER_OUTOFMEMORY, MYF(ME_FATAL), 0);
2194 goto error;
2195 }
2196
2197 if (multi_delete_precheck(thd, tables) ||
2198 select_like_stmt_test_with_open(stmt, tables,
2199 &mysql_multi_delete_prepare,
2200 OPTION_SETUP_TABLES_DONE))
2201 goto error;
2202 if (!tables->table)
2203 {
2204 my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0),
2205 tables->view_db.str, tables->view_name.str);
2206 goto error;
2207 }
2208 return FALSE;
2209 error:
2210 return TRUE;
2211 }
2212
2213
2214 /**
2215 Wrapper for mysql_insert_select_prepare, to make change of local tables
2216 after open_normal_and_derived_tables() call.
2217
2218 @param thd thread handle
2219
2220 @note
2221 We need to remove the first local table after
2222 open_normal_and_derived_tables(), because mysql_handle_derived
2223 uses local tables lists.
2224 */
2225
mysql_insert_select_prepare_tester(THD * thd)2226 static int mysql_insert_select_prepare_tester(THD *thd)
2227 {
2228 SELECT_LEX *first_select= thd->lex->first_select_lex();
2229 TABLE_LIST *second_table= first_select->table_list.first->next_local;
2230
2231 /* Skip first table, which is the table we are inserting in */
2232 first_select->table_list.first= second_table;
2233 thd->lex->first_select_lex()->context.table_list=
2234 thd->lex->first_select_lex()->context.first_name_resolution_table=
2235 second_table;
2236
2237 return mysql_insert_select_prepare(thd);
2238 }
2239
2240
2241 /**
2242 Validate and prepare for execution INSERT ... SELECT statement.
2243
2244 @param stmt prepared statement
2245 @param tables list of tables used in this query
2246
2247 @retval
2248 FALSE success
2249 @retval
2250 TRUE error, error message is set in THD
2251 */
2252
mysql_test_insert_select(Prepared_statement * stmt,TABLE_LIST * tables)2253 static bool mysql_test_insert_select(Prepared_statement *stmt,
2254 TABLE_LIST *tables)
2255 {
2256 int res;
2257 LEX *lex= stmt->lex;
2258 TABLE_LIST *first_local_table;
2259
2260 if (tables->table)
2261 {
2262 // don't allocate insert_values
2263 tables->table->insert_values=(uchar *)1;
2264 }
2265
2266 if (insert_precheck(stmt->thd, tables))
2267 return 1;
2268
2269 /* store it, because mysql_insert_select_prepare_tester change it */
2270 first_local_table= lex->first_select_lex()->table_list.first;
2271 DBUG_ASSERT(first_local_table != 0);
2272
2273 res=
2274 select_like_stmt_test_with_open(stmt, tables,
2275 &mysql_insert_select_prepare_tester,
2276 OPTION_SETUP_TABLES_DONE);
2277 /* revert changes made by mysql_insert_select_prepare_tester */
2278 lex->first_select_lex()->table_list.first= first_local_table;
2279 return res;
2280 }
2281
2282 /**
2283 Validate SELECT statement.
2284
2285 In case of success, if this query is not EXPLAIN, send column list info
2286 back to the client.
2287
2288 @param stmt prepared statement
2289 @param tables list of tables used in the query
2290
2291 @retval 0 success
2292 @retval 1 error, error message is set in THD
2293 @retval 2 success, and statement metadata has been sent
2294 */
2295
mysql_test_handler_read(Prepared_statement * stmt,TABLE_LIST * tables)2296 static int mysql_test_handler_read(Prepared_statement *stmt,
2297 TABLE_LIST *tables)
2298 {
2299 THD *thd= stmt->thd;
2300 LEX *lex= stmt->lex;
2301 SQL_HANDLER *ha_table;
2302 DBUG_ENTER("mysql_test_handler_read");
2303
2304 lex->first_select_lex()->context.resolve_in_select_list= TRUE;
2305
2306 /*
2307 We don't have to test for permissions as this is already done during
2308 HANDLER OPEN
2309 */
2310 if (!(ha_table= mysql_ha_read_prepare(thd, tables, lex->ha_read_mode,
2311 lex->ident.str,
2312 lex->insert_list,
2313 lex->ha_rkey_mode,
2314 lex->first_select_lex()->where)))
2315 DBUG_RETURN(1);
2316
2317 if (!stmt->is_sql_prepare())
2318 {
2319 if (!lex->result && !(lex->result= new (stmt->mem_root) select_send(thd)))
2320 DBUG_RETURN(1);
2321
2322 if (send_prep_stmt(stmt, ha_table->fields.elements) ||
2323 lex->result->send_result_set_metadata(ha_table->fields, Protocol::SEND_EOF) ||
2324 thd->protocol->flush())
2325 DBUG_RETURN(1);
2326 DBUG_RETURN(2);
2327 }
2328 DBUG_RETURN(0);
2329 }
2330
2331
2332 /**
2333 Perform semantic analysis of the parsed tree and send a response packet
2334 to the client.
2335
2336 This function
2337 - opens all tables and checks access rights
2338 - validates semantics of statement columns and SQL functions
2339 by calling fix_fields.
2340
2341 @param stmt prepared statement
2342
2343 @retval
2344 FALSE success, statement metadata is sent to client
2345 @retval
2346 TRUE error, error message is set in THD (but not sent)
2347 */
2348
check_prepared_statement(Prepared_statement * stmt)2349 static bool check_prepared_statement(Prepared_statement *stmt)
2350 {
2351 THD *thd= stmt->thd;
2352 LEX *lex= stmt->lex;
2353 SELECT_LEX *select_lex= lex->first_select_lex();
2354 TABLE_LIST *tables;
2355 enum enum_sql_command sql_command= lex->sql_command;
2356 int res= 0;
2357 DBUG_ENTER("check_prepared_statement");
2358 DBUG_PRINT("enter",("command: %d param_count: %u",
2359 sql_command, stmt->param_count));
2360
2361 lex->first_lists_tables_same();
2362 lex->fix_first_select_number();
2363 tables= lex->query_tables;
2364
2365 /* set context for commands which do not use setup_tables */
2366 lex->first_select_lex()->context.resolve_in_table_list_only(select_lex->
2367 get_table_list());
2368
2369 /*
2370 For the optimizer trace, this is the symmetric, for statement preparation,
2371 of what is done at statement execution (in mysql_execute_command()).
2372 */
2373 Opt_trace_start ots(thd, tables, lex->sql_command, &lex->var_list,
2374 thd->query(), thd->query_length(),
2375 thd->variables.character_set_client);
2376
2377 Json_writer_object trace_command(thd);
2378 Json_writer_array trace_command_steps(thd, "steps");
2379
2380 /* Reset warning count for each query that uses tables */
2381 if (tables)
2382 thd->get_stmt_da()->opt_clear_warning_info(thd->query_id);
2383
2384 if (sql_command_flags[sql_command] & CF_HA_CLOSE)
2385 mysql_ha_rm_tables(thd, tables);
2386
2387 /*
2388 Open temporary tables that are known now. Temporary tables added by
2389 prelocking will be opened afterwards (during open_tables()).
2390 */
2391 if (sql_command_flags[sql_command] & CF_PREOPEN_TMP_TABLES)
2392 {
2393 if (thd->open_temporary_tables(tables))
2394 goto error;
2395 }
2396
2397 switch (sql_command) {
2398 case SQLCOM_REPLACE:
2399 case SQLCOM_INSERT:
2400 res= mysql_test_insert(stmt, tables, lex->field_list,
2401 lex->many_values,
2402 lex->update_list, lex->value_list,
2403 lex->duplicates);
2404 break;
2405
2406 case SQLCOM_UPDATE:
2407 res= mysql_test_update(stmt, tables);
2408 /* mysql_test_update returns 2 if we need to switch to multi-update */
2409 if (res != 2)
2410 break;
2411 /* fall through */
2412 case SQLCOM_UPDATE_MULTI:
2413 res= mysql_test_multiupdate(stmt, tables, res == 2);
2414 break;
2415
2416 case SQLCOM_DELETE:
2417 res= mysql_test_delete(stmt, tables);
2418 break;
2419 /* The following allow WHERE clause, so they must be tested like SELECT */
2420 case SQLCOM_SHOW_DATABASES:
2421 case SQLCOM_SHOW_TABLES:
2422 case SQLCOM_SHOW_TRIGGERS:
2423 case SQLCOM_SHOW_EVENTS:
2424 case SQLCOM_SHOW_OPEN_TABLES:
2425 case SQLCOM_SHOW_FIELDS:
2426 case SQLCOM_SHOW_KEYS:
2427 case SQLCOM_SHOW_COLLATIONS:
2428 case SQLCOM_SHOW_CHARSETS:
2429 case SQLCOM_SHOW_VARIABLES:
2430 case SQLCOM_SHOW_STATUS:
2431 case SQLCOM_SHOW_TABLE_STATUS:
2432 case SQLCOM_SHOW_STATUS_PROC:
2433 case SQLCOM_SHOW_STATUS_FUNC:
2434 case SQLCOM_SHOW_STATUS_PACKAGE:
2435 case SQLCOM_SHOW_STATUS_PACKAGE_BODY:
2436 case SQLCOM_SELECT:
2437 res= mysql_test_select(stmt, tables);
2438 if (res == 2)
2439 {
2440 /* Statement and field info has already been sent */
2441 DBUG_RETURN(FALSE);
2442 }
2443 break;
2444 case SQLCOM_CREATE_TABLE:
2445 case SQLCOM_CREATE_SEQUENCE:
2446 res= mysql_test_create_table(stmt);
2447 break;
2448 case SQLCOM_SHOW_CREATE:
2449 if ((res= mysql_test_show_create_table(stmt, tables)) == 2)
2450 {
2451 /* Statement and field info has already been sent */
2452 DBUG_RETURN(FALSE);
2453 }
2454 break;
2455 case SQLCOM_SHOW_CREATE_DB:
2456 if ((res= mysql_test_show_create_db(stmt)) == 2)
2457 {
2458 /* Statement and field info has already been sent */
2459 DBUG_RETURN(FALSE);
2460 }
2461 break;
2462 #ifndef NO_EMBEDDED_ACCESS_CHECKS
2463 case SQLCOM_SHOW_GRANTS:
2464 if ((res= mysql_test_show_grants(stmt)) == 2)
2465 {
2466 /* Statement and field info has already been sent */
2467 DBUG_RETURN(FALSE);
2468 }
2469 break;
2470 #endif /* NO_EMBEDDED_ACCESS_CHECKS */
2471 #ifndef EMBEDDED_LIBRARY
2472 case SQLCOM_SHOW_SLAVE_STAT:
2473 if ((res= mysql_test_show_slave_status(stmt)) == 2)
2474 {
2475 /* Statement and field info has already been sent */
2476 DBUG_RETURN(FALSE);
2477 }
2478 break;
2479 case SQLCOM_SHOW_MASTER_STAT:
2480 if ((res= mysql_test_show_master_status(stmt)) == 2)
2481 {
2482 /* Statement and field info has already been sent */
2483 DBUG_RETURN(FALSE);
2484 }
2485 break;
2486 case SQLCOM_SHOW_BINLOGS:
2487 if ((res= mysql_test_show_binlogs(stmt)) == 2)
2488 {
2489 /* Statement and field info has already been sent */
2490 DBUG_RETURN(FALSE);
2491 }
2492 break;
2493 case SQLCOM_SHOW_BINLOG_EVENTS:
2494 case SQLCOM_SHOW_RELAYLOG_EVENTS:
2495 {
2496 List<Item> field_list;
2497 Log_event::init_show_field_list(thd, &field_list);
2498
2499 if ((res= send_stmt_metadata(thd, stmt, &field_list)) == 2)
2500 DBUG_RETURN(FALSE);
2501 }
2502 break;
2503 #endif /* EMBEDDED_LIBRARY */
2504 case SQLCOM_SHOW_CREATE_PROC:
2505 if ((res= mysql_test_show_create_routine(stmt, &sp_handler_procedure)) == 2)
2506 {
2507 /* Statement and field info has already been sent */
2508 DBUG_RETURN(FALSE);
2509 }
2510 break;
2511 case SQLCOM_SHOW_CREATE_FUNC:
2512 if ((res= mysql_test_show_create_routine(stmt, &sp_handler_function)) == 2)
2513 {
2514 /* Statement and field info has already been sent */
2515 DBUG_RETURN(FALSE);
2516 }
2517 break;
2518 case SQLCOM_SHOW_CREATE_PACKAGE:
2519 if ((res= mysql_test_show_create_routine(stmt, &sp_handler_package_spec)) == 2)
2520 {
2521 /* Statement and field info has already been sent */
2522 DBUG_RETURN(FALSE);
2523 }
2524 break;
2525 case SQLCOM_SHOW_CREATE_PACKAGE_BODY:
2526 if ((res= mysql_test_show_create_routine(stmt,
2527 &sp_handler_package_body)) == 2)
2528 {
2529 /* Statement and field info has already been sent */
2530 DBUG_RETURN(FALSE);
2531 }
2532 break;
2533 case SQLCOM_CREATE_VIEW:
2534 if (lex->create_view->mode == VIEW_ALTER)
2535 {
2536 my_message(ER_UNSUPPORTED_PS, ER_THD(thd, ER_UNSUPPORTED_PS), MYF(0));
2537 goto error;
2538 }
2539 res= mysql_test_create_view(stmt);
2540 break;
2541 case SQLCOM_DO:
2542 res= mysql_test_do_fields(stmt, tables, lex->insert_list);
2543 break;
2544
2545 case SQLCOM_CALL:
2546 res= mysql_test_call_fields(stmt, tables, &lex->value_list);
2547 break;
2548 case SQLCOM_SET_OPTION:
2549 res= mysql_test_set_fields(stmt, tables, &lex->var_list);
2550 break;
2551
2552 case SQLCOM_DELETE_MULTI:
2553 res= mysql_test_multidelete(stmt, tables);
2554 break;
2555
2556 case SQLCOM_INSERT_SELECT:
2557 case SQLCOM_REPLACE_SELECT:
2558 res= mysql_test_insert_select(stmt, tables);
2559 break;
2560
2561 case SQLCOM_HA_READ:
2562 res= mysql_test_handler_read(stmt, tables);
2563 /* Statement and field info has already been sent */
2564 DBUG_RETURN(res == 1 ? TRUE : FALSE);
2565
2566 /*
2567 Note that we don't need to have cases in this list if they are
2568 marked with CF_STATUS_COMMAND in sql_command_flags
2569 */
2570 case SQLCOM_SHOW_EXPLAIN:
2571 case SQLCOM_DROP_TABLE:
2572 case SQLCOM_DROP_SEQUENCE:
2573 case SQLCOM_RENAME_TABLE:
2574 case SQLCOM_ALTER_TABLE:
2575 case SQLCOM_ALTER_SEQUENCE:
2576 case SQLCOM_COMMIT:
2577 case SQLCOM_CREATE_INDEX:
2578 case SQLCOM_DROP_INDEX:
2579 case SQLCOM_ROLLBACK:
2580 case SQLCOM_ROLLBACK_TO_SAVEPOINT:
2581 case SQLCOM_TRUNCATE:
2582 case SQLCOM_DROP_VIEW:
2583 case SQLCOM_REPAIR:
2584 case SQLCOM_ANALYZE:
2585 case SQLCOM_OPTIMIZE:
2586 case SQLCOM_CHANGE_MASTER:
2587 case SQLCOM_RESET:
2588 case SQLCOM_FLUSH:
2589 case SQLCOM_SLAVE_START:
2590 case SQLCOM_SLAVE_STOP:
2591 case SQLCOM_SLAVE_ALL_START:
2592 case SQLCOM_SLAVE_ALL_STOP:
2593 case SQLCOM_INSTALL_PLUGIN:
2594 case SQLCOM_UNINSTALL_PLUGIN:
2595 case SQLCOM_CREATE_DB:
2596 case SQLCOM_DROP_DB:
2597 case SQLCOM_ALTER_DB_UPGRADE:
2598 case SQLCOM_CHECKSUM:
2599 case SQLCOM_CREATE_USER:
2600 case SQLCOM_ALTER_USER:
2601 case SQLCOM_RENAME_USER:
2602 case SQLCOM_DROP_USER:
2603 case SQLCOM_CREATE_ROLE:
2604 case SQLCOM_DROP_ROLE:
2605 case SQLCOM_ASSIGN_TO_KEYCACHE:
2606 case SQLCOM_PRELOAD_KEYS:
2607 case SQLCOM_GRANT:
2608 case SQLCOM_GRANT_ROLE:
2609 case SQLCOM_REVOKE:
2610 case SQLCOM_REVOKE_ALL:
2611 case SQLCOM_REVOKE_ROLE:
2612 case SQLCOM_KILL:
2613 case SQLCOM_COMPOUND:
2614 case SQLCOM_SHUTDOWN:
2615 break;
2616
2617 case SQLCOM_PREPARE:
2618 case SQLCOM_EXECUTE:
2619 case SQLCOM_DEALLOCATE_PREPARE:
2620 default:
2621 /*
2622 Trivial check of all status commands. This is easier than having
2623 things in the above case list, as it's less chance for mistakes.
2624 */
2625 if (!(sql_command_flags[sql_command] & CF_STATUS_COMMAND))
2626 {
2627 /* All other statements are not supported yet. */
2628 my_message(ER_UNSUPPORTED_PS, ER_THD(thd, ER_UNSUPPORTED_PS), MYF(0));
2629 goto error;
2630 }
2631 break;
2632 }
2633 if (res == 0)
2634 {
2635 if (!stmt->is_sql_prepare())
2636 {
2637 if (lex->describe || lex->analyze_stmt)
2638 {
2639 select_send result(thd);
2640 List<Item> field_list;
2641 res= thd->prepare_explain_fields(&result, &field_list,
2642 lex->describe, lex->analyze_stmt) ||
2643 send_prep_stmt(stmt, result.field_count(field_list)) ||
2644 result.send_result_set_metadata(field_list,
2645 Protocol::SEND_EOF);
2646 }
2647 else
2648 res= send_prep_stmt(stmt, 0);
2649 if (!res)
2650 thd->protocol->flush();
2651 }
2652 DBUG_RETURN(FALSE);
2653 }
2654 error:
2655 DBUG_RETURN(TRUE);
2656 }
2657
2658 /**
2659 Initialize array of parameters in statement from LEX.
2660 (We need to have quick access to items by number in mysql_stmt_get_longdata).
2661 This is to avoid using malloc/realloc in the parser.
2662 */
2663
init_param_array(Prepared_statement * stmt)2664 static bool init_param_array(Prepared_statement *stmt)
2665 {
2666 LEX *lex= stmt->lex;
2667 if ((stmt->param_count= lex->param_list.elements))
2668 {
2669 if (stmt->param_count > (uint) UINT_MAX16)
2670 {
2671 /* Error code to be defined in 5.0 */
2672 my_message(ER_PS_MANY_PARAM, ER_THD(stmt->thd, ER_PS_MANY_PARAM),
2673 MYF(0));
2674 return TRUE;
2675 }
2676 Item_param **to;
2677 List_iterator<Item_param> param_iterator(lex->param_list);
2678 /* Use thd->mem_root as it points at statement mem_root */
2679 stmt->param_array= (Item_param **)
2680 alloc_root(stmt->thd->mem_root,
2681 sizeof(Item_param*) * stmt->param_count);
2682 if (!stmt->param_array)
2683 return TRUE;
2684 for (to= stmt->param_array;
2685 to < stmt->param_array + stmt->param_count;
2686 ++to)
2687 {
2688 *to= param_iterator++;
2689 }
2690 }
2691 return FALSE;
2692 }
2693
2694
2695 /**
2696 COM_STMT_PREPARE handler.
2697
2698 Given a query string with parameter markers, create a prepared
2699 statement from it and send PS info back to the client.
2700
2701 If parameter markers are found in the query, then store the information
2702 using Item_param along with maintaining a list in lex->param_array, so
2703 that a fast and direct retrieval can be made without going through all
2704 field items.
2705
2706 @param packet query to be prepared
2707 @param packet_length query string length, including ignored
2708 trailing NULL or quote char.
2709
2710 @note
2711 This function parses the query and sends the total number of parameters
2712 and resultset metadata information back to client (if any), without
2713 executing the query i.e. without any log/disk writes. This allows the
2714 queries to be re-executed without re-parsing during execute.
2715
2716 @return
2717 none: in case of success a new statement id and metadata is sent
2718 to the client, otherwise an error message is set in THD.
2719 */
2720
mysqld_stmt_prepare(THD * thd,const char * packet,uint packet_length)2721 void mysqld_stmt_prepare(THD *thd, const char *packet, uint packet_length)
2722 {
2723 Protocol *save_protocol= thd->protocol;
2724 Prepared_statement *stmt;
2725 DBUG_ENTER("mysqld_stmt_prepare");
2726 DBUG_PRINT("prep_query", ("%s", packet));
2727
2728 /* First of all clear possible warnings from the previous command */
2729 thd->reset_for_next_command();
2730
2731 if (! (stmt= new Prepared_statement(thd)))
2732 goto end; /* out of memory: error is set in Sql_alloc */
2733
2734 if (thd->stmt_map.insert(thd, stmt))
2735 {
2736 /*
2737 The error is set in the insert. The statement itself
2738 will be also deleted there (this is how the hash works).
2739 */
2740 goto end;
2741 }
2742
2743 thd->protocol= &thd->protocol_binary;
2744
2745 if (stmt->prepare(packet, packet_length))
2746 {
2747 /* Statement map deletes statement on erase */
2748 thd->stmt_map.erase(stmt);
2749 thd->clear_last_stmt();
2750 }
2751 else
2752 thd->set_last_stmt(stmt);
2753
2754 thd->protocol= save_protocol;
2755
2756 sp_cache_enforce_limit(thd->sp_proc_cache, stored_program_cache_size);
2757 sp_cache_enforce_limit(thd->sp_func_cache, stored_program_cache_size);
2758 sp_cache_enforce_limit(thd->sp_package_spec_cache, stored_program_cache_size);
2759 sp_cache_enforce_limit(thd->sp_package_body_cache, stored_program_cache_size);
2760
2761 /* check_prepared_statemnt sends the metadata packet in case of success */
2762 end:
2763 DBUG_VOID_RETURN;
2764 }
2765
2766 /**
2767 Get an SQL statement from an item in m_code.
2768
2769 This function can return pointers to very different memory classes:
2770 - a static string "NULL", if the item returned NULL
2771 - the result of prepare_stmt_code->val_str(), if no conversion was needed
2772 - a thd->mem_root allocated string with the result of
2773 prepare_stmt_code->val_str() converted to @@collation_connection,
2774 if conversion was needed
2775
2776 The caller must dispose the result before the life cycle of "buffer" ends.
2777 As soon as buffer's destructor is called, the value is not valid any more!
2778
2779 mysql_sql_stmt_prepare() and mysql_sql_stmt_execute_immediate()
2780 call get_dynamic_sql_string() and then call respectively
2781 Prepare_statement::prepare() and Prepare_statment::execute_immediate(),
2782 who store the returned result into its permanent location using
2783 alloc_query(). "buffer" is still not destructed at that time.
2784
2785 @param[out] dst the result is stored here
2786 @param[inout] buffer
2787
2788 @retval false on success
2789 @retval true on error (out of memory)
2790 */
2791
get_dynamic_sql_string(THD * thd,LEX_CSTRING * dst,String * buffer)2792 bool Lex_prepared_stmt::get_dynamic_sql_string(THD *thd,
2793 LEX_CSTRING *dst,
2794 String *buffer)
2795 {
2796 if (m_code->fix_fields_if_needed_for_scalar(thd, NULL))
2797 return true;
2798
2799 const String *str= m_code->val_str(buffer);
2800 if (m_code->null_value)
2801 {
2802 /*
2803 Prepare source was NULL, so we need to set "str" to
2804 something reasonable to get a readable error message during parsing
2805 */
2806 dst->str= "NULL";
2807 dst->length= 4;
2808 return false;
2809 }
2810
2811 /*
2812 Character set conversion notes:
2813
2814 1) When PREPARE or EXECUTE IMMEDIATE are used with string literals:
2815 PREPARE stmt FROM 'SELECT ''str''';
2816 EXECUTE IMMEDIATE 'SELECT ''str''';
2817 it's very unlikely that any conversion will happen below, because
2818 @@character_set_client and @@collation_connection are normally
2819 set to the same CHARSET_INFO pointer.
2820
2821 In tricky environments when @@collation_connection is set to something
2822 different from @@character_set_client, double conversion may happen:
2823 - When the parser scans the string literal
2824 (sql_yacc.yy rules "prepare_src" -> "expr" -> ... -> "text_literal")
2825 it will convert 'str' from @@character_set_client to
2826 @@collation_connection.
2827 - Then in the code below will convert 'str' from @@collation_connection
2828 back to @@character_set_client.
2829
2830 2) When PREPARE or EXECUTE IMMEDIATE is used with a user variable,
2831 it should work about the same way, because user variables are usually
2832 assigned like this:
2833 SET @str='str';
2834 and thus have the same character set with string literals.
2835
2836 3) When PREPARE or EXECUTE IMMEDIATE is used with some
2837 more complex expression, conversion will depend on this expression.
2838 For example, a concatenation of string literals:
2839 EXECUTE IMMEDIATE 'SELECT * FROM'||'t1';
2840 should work the same way with just a single literal,
2841 so no conversion normally.
2842 */
2843 CHARSET_INFO *to_cs= thd->variables.character_set_client;
2844
2845 uint32 unused;
2846 if (String::needs_conversion(str->length(), str->charset(), to_cs, &unused))
2847 {
2848 if (!(dst->str= sql_strmake_with_convert(thd, str->ptr(), str->length(),
2849 str->charset(), UINT_MAX32,
2850 to_cs, &dst->length)))
2851 {
2852 dst->length= 0;
2853 return true;
2854 }
2855 DBUG_ASSERT(dst->length <= UINT_MAX32);
2856 return false;
2857 }
2858 dst->str= str->ptr();
2859 dst->length= str->length();
2860 return false;
2861 }
2862
2863
2864 /**
2865 SQLCOM_PREPARE implementation.
2866
2867 Prepare an SQL prepared statement. This is called from
2868 mysql_execute_command and should therefore behave like an
2869 ordinary query (e.g. should not reset any global THD data).
2870
2871 @param thd thread handle
2872
2873 @return
2874 none: in case of success, OK packet is sent to the client,
2875 otherwise an error message is set in THD
2876 */
2877
mysql_sql_stmt_prepare(THD * thd)2878 void mysql_sql_stmt_prepare(THD *thd)
2879 {
2880 LEX *lex= thd->lex;
2881 const LEX_CSTRING *name= &lex->prepared_stmt.name();
2882 Prepared_statement *stmt;
2883 LEX_CSTRING query;
2884 DBUG_ENTER("mysql_sql_stmt_prepare");
2885
2886 if ((stmt= (Prepared_statement*) thd->stmt_map.find_by_name(name)))
2887 {
2888 /*
2889 If there is a statement with the same name, remove it. It is ok to
2890 remove old and fail to insert a new one at the same time.
2891 */
2892 if (stmt->is_in_use())
2893 {
2894 my_error(ER_PS_NO_RECURSION, MYF(0));
2895 DBUG_VOID_RETURN;
2896 }
2897
2898 stmt->deallocate();
2899 }
2900
2901 /*
2902 It's important for "buffer" not to be destructed before stmt->prepare()!
2903 See comments in get_dynamic_sql_string().
2904 */
2905 StringBuffer<256> buffer;
2906 if (lex->prepared_stmt.get_dynamic_sql_string(thd, &query, &buffer) ||
2907 ! (stmt= new Prepared_statement(thd)))
2908 {
2909 DBUG_VOID_RETURN; /* out of memory */
2910 }
2911
2912 stmt->set_sql_prepare();
2913
2914 /* Set the name first, insert should know that this statement has a name */
2915 if (stmt->set_name(name))
2916 {
2917 delete stmt;
2918 DBUG_VOID_RETURN;
2919 }
2920
2921 if (thd->stmt_map.insert(thd, stmt))
2922 {
2923 /* The statement is deleted and an error is set if insert fails */
2924 DBUG_VOID_RETURN;
2925 }
2926
2927 /*
2928 Make sure we call Prepared_statement::prepare() with an empty
2929 THD::change_list. It can be non-empty as LEX::get_dynamic_sql_string()
2930 calls fix_fields() for the Item containing the PS source,
2931 e.g. on character set conversion:
2932
2933 SET NAMES utf8;
2934 DELIMITER $$
2935 CREATE PROCEDURE p1()
2936 BEGIN
2937 PREPARE stmt FROM CONCAT('SELECT ',CONVERT(RAND() USING latin1));
2938 EXECUTE stmt;
2939 END;
2940 $$
2941 DELIMITER ;
2942 CALL p1();
2943 */
2944 Item_change_list_savepoint change_list_savepoint(thd);
2945
2946 if (stmt->prepare(query.str, (uint) query.length))
2947 {
2948 /* Statement map deletes the statement on erase */
2949 thd->stmt_map.erase(stmt);
2950 }
2951 else
2952 {
2953 SESSION_TRACKER_CHANGED(thd, SESSION_STATE_CHANGE_TRACKER, NULL);
2954 my_ok(thd, 0L, 0L, "Statement prepared");
2955 }
2956 change_list_savepoint.rollback(thd);
2957
2958 DBUG_VOID_RETURN;
2959 }
2960
2961
mysql_sql_stmt_execute_immediate(THD * thd)2962 void mysql_sql_stmt_execute_immediate(THD *thd)
2963 {
2964 LEX *lex= thd->lex;
2965 Prepared_statement *stmt;
2966 LEX_CSTRING query;
2967 DBUG_ENTER("mysql_sql_stmt_execute_immediate");
2968
2969 if (lex->prepared_stmt.params_fix_fields(thd))
2970 DBUG_VOID_RETURN;
2971
2972 /*
2973 Prepared_statement is quite large,
2974 let's allocate it on the heap rather than on the stack.
2975
2976 It's important for "buffer" not to be destructed
2977 before stmt->execute_immediate().
2978 See comments in get_dynamic_sql_string().
2979 */
2980 StringBuffer<256> buffer;
2981 if (lex->prepared_stmt.get_dynamic_sql_string(thd, &query, &buffer) ||
2982 !(stmt= new Prepared_statement(thd)))
2983 DBUG_VOID_RETURN; // out of memory
2984
2985 // See comments on thd->free_list in mysql_sql_stmt_execute()
2986 Item *free_list_backup= thd->free_list;
2987 thd->free_list= NULL;
2988 /*
2989 Make sure we call Prepared_statement::execute_immediate()
2990 with an empty THD::change_list. It can be non empty as the above
2991 LEX::prepared_stmt_params_fix_fields() and LEX::get_dynamic_str_string()
2992 call fix_fields() for the PS source and PS parameter Items and
2993 can do Item tree changes, e.g. on character set conversion:
2994
2995 - Example #1: Item tree changes in get_dynamic_str_string()
2996 SET NAMES utf8;
2997 CREATE PROCEDURE p1()
2998 EXECUTE IMMEDIATE CONCAT('SELECT ',CONVERT(RAND() USING latin1));
2999 CALL p1();
3000
3001 - Example #2: Item tree changes in prepared_stmt_param_fix_fields():
3002 SET NAMES utf8;
3003 CREATE PROCEDURE p1(a VARCHAR(10) CHARACTER SET utf8)
3004 EXECUTE IMMEDIATE 'SELECT ?' USING CONCAT(a, CONVERT(RAND() USING latin1));
3005 CALL p1('x');
3006 */
3007 Item_change_list_savepoint change_list_savepoint(thd);
3008 (void) stmt->execute_immediate(query.str, (uint) query.length);
3009 change_list_savepoint.rollback(thd);
3010 thd->free_items();
3011 thd->free_list= free_list_backup;
3012
3013 stmt->lex->restore_set_statement_var();
3014 delete stmt;
3015 DBUG_VOID_RETURN;
3016 }
3017
3018
3019 /**
3020 Reinit prepared statement/stored procedure before execution.
3021
3022 @todo
3023 When the new table structure is ready, then have a status bit
3024 to indicate the table is altered, and re-do the setup_*
3025 and open the tables back.
3026 */
3027
reinit_stmt_before_use(THD * thd,LEX * lex)3028 void reinit_stmt_before_use(THD *thd, LEX *lex)
3029 {
3030 SELECT_LEX *sl= lex->all_selects_list;
3031 DBUG_ENTER("reinit_stmt_before_use");
3032 Window_spec *win_spec;
3033
3034 /*
3035 We have to update "thd" pointer in LEX, all its units and in LEX::result,
3036 since statements which belong to trigger body are associated with TABLE
3037 object and because of this can be used in different threads.
3038 */
3039 lex->thd= thd;
3040 DBUG_ASSERT(!lex->explain);
3041
3042 if (lex->empty_field_list_on_rset)
3043 {
3044 lex->empty_field_list_on_rset= 0;
3045 lex->field_list.empty();
3046 }
3047 for (; sl; sl= sl->next_select_in_list())
3048 {
3049 if (sl->changed_elements & TOUCHED_SEL_COND)
3050 {
3051 /* remove option which was put by mysql_explain_union() */
3052 sl->options&= ~SELECT_DESCRIBE;
3053
3054 /* see unique_table() */
3055 sl->exclude_from_table_unique_test= FALSE;
3056
3057 /*
3058 Copy WHERE, HAVING clause pointers to avoid damaging them
3059 by optimisation
3060 */
3061 if (sl->prep_where)
3062 {
3063 /*
3064 We need this rollback because memory allocated in
3065 copy_andor_structure() will be freed
3066 */
3067 thd->change_item_tree((Item**)&sl->where,
3068 sl->prep_where->copy_andor_structure(thd));
3069 sl->where->cleanup();
3070 }
3071 else
3072 sl->where= NULL;
3073 if (sl->prep_having)
3074 {
3075 /*
3076 We need this rollback because memory allocated in
3077 copy_andor_structure() will be freed
3078 */
3079 thd->change_item_tree((Item**)&sl->having,
3080 sl->prep_having->copy_andor_structure(thd));
3081 sl->having->cleanup();
3082 }
3083 else
3084 sl->having= NULL;
3085 DBUG_ASSERT(sl->join == 0);
3086 ORDER *order;
3087 /* Fix GROUP list */
3088 if (sl->group_list_ptrs && sl->group_list_ptrs->size() > 0)
3089 {
3090 for (uint ix= 0; ix < sl->group_list_ptrs->size() - 1; ++ix)
3091 {
3092 order= sl->group_list_ptrs->at(ix);
3093 order->next= sl->group_list_ptrs->at(ix+1);
3094 }
3095 }
3096 }
3097 { // no harm to do it (item_ptr set on parsing)
3098 ORDER *order;
3099 for (order= sl->group_list.first; order; order= order->next)
3100 {
3101 order->item= &order->item_ptr;
3102 }
3103 /* Fix ORDER list */
3104 for (order= sl->order_list.first; order; order= order->next)
3105 order->item= &order->item_ptr;
3106 /* Fix window functions too */
3107 List_iterator<Window_spec> it(sl->window_specs);
3108
3109 while ((win_spec= it++))
3110 {
3111 for (order= win_spec->partition_list->first; order; order= order->next)
3112 order->item= &order->item_ptr;
3113 for (order= win_spec->order_list->first; order; order= order->next)
3114 order->item= &order->item_ptr;
3115 }
3116
3117 // Reinit Pushdown
3118 sl->cond_pushed_into_where= NULL;
3119 sl->cond_pushed_into_having= NULL;
3120 }
3121 if (sl->changed_elements & TOUCHED_SEL_DERIVED)
3122 {
3123 #ifdef DBUG_ASSERT_EXISTS
3124 bool res=
3125 #endif
3126 sl->handle_derived(lex, DT_REINIT);
3127 DBUG_ASSERT(res == 0);
3128 }
3129
3130 {
3131 SELECT_LEX_UNIT *unit= sl->master_unit();
3132 unit->unclean();
3133 unit->types.empty();
3134 /* for derived tables & PS (which can't be reset by Item_subselect) */
3135 unit->reinit_exec_mechanism();
3136 unit->set_thd(thd);
3137 }
3138 }
3139
3140 /*
3141 TODO: When the new table structure is ready, then have a status bit
3142 to indicate the table is altered, and re-do the setup_*
3143 and open the tables back.
3144 */
3145 /*
3146 NOTE: We should reset whole table list here including all tables added
3147 by prelocking algorithm (it is not a problem for substatements since
3148 they have their own table list).
3149 */
3150 for (TABLE_LIST *tables= lex->query_tables;
3151 tables;
3152 tables= tables->next_global)
3153 {
3154 tables->reinit_before_use(thd);
3155 }
3156
3157 /* Reset MDL tickets for procedures/functions */
3158 for (Sroutine_hash_entry *rt=
3159 (Sroutine_hash_entry*)thd->lex->sroutines_list.first;
3160 rt; rt= rt->next)
3161 rt->mdl_request.ticket= NULL;
3162
3163 /*
3164 Cleanup of the special case of DELETE t1, t2 FROM t1, t2, t3 ...
3165 (multi-delete). We do a full clean up, although at the moment all we
3166 need to clean in the tables of MULTI-DELETE list is 'table' member.
3167 */
3168 for (TABLE_LIST *tables= lex->auxiliary_table_list.first;
3169 tables;
3170 tables= tables->next_global)
3171 {
3172 tables->reinit_before_use(thd);
3173 }
3174 lex->current_select= lex->first_select_lex();
3175
3176
3177 if (lex->result)
3178 {
3179 lex->result->cleanup();
3180 lex->result->set_thd(thd);
3181 }
3182 lex->allow_sum_func.clear_all();
3183 lex->in_sum_func= NULL;
3184 DBUG_VOID_RETURN;
3185 }
3186
3187
3188 /**
3189 Clears parameters from data left from previous execution or long data.
3190
3191 @param stmt prepared statement for which parameters should
3192 be reset
3193 */
3194
reset_stmt_params(Prepared_statement * stmt)3195 static void reset_stmt_params(Prepared_statement *stmt)
3196 {
3197 Item_param **item= stmt->param_array;
3198 Item_param **end= item + stmt->param_count;
3199 for (;item < end ; ++item)
3200 {
3201 (**item).reset();
3202 (**item).sync_clones();
3203 }
3204 }
3205
3206
3207 static void mysql_stmt_execute_common(THD *thd,
3208 ulong stmt_id,
3209 uchar *packet,
3210 uchar *packet_end,
3211 ulong cursor_flags,
3212 bool iteration,
3213 bool types);
3214
3215 /**
3216 COM_STMT_EXECUTE handler: execute a previously prepared statement.
3217
3218 If there are any parameters, then replace parameter markers with the
3219 data supplied from the client, and then execute the statement.
3220 This function uses binary protocol to send a possible result set
3221 to the client.
3222
3223 @param thd current thread
3224 @param packet_arg parameter types and data, if any
3225 @param packet_length packet length, including the terminator character.
3226
3227 @return
3228 none: in case of success OK packet or a result set is sent to the
3229 client, otherwise an error message is set in THD.
3230 */
3231
mysqld_stmt_execute(THD * thd,char * packet_arg,uint packet_length)3232 void mysqld_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
3233 {
3234 const uint packet_min_lenght= 9;
3235 uchar *packet= (uchar*)packet_arg; // GCC 4.0.1 workaround
3236
3237 DBUG_ENTER("mysqld_stmt_execute");
3238
3239 if (packet_length < packet_min_lenght)
3240 {
3241 my_error(ER_MALFORMED_PACKET, MYF(0));
3242 DBUG_VOID_RETURN;
3243 }
3244 ulong stmt_id= uint4korr(packet);
3245 ulong flags= (ulong) packet[4];
3246 uchar *packet_end= packet + packet_length;
3247
3248 packet+= 9; /* stmt_id + 5 bytes of flags */
3249
3250 mysql_stmt_execute_common(thd, stmt_id, packet, packet_end, flags, FALSE,
3251 FALSE);
3252 DBUG_VOID_RETURN;
3253 }
3254
3255
3256 /**
3257 COM_STMT_BULK_EXECUTE handler: execute a previously prepared statement.
3258
3259 If there are any parameters, then replace parameter markers with the
3260 data supplied from the client, and then execute the statement.
3261 This function uses binary protocol to send a possible result set
3262 to the client.
3263
3264 @param thd current thread
3265 @param packet_arg parameter types and data, if any
3266 @param packet_length packet length, including the terminator character.
3267
3268 @return
3269 none: in case of success OK packet or a result set is sent to the
3270 client, otherwise an error message is set in THD.
3271 */
3272
mysqld_stmt_bulk_execute(THD * thd,char * packet_arg,uint packet_length)3273 void mysqld_stmt_bulk_execute(THD *thd, char *packet_arg, uint packet_length)
3274 {
3275 uchar *packet= (uchar*)packet_arg; // GCC 4.0.1 workaround
3276 DBUG_ENTER("mysqld_stmt_execute_bulk");
3277
3278 const uint packet_header_lenght= 4 + 2; //ID & 2 bytes of flags
3279
3280 if (packet_length < packet_header_lenght)
3281 {
3282 my_error(ER_MALFORMED_PACKET, MYF(0));
3283 DBUG_VOID_RETURN;
3284 }
3285
3286 ulong stmt_id= uint4korr(packet);
3287 uint flags= (uint) uint2korr(packet + 4);
3288 uchar *packet_end= packet + packet_length;
3289
3290 if (!(thd->client_capabilities &
3291 MARIADB_CLIENT_STMT_BULK_OPERATIONS))
3292 {
3293 DBUG_PRINT("error",
3294 ("An attempt to execute bulk operation without support"));
3295 my_error(ER_UNSUPPORTED_PS, MYF(0));
3296 DBUG_VOID_RETURN;
3297 }
3298 /* Check for implemented parameters */
3299 if (flags & (~STMT_BULK_FLAG_CLIENT_SEND_TYPES))
3300 {
3301 DBUG_PRINT("error", ("unsupported bulk execute flags %x", flags));
3302 my_error(ER_UNSUPPORTED_PS, MYF(0));
3303 DBUG_VOID_RETURN;
3304 }
3305
3306 /* stmt id and two bytes of flags */
3307 packet+= packet_header_lenght;
3308 mysql_stmt_execute_common(thd, stmt_id, packet, packet_end, 0, TRUE,
3309 (flags & STMT_BULK_FLAG_CLIENT_SEND_TYPES));
3310 DBUG_VOID_RETURN;
3311 }
3312
3313 /**
3314 Additional packet checks for direct execution
3315
3316 @param thd THD handle
3317 @param stmt prepared statement being directly executed
3318 @param paket packet with parameters to bind
3319 @param packet_end pointer to the byte after parameters end
3320 @param bulk_op is it bulk operation
3321 @param direct_exec is it direct execution
3322 @param read_bytes need to read types (only with bulk_op)
3323
3324 @retval true this parameter is wrong
3325 @retval false this parameter is OK
3326 */
3327
3328 static bool
stmt_execute_packet_sanity_check(Prepared_statement * stmt,uchar * packet,uchar * packet_end,bool bulk_op,bool direct_exec,bool read_types)3329 stmt_execute_packet_sanity_check(Prepared_statement *stmt,
3330 uchar *packet, uchar *packet_end,
3331 bool bulk_op, bool direct_exec,
3332 bool read_types)
3333 {
3334
3335 DBUG_ASSERT((!read_types) || (read_types && bulk_op));
3336 if (stmt->param_count > 0)
3337 {
3338 uint packet_length= static_cast<uint>(packet_end - packet);
3339 uint null_bitmap_bytes= (bulk_op ? 0 : (stmt->param_count + 7)/8);
3340 uint min_len_for_param_count = null_bitmap_bytes
3341 + (bulk_op ? 0 : 1); /* sent types byte */
3342
3343 if (!bulk_op && packet_length >= min_len_for_param_count)
3344 {
3345 if ((read_types= packet[null_bitmap_bytes]))
3346 {
3347 /*
3348 Should be 0 or 1. If the byte is not 1, that could mean,
3349 e.g. that we read incorrect byte due to incorrect number
3350 of sent parameters for direct execution (i.e. null bitmap
3351 is shorter or longer, than it should be)
3352 */
3353 if (packet[null_bitmap_bytes] != '\1')
3354 {
3355 return true;
3356 }
3357 }
3358 }
3359
3360 if (read_types)
3361 {
3362 /* 2 bytes per parameter of the type and flags */
3363 min_len_for_param_count+= 2*stmt->param_count;
3364 }
3365 else
3366 {
3367 /*
3368 If types are not sent, there is nothing to do here.
3369 But for direct execution types should always be sent
3370 */
3371 return direct_exec;
3372 }
3373
3374 /*
3375 If true, the packet is guaranteed too short for the number of
3376 parameters in the PS
3377 */
3378 return (packet_length < min_len_for_param_count);
3379 }
3380 else
3381 {
3382 /*
3383 If there is no parameters, this should be normally already end
3384 of the packet, but it is not a problem if something left (popular
3385 mistake in protocol implementation) because we will not read anymore
3386 from the buffer.
3387 */
3388 return false;
3389 }
3390 return false;
3391 }
3392
3393
3394 /**
3395 Common part of prepared statement execution
3396
3397 @param thd THD handle
3398 @param stmt_id id of the prepared statement
3399 @param paket packet with parameters to bind
3400 @param packet_end pointer to the byte after parameters end
3401 @param cursor_flags cursor flags
3402 @param bulk_op id it bulk operation
3403 @param read_types flag say that types muast been read
3404 */
3405
mysql_stmt_execute_common(THD * thd,ulong stmt_id,uchar * packet,uchar * packet_end,ulong cursor_flags,bool bulk_op,bool read_types)3406 static void mysql_stmt_execute_common(THD *thd,
3407 ulong stmt_id,
3408 uchar *packet,
3409 uchar *packet_end,
3410 ulong cursor_flags,
3411 bool bulk_op,
3412 bool read_types)
3413 {
3414 /* Query text for binary, general or slow log, if any of them is open */
3415 String expanded_query;
3416 Prepared_statement *stmt;
3417 Protocol *save_protocol= thd->protocol;
3418 bool open_cursor;
3419 DBUG_ENTER("mysqld_stmt_execute_common");
3420 DBUG_ASSERT((!read_types) || (read_types && bulk_op));
3421
3422 /* First of all clear possible warnings from the previous command */
3423 thd->reset_for_next_command();
3424
3425 if (!(stmt= find_prepared_statement(thd, stmt_id)))
3426 {
3427 char llbuf[22];
3428 my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), static_cast<int>(sizeof(llbuf)),
3429 llstr(stmt_id, llbuf), "mysqld_stmt_execute");
3430 DBUG_VOID_RETURN;
3431 }
3432
3433 /*
3434 In case of direct execution application decides how many parameters
3435 to send.
3436
3437 Thus extra checks are required to prevent crashes caused by incorrect
3438 interpretation of the packet data. Plus there can be always a broken
3439 evil client.
3440 */
3441 if (stmt_execute_packet_sanity_check(stmt, packet, packet_end, bulk_op,
3442 stmt_id == LAST_STMT_ID, read_types))
3443 {
3444 my_error(ER_MALFORMED_PACKET, MYF(0));
3445 /*
3446 Let's set the thd->query_string so the audit plugin
3447 can report the executed query that failed.
3448 */
3449 thd->set_query_inner(stmt->query_string);
3450 DBUG_VOID_RETURN;
3451 }
3452
3453 stmt->read_types= read_types;
3454
3455 #if defined(ENABLED_PROFILING)
3456 thd->profiling.set_query_source(stmt->query(), stmt->query_length());
3457 #endif
3458 DBUG_PRINT("exec_query", ("%s", stmt->query()));
3459 DBUG_PRINT("info",("stmt: %p bulk_op %d", stmt, bulk_op));
3460
3461 open_cursor= MY_TEST(cursor_flags & (ulong) CURSOR_TYPE_READ_ONLY);
3462
3463 thd->protocol= &thd->protocol_binary;
3464 if (!bulk_op)
3465 stmt->execute_loop(&expanded_query, open_cursor, packet, packet_end);
3466 else
3467 stmt->execute_bulk_loop(&expanded_query, open_cursor, packet, packet_end);
3468 thd->protocol= save_protocol;
3469
3470 sp_cache_enforce_limit(thd->sp_proc_cache, stored_program_cache_size);
3471 sp_cache_enforce_limit(thd->sp_func_cache, stored_program_cache_size);
3472 sp_cache_enforce_limit(thd->sp_package_spec_cache, stored_program_cache_size);
3473 sp_cache_enforce_limit(thd->sp_package_body_cache, stored_program_cache_size);
3474
3475 /* Close connection socket; for use with client testing (Bug#43560). */
3476 DBUG_EXECUTE_IF("close_conn_after_stmt_execute", vio_shutdown(thd->net.vio,SHUT_RD););
3477
3478 DBUG_VOID_RETURN;
3479 }
3480
3481
3482 /**
3483 SQLCOM_EXECUTE implementation.
3484
3485 Execute prepared statement using parameter values from
3486 lex->prepared_stmt_params and send result to the client using
3487 text protocol. This is called from mysql_execute_command and
3488 therefore should behave like an ordinary query (e.g. not change
3489 global THD data, such as warning count, server status, etc).
3490 This function uses text protocol to send a possible result set.
3491
3492 @param thd thread handle
3493
3494 @return
3495 none: in case of success, OK (or result set) packet is sent to the
3496 client, otherwise an error is set in THD
3497 */
3498
mysql_sql_stmt_execute(THD * thd)3499 void mysql_sql_stmt_execute(THD *thd)
3500 {
3501 LEX *lex= thd->lex;
3502 Prepared_statement *stmt;
3503 const LEX_CSTRING *name= &lex->prepared_stmt.name();
3504 /* Query text for binary, general or slow log, if any of them is open */
3505 String expanded_query;
3506 DBUG_ENTER("mysql_sql_stmt_execute");
3507 DBUG_PRINT("info", ("EXECUTE: %.*s", (int) name->length, name->str));
3508
3509 if (!(stmt= (Prepared_statement*) thd->stmt_map.find_by_name(name)))
3510 {
3511 my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0),
3512 static_cast<int>(name->length), name->str, "EXECUTE");
3513 DBUG_VOID_RETURN;
3514 }
3515
3516 if (stmt->param_count != lex->prepared_stmt.param_count())
3517 {
3518 my_error(ER_WRONG_ARGUMENTS, MYF(0), "EXECUTE");
3519 DBUG_VOID_RETURN;
3520 }
3521
3522 DBUG_PRINT("info",("stmt: %p", stmt));
3523
3524 if (lex->prepared_stmt.params_fix_fields(thd))
3525 DBUG_VOID_RETURN;
3526
3527 /*
3528 thd->free_list can already have some Items.
3529
3530 Example queries:
3531 - SET STATEMENT var=expr FOR EXECUTE stmt;
3532 - EXECUTE stmt USING expr;
3533
3534 E.g. for a query like this:
3535 PREPARE stmt FROM 'INSERT INTO t1 VALUES (@@max_sort_length)';
3536 SET STATEMENT max_sort_length=2048 FOR EXECUTE stmt;
3537 thd->free_list contains a pointer to Item_int corresponding to 2048.
3538
3539 If Prepared_statement::execute() notices that the table metadata for "t1"
3540 has changed since PREPARE, it returns an error asking the calling
3541 Prepared_statement::execute_loop() to re-prepare the statement.
3542 Before returning the error, Prepared_statement::execute()
3543 calls Prepared_statement::cleanup_stmt(),
3544 which calls thd->cleanup_after_query(),
3545 which calls Query_arena::free_items().
3546
3547 We hide "external" Items, e.g. those created while parsing the
3548 "SET STATEMENT" or "USING" parts of the query,
3549 so they don't get freed in case of re-prepare.
3550 See MDEV-10702 Crash in SET STATEMENT FOR EXECUTE
3551 */
3552 Item *free_list_backup= thd->free_list;
3553 thd->free_list= NULL; // Hide the external (e.g. "SET STATEMENT") Items
3554 /*
3555 Make sure we call Prepared_statement::execute_loop() with an empty
3556 THD::change_list. It can be non-empty because the above
3557 LEX::prepared_stmt_params_fix_fields() calls fix_fields() for
3558 the PS parameter Items and can do some Item tree changes,
3559 e.g. on character set conversion:
3560
3561 SET NAMES utf8;
3562 DELIMITER $$
3563 CREATE PROCEDURE p1(a VARCHAR(10) CHARACTER SET utf8)
3564 BEGIN
3565 PREPARE stmt FROM 'SELECT ?';
3566 EXECUTE stmt USING CONCAT(a, CONVERT(RAND() USING latin1));
3567 END;
3568 $$
3569 DELIMITER ;
3570 CALL p1('x');
3571 */
3572 Item_change_list_savepoint change_list_savepoint(thd);
3573 (void) stmt->execute_loop(&expanded_query, FALSE, NULL, NULL);
3574 change_list_savepoint.rollback(thd);
3575 thd->free_items(); // Free items created by execute_loop()
3576 /*
3577 Now restore the "external" (e.g. "SET STATEMENT") Item list.
3578 It will be freed normaly in THD::cleanup_after_query().
3579 */
3580 thd->free_list= free_list_backup;
3581
3582 stmt->lex->restore_set_statement_var();
3583 DBUG_VOID_RETURN;
3584 }
3585
3586
3587 /**
3588 COM_STMT_FETCH handler: fetches requested amount of rows from cursor.
3589
3590 @param thd Thread handle
3591 @param packet Packet from client (with stmt_id & num_rows)
3592 @param packet_length Length of packet
3593 */
3594
mysqld_stmt_fetch(THD * thd,char * packet,uint packet_length)3595 void mysqld_stmt_fetch(THD *thd, char *packet, uint packet_length)
3596 {
3597 /* assume there is always place for 8-16 bytes */
3598 ulong stmt_id= uint4korr(packet);
3599 ulong num_rows= uint4korr(packet+4);
3600 Prepared_statement *stmt;
3601 Statement stmt_backup;
3602 Server_side_cursor *cursor;
3603 DBUG_ENTER("mysqld_stmt_fetch");
3604
3605 /* First of all clear possible warnings from the previous command */
3606 thd->reset_for_next_command();
3607
3608 status_var_increment(thd->status_var.com_stmt_fetch);
3609 if (!(stmt= find_prepared_statement(thd, stmt_id)))
3610 {
3611 char llbuf[22];
3612 my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), static_cast<int>(sizeof(llbuf)),
3613 llstr(stmt_id, llbuf), "mysqld_stmt_fetch");
3614 DBUG_VOID_RETURN;
3615 }
3616
3617 cursor= stmt->cursor;
3618 if (!cursor)
3619 {
3620 my_error(ER_STMT_HAS_NO_OPEN_CURSOR, MYF(0), stmt_id);
3621 DBUG_VOID_RETURN;
3622 }
3623
3624 thd->stmt_arena= stmt;
3625 thd->set_n_backup_statement(stmt, &stmt_backup);
3626
3627 cursor->fetch(num_rows);
3628
3629 if (!cursor->is_open())
3630 {
3631 stmt->close_cursor();
3632 reset_stmt_params(stmt);
3633 }
3634
3635 thd->restore_backup_statement(stmt, &stmt_backup);
3636 thd->stmt_arena= thd;
3637
3638 DBUG_VOID_RETURN;
3639 }
3640
3641
3642 /**
3643 Reset a prepared statement in case there was a recoverable error.
3644
3645 This function resets statement to the state it was right after prepare.
3646 It can be used to:
3647 - clear an error happened during mysqld_stmt_send_long_data
3648 - cancel long data stream for all placeholders without
3649 having to call mysqld_stmt_execute.
3650 - close an open cursor
3651 Sends 'OK' packet in case of success (statement was reset)
3652 or 'ERROR' packet (unrecoverable error/statement not found/etc).
3653
3654 @param thd Thread handle
3655 @param packet Packet with stmt id
3656 */
3657
mysqld_stmt_reset(THD * thd,char * packet)3658 void mysqld_stmt_reset(THD *thd, char *packet)
3659 {
3660 /* There is always space for 4 bytes in buffer */
3661 ulong stmt_id= uint4korr(packet);
3662 Prepared_statement *stmt;
3663 DBUG_ENTER("mysqld_stmt_reset");
3664
3665 /* First of all clear possible warnings from the previous command */
3666 thd->reset_for_next_command();
3667
3668 status_var_increment(thd->status_var.com_stmt_reset);
3669 if (!(stmt= find_prepared_statement(thd, stmt_id)))
3670 {
3671 char llbuf[22];
3672 my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), static_cast<int>(sizeof(llbuf)),
3673 llstr(stmt_id, llbuf), "mysqld_stmt_reset");
3674 DBUG_VOID_RETURN;
3675 }
3676
3677 stmt->close_cursor();
3678
3679 /*
3680 Clear parameters from data which could be set by
3681 mysqld_stmt_send_long_data() call.
3682 */
3683 reset_stmt_params(stmt);
3684
3685 stmt->state= Query_arena::STMT_PREPARED;
3686
3687 general_log_print(thd, thd->get_command(), NullS);
3688
3689 my_ok(thd);
3690
3691 DBUG_VOID_RETURN;
3692 }
3693
3694
3695 /**
3696 Delete a prepared statement from memory.
3697
3698 @note
3699 we don't send any reply to this command.
3700 */
3701
mysqld_stmt_close(THD * thd,char * packet)3702 void mysqld_stmt_close(THD *thd, char *packet)
3703 {
3704 /* There is always space for 4 bytes in packet buffer */
3705 ulong stmt_id= uint4korr(packet);
3706 Prepared_statement *stmt;
3707 DBUG_ENTER("mysqld_stmt_close");
3708
3709 thd->get_stmt_da()->disable_status();
3710
3711 if (!(stmt= find_prepared_statement(thd, stmt_id)))
3712 DBUG_VOID_RETURN;
3713
3714 /*
3715 The only way currently a statement can be deallocated when it's
3716 in use is from within Dynamic SQL.
3717 */
3718 DBUG_ASSERT(! stmt->is_in_use());
3719 stmt->deallocate();
3720 general_log_print(thd, thd->get_command(), NullS);
3721
3722 if (thd->last_stmt == stmt)
3723 thd->clear_last_stmt();
3724
3725 DBUG_VOID_RETURN;
3726 }
3727
3728
3729 /**
3730 SQLCOM_DEALLOCATE implementation.
3731
3732 Close an SQL prepared statement. As this can be called from Dynamic
3733 SQL, we should be careful to not close a statement that is currently
3734 being executed.
3735
3736 @return
3737 none: OK packet is sent in case of success, otherwise an error
3738 message is set in THD
3739 */
3740
mysql_sql_stmt_close(THD * thd)3741 void mysql_sql_stmt_close(THD *thd)
3742 {
3743 Prepared_statement* stmt;
3744 const LEX_CSTRING *name= &thd->lex->prepared_stmt.name();
3745 DBUG_PRINT("info", ("DEALLOCATE PREPARE: %.*s", (int) name->length,
3746 name->str));
3747
3748 if (! (stmt= (Prepared_statement*) thd->stmt_map.find_by_name(name)))
3749 my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0),
3750 static_cast<int>(name->length), name->str, "DEALLOCATE PREPARE");
3751 else if (stmt->is_in_use())
3752 my_error(ER_PS_NO_RECURSION, MYF(0));
3753 else
3754 {
3755 stmt->deallocate();
3756 SESSION_TRACKER_CHANGED(thd, SESSION_STATE_CHANGE_TRACKER, NULL);
3757 my_ok(thd);
3758 }
3759 }
3760
3761
3762 /**
3763 Handle long data in pieces from client.
3764
3765 Get a part of a long data. To make the protocol efficient, we are
3766 not sending any return packets here. If something goes wrong, then
3767 we will send the error on 'execute' We assume that the client takes
3768 care of checking that all parts are sent to the server. (No checking
3769 that we get a 'end of column' in the server is performed).
3770
3771 @param thd Thread handle
3772 @param packet String to append
3773 @param packet_length Length of string (including end \\0)
3774 */
3775
mysql_stmt_get_longdata(THD * thd,char * packet,ulong packet_length)3776 void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length)
3777 {
3778 ulong stmt_id;
3779 uint param_number;
3780 Prepared_statement *stmt;
3781 Item_param *param;
3782 #ifndef EMBEDDED_LIBRARY
3783 char *packet_end= packet + packet_length;
3784 #endif
3785 DBUG_ENTER("mysql_stmt_get_longdata");
3786
3787 status_var_increment(thd->status_var.com_stmt_send_long_data);
3788
3789 thd->get_stmt_da()->disable_status();
3790 #ifndef EMBEDDED_LIBRARY
3791 /* Minimal size of long data packet is 6 bytes */
3792 if (packet_length < MYSQL_LONG_DATA_HEADER)
3793 DBUG_VOID_RETURN;
3794 #endif
3795
3796 stmt_id= uint4korr(packet);
3797 packet+= 4;
3798
3799 if (!(stmt=find_prepared_statement(thd, stmt_id)))
3800 DBUG_VOID_RETURN;
3801
3802 param_number= uint2korr(packet);
3803 packet+= 2;
3804 #ifndef EMBEDDED_LIBRARY
3805 if (param_number >= stmt->param_count)
3806 {
3807 /* Error will be sent in execute call */
3808 stmt->state= Query_arena::STMT_ERROR;
3809 stmt->last_errno= ER_WRONG_ARGUMENTS;
3810 sprintf(stmt->last_error, ER_THD(thd, ER_WRONG_ARGUMENTS),
3811 "mysqld_stmt_send_long_data");
3812 DBUG_VOID_RETURN;
3813 }
3814 #endif
3815
3816 param= stmt->param_array[param_number];
3817
3818 Diagnostics_area new_stmt_da(thd->query_id, false, true);
3819 Diagnostics_area *save_stmt_da= thd->get_stmt_da();
3820
3821 thd->set_stmt_da(&new_stmt_da);
3822
3823 #ifndef EMBEDDED_LIBRARY
3824 param->set_longdata(packet, (ulong) (packet_end - packet));
3825 #else
3826 param->set_longdata(thd->extra_data, thd->extra_length);
3827 #endif
3828 if (unlikely(thd->get_stmt_da()->is_error()))
3829 {
3830 stmt->state= Query_arena::STMT_ERROR;
3831 stmt->last_errno= thd->get_stmt_da()->sql_errno();
3832 strmake_buf(stmt->last_error, thd->get_stmt_da()->message());
3833 }
3834 thd->set_stmt_da(save_stmt_da);
3835
3836 general_log_print(thd, thd->get_command(), NullS);
3837
3838 DBUG_VOID_RETURN;
3839 }
3840
3841
3842 /***************************************************************************
3843 Select_fetch_protocol_binary
3844 ****************************************************************************/
3845
Select_fetch_protocol_binary(THD * thd_arg)3846 Select_fetch_protocol_binary::Select_fetch_protocol_binary(THD *thd_arg):
3847 select_send(thd_arg), protocol(thd_arg)
3848 {}
3849
send_result_set_metadata(List<Item> & list,uint flags)3850 bool Select_fetch_protocol_binary::send_result_set_metadata(List<Item> &list, uint flags)
3851 {
3852 bool rc;
3853 Protocol *save_protocol= thd->protocol;
3854
3855 /*
3856 Protocol::send_result_set_metadata caches the information about column types:
3857 this information is later used to send data. Therefore, the same
3858 dedicated Protocol object must be used for all operations with
3859 a cursor.
3860 */
3861 thd->protocol= &protocol;
3862 rc= select_send::send_result_set_metadata(list, flags);
3863 thd->protocol= save_protocol;
3864
3865 return rc;
3866 }
3867
send_eof()3868 bool Select_fetch_protocol_binary::send_eof()
3869 {
3870 /*
3871 Don't send EOF if we're in error condition (which implies we've already
3872 sent or are sending an error)
3873 */
3874 if (unlikely(thd->is_error()))
3875 return true;
3876
3877 ::my_eof(thd);
3878 return false;
3879 }
3880
3881
3882 int
send_data(List<Item> & fields)3883 Select_fetch_protocol_binary::send_data(List<Item> &fields)
3884 {
3885 Protocol *save_protocol= thd->protocol;
3886 int rc;
3887
3888 thd->protocol= &protocol;
3889 rc= select_send::send_data(fields);
3890 thd->protocol= save_protocol;
3891 return rc;
3892 }
3893
3894 /*******************************************************************
3895 * Reprepare_observer
3896 *******************************************************************/
3897 /** Push an error to the error stack and return TRUE for now. */
3898
3899 bool
report_error(THD * thd)3900 Reprepare_observer::report_error(THD *thd)
3901 {
3902 /*
3903 This 'error' is purely internal to the server:
3904 - No exception handler is invoked,
3905 - No condition is added in the condition area (warn_list).
3906 The diagnostics area is set to an error status to enforce
3907 that this thread execution stops and returns to the caller,
3908 backtracking all the way to Prepared_statement::execute_loop().
3909 */
3910 thd->get_stmt_da()->set_error_status(ER_NEED_REPREPARE);
3911 m_invalidated= TRUE;
3912
3913 return TRUE;
3914 }
3915
3916
3917 /*******************************************************************
3918 * Server_runnable
3919 *******************************************************************/
3920
~Server_runnable()3921 Server_runnable::~Server_runnable()
3922 {
3923 }
3924
3925 ///////////////////////////////////////////////////////////////////////////
3926
3927 Execute_sql_statement::
Execute_sql_statement(LEX_STRING sql_text)3928 Execute_sql_statement(LEX_STRING sql_text)
3929 :m_sql_text(sql_text)
3930 {}
3931
3932
3933 /**
3934 Parse and execute a statement. Does not prepare the query.
3935
3936 Allows to execute a statement from within another statement.
3937 The main property of the implementation is that it does not
3938 affect the environment -- i.e. you can run many
3939 executions without having to cleanup/reset THD in between.
3940 */
3941
3942 bool
execute_server_code(THD * thd)3943 Execute_sql_statement::execute_server_code(THD *thd)
3944 {
3945 PSI_statement_locker *parent_locker;
3946 bool error;
3947
3948 if (alloc_query(thd, m_sql_text.str, m_sql_text.length))
3949 return TRUE;
3950
3951 Parser_state parser_state;
3952 if (parser_state.init(thd, thd->query(), thd->query_length()))
3953 return TRUE;
3954
3955 parser_state.m_lip.multi_statements= FALSE;
3956 lex_start(thd);
3957
3958 error= parse_sql(thd, &parser_state, NULL) || thd->is_error();
3959
3960 if (unlikely(error))
3961 goto end;
3962
3963 thd->lex->set_trg_event_type_for_tables();
3964
3965 parent_locker= thd->m_statement_psi;
3966 thd->m_statement_psi= NULL;
3967 error= mysql_execute_command(thd);
3968 thd->m_statement_psi= parent_locker;
3969
3970 /* report error issued during command execution */
3971 if (likely(error == 0) && thd->spcont == NULL)
3972 general_log_write(thd, COM_STMT_EXECUTE,
3973 thd->query(), thd->query_length());
3974
3975 end:
3976 thd->lex->restore_set_statement_var();
3977 lex_end(thd->lex);
3978
3979 return error;
3980 }
3981
3982 /***************************************************************************
3983 Prepared_statement
3984 ****************************************************************************/
3985
Prepared_statement(THD * thd_arg)3986 Prepared_statement::Prepared_statement(THD *thd_arg)
3987 :Statement(NULL, &main_mem_root,
3988 STMT_INITIALIZED,
3989 ((++thd_arg->statement_id_counter) & STMT_ID_MASK)),
3990 thd(thd_arg),
3991 result(thd_arg),
3992 param_array(0),
3993 cursor(0),
3994 packet(0),
3995 packet_end(0),
3996 param_count(0),
3997 last_errno(0),
3998 flags((uint) IS_IN_USE),
3999 iterations(0),
4000 start_param(0),
4001 read_types(0),
4002 m_sql_mode(thd->variables.sql_mode)
4003 {
4004 init_sql_alloc(&main_mem_root, "Prepared_statement",
4005 thd_arg->variables.query_alloc_block_size,
4006 thd_arg->variables.query_prealloc_size,
4007 MYF(MY_THREAD_SPECIFIC));
4008 *last_error= '\0';
4009 }
4010
4011
setup_set_params()4012 void Prepared_statement::setup_set_params()
4013 {
4014 /*
4015 Note: BUG#25843 applies here too (query cache lookup uses thd->db, not
4016 db from "prepare" time).
4017 */
4018 if (query_cache_maybe_disabled(thd)) // we won't expand the query
4019 lex->safe_to_cache_query= FALSE; // so don't cache it at Execution
4020
4021 /*
4022 Decide if we have to expand the query (because we must write it to logs or
4023 because we want to look it up in the query cache) or not.
4024 */
4025 bool replace_params_with_values= false;
4026 // binlog
4027 replace_params_with_values|= mysql_bin_log.is_open() && is_update_query(lex->sql_command);
4028 // general or slow log
4029 replace_params_with_values|= opt_log || thd->variables.sql_log_slow;
4030 // query cache
4031 replace_params_with_values|= query_cache_is_cacheable_query(lex);
4032 // but never for compound statements
4033 replace_params_with_values&= lex->sql_command != SQLCOM_COMPOUND;
4034
4035 if (replace_params_with_values)
4036 {
4037 set_params_from_actual_params= insert_params_from_actual_params_with_log;
4038 #ifndef EMBEDDED_LIBRARY
4039 set_params= insert_params_with_log;
4040 set_bulk_params= insert_bulk_params; // RBR is on for bulk operation
4041 #else
4042 //TODO: add bulk support for bulk parameters
4043 set_params_data= emb_insert_params_with_log;
4044 #endif
4045 }
4046 else
4047 {
4048 set_params_from_actual_params= insert_params_from_actual_params;
4049 #ifndef EMBEDDED_LIBRARY
4050 set_params= insert_params;
4051 set_bulk_params= insert_bulk_params;
4052 #else
4053 //TODO: add bulk support for bulk parameters
4054 set_params_data= emb_insert_params;
4055 #endif
4056 }
4057 }
4058
4059
4060 /**
4061 Destroy this prepared statement, cleaning up all used memory
4062 and resources.
4063
4064 This is called from ::deallocate() to handle COM_STMT_CLOSE and
4065 DEALLOCATE PREPARE or when THD ends and all prepared statements are freed.
4066 */
4067
~Prepared_statement()4068 Prepared_statement::~Prepared_statement()
4069 {
4070 DBUG_ENTER("Prepared_statement::~Prepared_statement");
4071 DBUG_PRINT("enter",("stmt: %p cursor: %p",
4072 this, cursor));
4073 delete cursor;
4074 /*
4075 We have to call free on the items even if cleanup is called as some items,
4076 like Item_param, don't free everything until free_items()
4077 */
4078 free_items();
4079 if (lex)
4080 {
4081 sp_head::destroy(lex->sphead);
4082 delete lex->result;
4083 delete (st_lex_local *) lex;
4084 }
4085 free_root(&main_mem_root, MYF(0));
4086 DBUG_VOID_RETURN;
4087 }
4088
4089
type() const4090 Query_arena::Type Prepared_statement::type() const
4091 {
4092 return PREPARED_STATEMENT;
4093 }
4094
4095
cleanup_stmt()4096 void Prepared_statement::cleanup_stmt()
4097 {
4098 DBUG_ENTER("Prepared_statement::cleanup_stmt");
4099 DBUG_PRINT("enter",("stmt: %p", this));
4100 lex->restore_set_statement_var();
4101 thd->rollback_item_tree_changes();
4102 cleanup_items(free_list);
4103 thd->cleanup_after_query();
4104
4105 DBUG_VOID_RETURN;
4106 }
4107
4108
set_name(const LEX_CSTRING * name_arg)4109 bool Prepared_statement::set_name(const LEX_CSTRING *name_arg)
4110 {
4111 name.length= name_arg->length;
4112 name.str= (char*) memdup_root(mem_root, name_arg->str, name_arg->length);
4113 return name.str == 0;
4114 }
4115
4116
4117 /**
4118 Remember the current database.
4119
4120 We must reset/restore the current database during execution of
4121 a prepared statement since it affects execution environment:
4122 privileges, @@character_set_database, and other.
4123
4124 @return 1 if out of memory.
4125 */
4126
4127 bool
set_db(const LEX_CSTRING * db_arg)4128 Prepared_statement::set_db(const LEX_CSTRING *db_arg)
4129 {
4130 /* Remember the current database. */
4131 if (db_arg->length)
4132 {
4133 if (!(db.str= this->strmake(db_arg->str, db_arg->length)))
4134 return 1;
4135 db.length= db_arg->length;
4136 }
4137 else
4138 db= null_clex_str;
4139 return 0;
4140 }
4141
4142 /**************************************************************************
4143 Common parts of mysql_[sql]_stmt_prepare, mysql_[sql]_stmt_execute.
4144 Essentially, these functions do all the magic of preparing/executing
4145 a statement, leaving network communication, input data handling and
4146 global THD state management to the caller.
4147 ***************************************************************************/
4148
4149 /**
4150 Parse statement text, validate the statement, and prepare it for execution.
4151
4152 You should not change global THD state in this function, if at all
4153 possible: it may be called from any context, e.g. when executing
4154 a COM_* command, and SQLCOM_* command, or a stored procedure.
4155
4156 @param packet statement text
4157 @param packet_len
4158
4159 @note
4160 Precondition:
4161 The caller must ensure that thd->change_list and thd->free_list
4162 is empty: this function will not back them up but will free
4163 in the end of its execution.
4164
4165 @note
4166 Postcondition:
4167 thd->mem_root contains unused memory allocated during validation.
4168 */
4169
prepare(const char * packet,uint packet_len)4170 bool Prepared_statement::prepare(const char *packet, uint packet_len)
4171 {
4172 bool error;
4173 Statement stmt_backup;
4174 Query_arena *old_stmt_arena;
4175 DBUG_ENTER("Prepared_statement::prepare");
4176 DBUG_ASSERT(m_sql_mode == thd->variables.sql_mode);
4177 /*
4178 If this is an SQLCOM_PREPARE, we also increase Com_prepare_sql.
4179 However, it seems handy if com_stmt_prepare is increased always,
4180 no matter what kind of prepare is processed.
4181 */
4182 status_var_increment(thd->status_var.com_stmt_prepare);
4183
4184 if (! (lex= new (mem_root) st_lex_local))
4185 DBUG_RETURN(TRUE);
4186 lex->stmt_lex= lex;
4187
4188 if (set_db(&thd->db))
4189 DBUG_RETURN(TRUE);
4190
4191 /*
4192 alloc_query() uses thd->mem_root && thd->query, so we should call
4193 both of backup_statement() and backup_query_arena() here.
4194 */
4195 thd->set_n_backup_statement(this, &stmt_backup);
4196 thd->set_n_backup_active_arena(this, &stmt_backup);
4197
4198 if (alloc_query(thd, packet, packet_len))
4199 {
4200 thd->restore_backup_statement(this, &stmt_backup);
4201 thd->restore_active_arena(this, &stmt_backup);
4202 DBUG_RETURN(TRUE);
4203 }
4204
4205 old_stmt_arena= thd->stmt_arena;
4206 thd->stmt_arena= this;
4207
4208 Parser_state parser_state;
4209 if (parser_state.init(thd, thd->query(), thd->query_length()))
4210 {
4211 thd->restore_backup_statement(this, &stmt_backup);
4212 thd->restore_active_arena(this, &stmt_backup);
4213 thd->stmt_arena= old_stmt_arena;
4214 DBUG_RETURN(TRUE);
4215 }
4216
4217 parser_state.m_lip.stmt_prepare_mode= TRUE;
4218 parser_state.m_lip.multi_statements= FALSE;
4219
4220 lex_start(thd);
4221 lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_PREPARE;
4222
4223 error= (parse_sql(thd, & parser_state, NULL) ||
4224 thd->is_error() ||
4225 init_param_array(this));
4226
4227 if (thd->security_ctx->password_expired &&
4228 lex->sql_command != SQLCOM_SET_OPTION)
4229 {
4230 thd->restore_backup_statement(this, &stmt_backup);
4231 thd->restore_active_arena(this, &stmt_backup);
4232 thd->stmt_arena= old_stmt_arena;
4233 my_error(ER_MUST_CHANGE_PASSWORD, MYF(0));
4234 DBUG_RETURN(true);
4235 }
4236 lex->set_trg_event_type_for_tables();
4237
4238 /*
4239 While doing context analysis of the query (in check_prepared_statement)
4240 we allocate a lot of additional memory: for open tables, JOINs, derived
4241 tables, etc. Let's save a snapshot of current parse tree to the
4242 statement and restore original THD. In cases when some tree
4243 transformation can be reused on execute, we set again thd->mem_root from
4244 stmt->mem_root (see setup_wild for one place where we do that).
4245 */
4246 thd->restore_active_arena(this, &stmt_backup);
4247
4248 /*
4249 If called from a stored procedure, ensure that we won't rollback
4250 external changes when cleaning up after validation.
4251 */
4252 DBUG_ASSERT(thd->Item_change_list::is_empty());
4253
4254 /*
4255 Marker used to release metadata locks acquired while the prepared
4256 statement is being checked.
4257 */
4258 MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint();
4259
4260 /*
4261 Set variables specified by
4262 SET STATEMENT var1=value1 [, var2=value2, ...] FOR <statement>
4263 clause for duration of prepare phase. Original values of variable
4264 listed in the SET STATEMENT clause is restored right after return
4265 from the function check_prepared_statement()
4266 */
4267 if (likely(error == 0))
4268 error= run_set_statement_if_requested(thd, lex);
4269
4270 /*
4271 The only case where we should have items in the thd->free_list is
4272 after stmt->set_params_from_vars(), which may in some cases create
4273 Item_null objects.
4274 */
4275
4276 if (likely(error == 0))
4277 error= check_prepared_statement(this);
4278
4279 if (unlikely(error))
4280 {
4281 /*
4282 let the following code know we're not in PS anymore,
4283 the won't be any EXECUTE, so we need a full cleanup
4284 */
4285 lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_PREPARE;
4286 }
4287
4288 /*
4289 Restore original values of variables modified on handling
4290 SET STATEMENT clause.
4291 */
4292 error|= thd->lex->restore_set_statement_var();
4293
4294 /* The order is important */
4295 lex->unit.cleanup();
4296
4297 /* No need to commit statement transaction, it's not started. */
4298 DBUG_ASSERT(thd->transaction.stmt.is_empty());
4299
4300 close_thread_tables(thd);
4301 thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
4302
4303 /*
4304 Transaction rollback was requested since MDL deadlock was discovered
4305 while trying to open tables. Rollback transaction in all storage
4306 engines including binary log and release all locks.
4307
4308 Once dynamic SQL is allowed as substatements the below if-statement
4309 has to be adjusted to not do rollback in substatement.
4310 */
4311 DBUG_ASSERT(! thd->in_sub_stmt);
4312 if (thd->transaction_rollback_request)
4313 {
4314 trans_rollback_implicit(thd);
4315 thd->release_transactional_locks();
4316 }
4317
4318 /* Preserve locked plugins for SET */
4319 if (lex->sql_command != SQLCOM_SET_OPTION)
4320 lex_unlock_plugins(lex);
4321
4322 cleanup_stmt();
4323 thd->restore_backup_statement(this, &stmt_backup);
4324 thd->stmt_arena= old_stmt_arena;
4325
4326 if (likely(error == 0))
4327 {
4328 setup_set_params();
4329 lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_PREPARE;
4330 state= Query_arena::STMT_PREPARED;
4331 flags&= ~ (uint) IS_IN_USE;
4332
4333 /*
4334 Log COM_EXECUTE to the general log. Note, that in case of SQL
4335 prepared statements this causes two records to be output:
4336
4337 Query PREPARE stmt from @user_variable
4338 Prepare <statement SQL text>
4339
4340 This is considered user-friendly, since in the
4341 second log entry we output the actual statement text.
4342
4343 Do not print anything if this is an SQL prepared statement and
4344 we're inside a stored procedure (also called Dynamic SQL) --
4345 sub-statements inside stored procedures are not logged into
4346 the general log.
4347 */
4348 if (thd->spcont == NULL)
4349 general_log_write(thd, COM_STMT_PREPARE, query(), query_length());
4350 }
4351 DBUG_RETURN(error);
4352 }
4353
4354
4355 /**
4356 Assign parameter values either from variables, in case of SQL PS
4357 or from the execute packet.
4358
4359 @param expanded_query a container with the original SQL statement.
4360 '?' placeholders will be replaced with
4361 their values in case of success.
4362 The result is used for logging and replication
4363 @param packet pointer to execute packet.
4364 NULL in case of SQL PS
4365 @param packet_end end of the packet. NULL in case of SQL PS
4366
4367 @todo Use a paremeter source class family instead of 'if's, and
4368 support stored procedure variables.
4369
4370 @retval TRUE an error occurred when assigning a parameter (likely
4371 a conversion error or out of memory, or malformed packet)
4372 @retval FALSE success
4373 */
4374
4375 bool
set_parameters(String * expanded_query,uchar * packet,uchar * packet_end)4376 Prepared_statement::set_parameters(String *expanded_query,
4377 uchar *packet, uchar *packet_end)
4378 {
4379 bool is_sql_ps= packet == NULL;
4380 bool res= FALSE;
4381
4382 if (is_sql_ps)
4383 {
4384 /* SQL prepared statement */
4385 res= set_params_from_actual_params(this, thd->lex->prepared_stmt.params(),
4386 expanded_query);
4387 }
4388 else if (param_count)
4389 {
4390 #ifndef EMBEDDED_LIBRARY
4391 uchar *null_array= packet;
4392 res= (setup_conversion_functions(this, &packet) ||
4393 set_params(this, null_array, packet, packet_end, expanded_query));
4394 #else
4395 /*
4396 In embedded library we re-install conversion routines each time
4397 we set parameters, and also we don't need to parse packet.
4398 So we do it in one function.
4399 */
4400 res= set_params_data(this, expanded_query);
4401 #endif
4402 }
4403 if (res)
4404 {
4405 my_error(ER_WRONG_ARGUMENTS, MYF(0),
4406 is_sql_ps ? "EXECUTE" : "mysqld_stmt_execute");
4407 reset_stmt_params(this);
4408 }
4409 return res;
4410 }
4411
4412
4413 /**
4414 Execute a prepared statement. Re-prepare it a limited number
4415 of times if necessary.
4416
4417 Try to execute a prepared statement. If there is a metadata
4418 validation error, prepare a new copy of the prepared statement,
4419 swap the old and the new statements, and try again.
4420 If there is a validation error again, repeat the above, but
4421 perform no more than MAX_REPREPARE_ATTEMPTS.
4422
4423 @note We have to try several times in a loop since we
4424 release metadata locks on tables after prepared statement
4425 prepare. Therefore, a DDL statement may sneak in between prepare
4426 and execute of a new statement. If this happens repeatedly
4427 more than MAX_REPREPARE_ATTEMPTS times, we give up.
4428
4429 @return TRUE if an error, FALSE if success
4430 @retval TRUE either MAX_REPREPARE_ATTEMPTS has been reached,
4431 or some general error
4432 @retval FALSE successfully executed the statement, perhaps
4433 after having reprepared it a few times.
4434 */
4435 const static int MAX_REPREPARE_ATTEMPTS= 3;
4436
4437 bool
execute_loop(String * expanded_query,bool open_cursor,uchar * packet,uchar * packet_end)4438 Prepared_statement::execute_loop(String *expanded_query,
4439 bool open_cursor,
4440 uchar *packet,
4441 uchar *packet_end)
4442 {
4443 Reprepare_observer reprepare_observer;
4444 bool error;
4445 int reprepare_attempt= 0;
4446 iterations= FALSE;
4447
4448 /*
4449 - In mysql_sql_stmt_execute() we hide all "external" Items
4450 e.g. those created in the "SET STATEMENT" part of the "EXECUTE" query.
4451 - In case of mysqld_stmt_execute() there should not be "external" Items.
4452 */
4453 DBUG_ASSERT(thd->free_list == NULL);
4454
4455 /* Check if we got an error when sending long data */
4456 if (unlikely(state == Query_arena::STMT_ERROR))
4457 {
4458 my_message(last_errno, last_error, MYF(0));
4459 return TRUE;
4460 }
4461
4462 if (set_parameters(expanded_query, packet, packet_end))
4463 return TRUE;
4464
4465 reexecute:
4466 // Make sure that reprepare() did not create any new Items.
4467 DBUG_ASSERT(thd->free_list == NULL);
4468
4469 /*
4470 Install the metadata observer. If some metadata version is
4471 different from prepare time and an observer is installed,
4472 the observer method will be invoked to push an error into
4473 the error stack.
4474 */
4475
4476 if (sql_command_flags[lex->sql_command] & CF_REEXECUTION_FRAGILE)
4477 {
4478 reprepare_observer.reset_reprepare_observer();
4479 DBUG_ASSERT(thd->m_reprepare_observer == NULL);
4480 thd->m_reprepare_observer= &reprepare_observer;
4481 }
4482
4483 error= execute(expanded_query, open_cursor) || thd->is_error();
4484
4485 thd->m_reprepare_observer= NULL;
4486
4487 if (unlikely(error) &&
4488 (sql_command_flags[lex->sql_command] & CF_REEXECUTION_FRAGILE) &&
4489 !thd->is_fatal_error && !thd->killed &&
4490 reprepare_observer.is_invalidated() &&
4491 reprepare_attempt++ < MAX_REPREPARE_ATTEMPTS)
4492 {
4493 DBUG_ASSERT(thd->get_stmt_da()->sql_errno() == ER_NEED_REPREPARE);
4494 thd->clear_error();
4495
4496 error= reprepare();
4497
4498 if (likely(!error)) /* Success */
4499 goto reexecute;
4500 }
4501 reset_stmt_params(this);
4502
4503 return error;
4504 }
4505
bulk_parameters_set(THD * thd)4506 my_bool bulk_parameters_set(THD *thd)
4507 {
4508 DBUG_ENTER("bulk_parameters_set");
4509 Prepared_statement *stmt= (Prepared_statement *) thd->bulk_param;
4510
4511 if (stmt && unlikely(stmt->set_bulk_parameters(FALSE)))
4512 DBUG_RETURN(TRUE);
4513 DBUG_RETURN(FALSE);
4514 }
4515
bulk_parameters_iterations(THD * thd)4516 my_bool bulk_parameters_iterations(THD *thd)
4517 {
4518 Prepared_statement *stmt= (Prepared_statement *) thd->bulk_param;
4519 if (!stmt)
4520 return FALSE;
4521 return stmt->bulk_iterations();
4522 }
4523
4524
set_bulk_parameters(bool reset)4525 my_bool Prepared_statement::set_bulk_parameters(bool reset)
4526 {
4527 DBUG_ENTER("Prepared_statement::set_bulk_parameters");
4528 DBUG_PRINT("info", ("iteration: %d", iterations));
4529
4530 if (iterations)
4531 {
4532 #ifndef EMBEDDED_LIBRARY
4533 if ((*set_bulk_params)(this, &packet, packet_end, reset))
4534 #else
4535 // bulk parameters are not supported for embedded, so it will an error
4536 #endif
4537 {
4538 my_error(ER_WRONG_ARGUMENTS, MYF(0),
4539 "mysqld_stmt_bulk_execute");
4540 reset_stmt_params(this);
4541 DBUG_RETURN(true);
4542 }
4543 if (packet >= packet_end)
4544 iterations= FALSE;
4545 }
4546 start_param= 0;
4547 DBUG_RETURN(false);
4548 }
4549
4550 bool
execute_bulk_loop(String * expanded_query,bool open_cursor,uchar * packet_arg,uchar * packet_end_arg)4551 Prepared_statement::execute_bulk_loop(String *expanded_query,
4552 bool open_cursor,
4553 uchar *packet_arg,
4554 uchar *packet_end_arg)
4555 {
4556 Reprepare_observer reprepare_observer;
4557 bool error= 0;
4558 packet= packet_arg;
4559 packet_end= packet_end_arg;
4560 iterations= TRUE;
4561 start_param= true;
4562 #ifdef DBUG_ASSERT_EXISTS
4563 Item *free_list_state= thd->free_list;
4564 #endif
4565 thd->set_bulk_execution((void *)this);
4566 /* Check if we got an error when sending long data */
4567 if (state == Query_arena::STMT_ERROR)
4568 {
4569 my_message(last_errno, last_error, MYF(0));
4570 thd->set_bulk_execution(0);
4571 return TRUE;
4572 }
4573 /* Check for non zero parameter count*/
4574 if (param_count == 0)
4575 {
4576 DBUG_PRINT("error", ("Statement with no parameters for bulk execution."));
4577 my_error(ER_UNSUPPORTED_PS, MYF(0));
4578 thd->set_bulk_execution(0);
4579 return TRUE;
4580 }
4581
4582 if (!(sql_command_flags[lex->sql_command] & CF_PS_ARRAY_BINDING_SAFE))
4583 {
4584 DBUG_PRINT("error", ("Command is not supported in bulk execution."));
4585 my_error(ER_UNSUPPORTED_PS, MYF(0));
4586 thd->set_bulk_execution(0);
4587 return TRUE;
4588 }
4589
4590 #ifndef EMBEDDED_LIBRARY
4591 if (read_types &&
4592 set_conversion_functions(this, &packet))
4593 #else
4594 // bulk parameters are not supported for embedded, so it will an error
4595 #endif
4596 {
4597 my_error(ER_WRONG_ARGUMENTS, MYF(0),
4598 "mysqld_stmt_bulk_execute");
4599 reset_stmt_params(this);
4600 thd->set_bulk_execution(0);
4601 return true;
4602 }
4603 read_types= FALSE;
4604
4605 // iterations changed by set_bulk_parameters
4606 while ((iterations || start_param) && !error && !thd->is_error())
4607 {
4608 int reprepare_attempt= 0;
4609
4610 /*
4611 Here we set parameters for not optimized commands,
4612 optimized commands do it inside thier internal loop.
4613 */
4614 if (!(sql_command_flags[lex->sql_command] & CF_PS_ARRAY_BINDING_OPTIMIZED))
4615 {
4616 if (set_bulk_parameters(TRUE))
4617 {
4618 thd->set_bulk_execution(0);
4619 return true;
4620 }
4621 }
4622
4623 reexecute:
4624 /*
4625 If the free_list is not empty, we'll wrongly free some externally
4626 allocated items when cleaning up after validation of the prepared
4627 statement.
4628 */
4629 DBUG_ASSERT(thd->free_list == free_list_state);
4630
4631 /*
4632 Install the metadata observer. If some metadata version is
4633 different from prepare time and an observer is installed,
4634 the observer method will be invoked to push an error into
4635 the error stack.
4636 */
4637
4638 if (sql_command_flags[lex->sql_command] & CF_REEXECUTION_FRAGILE)
4639 {
4640 reprepare_observer.reset_reprepare_observer();
4641 DBUG_ASSERT(thd->m_reprepare_observer == NULL);
4642 thd->m_reprepare_observer= &reprepare_observer;
4643 }
4644
4645 error= execute(expanded_query, open_cursor) || thd->is_error();
4646
4647 thd->m_reprepare_observer= NULL;
4648
4649 #ifdef WITH_WSREP
4650 if (!(sql_command_flags[lex->sql_command] & CF_PS_ARRAY_BINDING_OPTIMIZED) &&
4651 WSREP(thd))
4652 {
4653 if (wsrep_after_statement(thd))
4654 {
4655 /*
4656 Re-execution success is unlikely after an error from
4657 wsrep_after_statement(), so retrun error immediately.
4658 */
4659 thd->get_stmt_da()->reset_diagnostics_area();
4660 wsrep_override_error(thd, thd->wsrep_cs().current_error(),
4661 thd->wsrep_cs().current_error_status());
4662 }
4663 }
4664 else
4665 #endif /* WITH_WSREP */
4666 if (unlikely(error) &&
4667 (sql_command_flags[lex->sql_command] & CF_REEXECUTION_FRAGILE) &&
4668 !thd->is_fatal_error && !thd->killed &&
4669 reprepare_observer.is_invalidated() &&
4670 reprepare_attempt++ < MAX_REPREPARE_ATTEMPTS)
4671 {
4672 DBUG_ASSERT(thd->get_stmt_da()->sql_errno() == ER_NEED_REPREPARE);
4673 thd->clear_error();
4674
4675 error= reprepare();
4676
4677 if (likely(!error)) /* Success */
4678 goto reexecute;
4679 }
4680 }
4681 reset_stmt_params(this);
4682 thd->set_bulk_execution(0);
4683
4684 return error;
4685 }
4686
4687
4688 bool
execute_server_runnable(Server_runnable * server_runnable)4689 Prepared_statement::execute_server_runnable(Server_runnable *server_runnable)
4690 {
4691 Statement stmt_backup;
4692 bool error;
4693 Query_arena *save_stmt_arena= thd->stmt_arena;
4694 Item_change_list save_change_list;
4695 thd->Item_change_list::move_elements_to(&save_change_list);
4696
4697 state= STMT_CONVENTIONAL_EXECUTION;
4698
4699 if (!(lex= new (mem_root) st_lex_local))
4700 return TRUE;
4701
4702 thd->set_n_backup_statement(this, &stmt_backup);
4703 thd->set_n_backup_active_arena(this, &stmt_backup);
4704 thd->stmt_arena= this;
4705
4706 error= server_runnable->execute_server_code(thd);
4707
4708 thd->cleanup_after_query();
4709
4710 thd->restore_active_arena(this, &stmt_backup);
4711 thd->restore_backup_statement(this, &stmt_backup);
4712 thd->stmt_arena= save_stmt_arena;
4713
4714 save_change_list.move_elements_to(thd);
4715
4716 /* Items and memory will freed in destructor */
4717
4718 return error;
4719 }
4720
4721
4722 /**
4723 Reprepare this prepared statement.
4724
4725 Currently this is implemented by creating a new prepared
4726 statement, preparing it with the original query and then
4727 swapping the new statement and the original one.
4728
4729 @retval TRUE an error occurred. Possible errors include
4730 incompatibility of new and old result set
4731 metadata
4732 @retval FALSE success, the statement has been reprepared
4733 */
4734
4735 bool
reprepare()4736 Prepared_statement::reprepare()
4737 {
4738 char saved_cur_db_name_buf[SAFE_NAME_LEN+1];
4739 LEX_STRING saved_cur_db_name=
4740 { saved_cur_db_name_buf, sizeof(saved_cur_db_name_buf) };
4741 LEX_CSTRING stmt_db_name= db;
4742 bool cur_db_changed;
4743 bool error;
4744
4745 Prepared_statement copy(thd);
4746 copy.m_sql_mode= m_sql_mode;
4747
4748 copy.set_sql_prepare(); /* To suppress sending metadata to the client. */
4749
4750 status_var_increment(thd->status_var.com_stmt_reprepare);
4751
4752 if (unlikely(mysql_opt_change_db(thd, &stmt_db_name, &saved_cur_db_name,
4753 TRUE, &cur_db_changed)))
4754 return TRUE;
4755
4756 sql_mode_t save_sql_mode= thd->variables.sql_mode;
4757 thd->variables.sql_mode= m_sql_mode;
4758 error= ((name.str && copy.set_name(&name)) ||
4759 copy.prepare(query(), query_length()) ||
4760 validate_metadata(©));
4761 thd->variables.sql_mode= save_sql_mode;
4762
4763 if (cur_db_changed)
4764 mysql_change_db(thd, (LEX_CSTRING*) &saved_cur_db_name, TRUE);
4765
4766 if (likely(!error))
4767 {
4768 swap_prepared_statement(©);
4769 swap_parameter_array(param_array, copy.param_array, param_count);
4770 #ifdef DBUG_ASSERT_EXISTS
4771 is_reprepared= TRUE;
4772 #endif
4773 /*
4774 Clear possible warnings during reprepare, it has to be completely
4775 transparent to the user. We use clear_warning_info() since
4776 there were no separate query id issued for re-prepare.
4777 Sic: we can't simply silence warnings during reprepare, because if
4778 it's failed, we need to return all the warnings to the user.
4779 */
4780 thd->get_stmt_da()->clear_warning_info(thd->query_id);
4781 }
4782 return error;
4783 }
4784
4785
4786 /**
4787 Validate statement result set metadata (if the statement returns
4788 a result set).
4789
4790 Currently we only check that the number of columns of the result
4791 set did not change.
4792 This is a helper method used during re-prepare.
4793
4794 @param[in] copy the re-prepared prepared statement to verify
4795 the metadata of
4796
4797 @retval TRUE error, ER_PS_REBIND is reported
4798 @retval FALSE statement return no or compatible metadata
4799 */
4800
4801
validate_metadata(Prepared_statement * copy)4802 bool Prepared_statement::validate_metadata(Prepared_statement *copy)
4803 {
4804 /**
4805 If this is an SQL prepared statement or EXPLAIN,
4806 return FALSE -- the metadata of the original SELECT,
4807 if any, has not been sent to the client.
4808 */
4809 if (is_sql_prepare() || lex->describe)
4810 return FALSE;
4811
4812 if (lex->first_select_lex()->item_list.elements !=
4813 copy->lex->first_select_lex()->item_list.elements)
4814 {
4815 /** Column counts mismatch, update the client */
4816 thd->server_status|= SERVER_STATUS_METADATA_CHANGED;
4817 }
4818
4819 return FALSE;
4820 }
4821
4822
4823 /**
4824 Replace the original prepared statement with a prepared copy.
4825
4826 This is a private helper that is used as part of statement
4827 reprepare
4828
4829 @return This function does not return any errors.
4830 */
4831
4832 void
swap_prepared_statement(Prepared_statement * copy)4833 Prepared_statement::swap_prepared_statement(Prepared_statement *copy)
4834 {
4835 Statement tmp_stmt;
4836
4837 /* Swap memory roots. */
4838 swap_variables(MEM_ROOT, main_mem_root, copy->main_mem_root);
4839
4840 /* Swap the arenas */
4841 tmp_stmt.set_query_arena(this);
4842 set_query_arena(copy);
4843 copy->set_query_arena(&tmp_stmt);
4844
4845 /* Swap the statement parent classes */
4846 tmp_stmt.set_statement(this);
4847 set_statement(copy);
4848 copy->set_statement(&tmp_stmt);
4849
4850 /* Swap ids back, we need the original id */
4851 swap_variables(ulong, id, copy->id);
4852 /* Swap mem_roots back, they must continue pointing at the main_mem_roots */
4853 swap_variables(MEM_ROOT *, mem_root, copy->mem_root);
4854 /*
4855 Swap the old and the new parameters array. The old array
4856 is allocated in the old arena.
4857 */
4858 swap_variables(Item_param **, param_array, copy->param_array);
4859 /* Don't swap flags: the copy has IS_SQL_PREPARE always set. */
4860 /* swap_variables(uint, flags, copy->flags); */
4861 /* Swap names, the old name is allocated in the wrong memory root */
4862 swap_variables(LEX_CSTRING, name, copy->name);
4863 /* Ditto */
4864 swap_variables(LEX_CSTRING, db, copy->db);
4865
4866 DBUG_ASSERT(param_count == copy->param_count);
4867 DBUG_ASSERT(thd == copy->thd);
4868 last_error[0]= '\0';
4869 last_errno= 0;
4870 }
4871
4872
4873 /**
4874 Execute a prepared statement.
4875
4876 You should not change global THD state in this function, if at all
4877 possible: it may be called from any context, e.g. when executing
4878 a COM_* command, and SQLCOM_* command, or a stored procedure.
4879
4880 @param expanded_query A query for binlogging which has all parameter
4881 markers ('?') replaced with their actual values.
4882 @param open_cursor True if an attempt to open a cursor should be made.
4883 Currenlty used only in the binary protocol.
4884
4885 @note
4886 Preconditions, postconditions.
4887 - See the comment for Prepared_statement::prepare().
4888
4889 @retval
4890 FALSE ok
4891 @retval
4892 TRUE Error
4893 */
4894
execute(String * expanded_query,bool open_cursor)4895 bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
4896 {
4897 Statement stmt_backup;
4898 Query_arena *old_stmt_arena;
4899 bool error= TRUE;
4900 bool qc_executed= FALSE;
4901
4902 char saved_cur_db_name_buf[SAFE_NAME_LEN+1];
4903 LEX_STRING saved_cur_db_name=
4904 { saved_cur_db_name_buf, sizeof(saved_cur_db_name_buf) };
4905 bool cur_db_changed;
4906
4907 LEX_CSTRING stmt_db_name= db;
4908
4909 status_var_increment(thd->status_var.com_stmt_execute);
4910
4911 if (flags & (uint) IS_IN_USE)
4912 {
4913 my_error(ER_PS_NO_RECURSION, MYF(0));
4914 return TRUE;
4915 }
4916
4917 /*
4918 For SHOW VARIABLES lex->result is NULL, as it's a non-SELECT
4919 command. For such queries we don't return an error and don't
4920 open a cursor -- the client library will recognize this case and
4921 materialize the result set.
4922 For SELECT statements lex->result is created in
4923 check_prepared_statement. lex->result->simple_select() is FALSE
4924 in INSERT ... SELECT and similar commands.
4925 */
4926
4927 if (open_cursor && lex->result && lex->result->check_simple_select())
4928 {
4929 DBUG_PRINT("info",("Cursor asked for not SELECT stmt"));
4930 return TRUE;
4931 }
4932
4933 /* In case the command has a call to SP which re-uses this statement name */
4934 flags|= IS_IN_USE;
4935
4936 close_cursor();
4937
4938 /*
4939 If the free_list is not empty, we'll wrongly free some externally
4940 allocated items when cleaning up after execution of this statement.
4941 */
4942 DBUG_ASSERT(thd->Item_change_list::is_empty());
4943
4944 /*
4945 The only case where we should have items in the thd->free_list is
4946 after stmt->set_params_from_vars(), which may in some cases create
4947 Item_null objects.
4948 */
4949
4950 thd->set_n_backup_statement(this, &stmt_backup);
4951
4952 /*
4953 Change the current database (if needed).
4954
4955 Force switching, because the database of the prepared statement may be
4956 NULL (prepared statements can be created while no current database
4957 selected).
4958 */
4959
4960 if (mysql_opt_change_db(thd, &stmt_db_name, &saved_cur_db_name, TRUE,
4961 &cur_db_changed))
4962 goto error;
4963
4964 /* Allocate query. */
4965
4966 if (expanded_query->length() &&
4967 alloc_query(thd, (char*) expanded_query->ptr(),
4968 expanded_query->length()))
4969 {
4970 my_error(ER_OUTOFMEMORY, MYF(ME_FATAL), expanded_query->length());
4971 goto error;
4972 }
4973 /*
4974 Expanded query is needed for slow logging, so we want thd->query
4975 to point at it even after we restore from backup. This is ok, as
4976 expanded query was allocated in thd->mem_root.
4977 */
4978 stmt_backup.set_query_inner(thd->query_string);
4979
4980 /*
4981 At first execution of prepared statement we may perform logical
4982 transformations of the query tree. Such changes should be performed
4983 on the parse tree of current prepared statement and new items should
4984 be allocated in its memory root. Set the appropriate pointer in THD
4985 to the arena of the statement.
4986 */
4987 old_stmt_arena= thd->stmt_arena;
4988 thd->stmt_arena= this;
4989 reinit_stmt_before_use(thd, lex);
4990
4991 /* Go! */
4992
4993 if (open_cursor)
4994 error= mysql_open_cursor(thd, &result, &cursor);
4995 else
4996 {
4997 /*
4998 Try to find it in the query cache, if not, execute it.
4999 Note that multi-statements cannot exist here (they are not supported in
5000 prepared statements).
5001 */
5002 if (query_cache_send_result_to_client(thd, thd->query(),
5003 thd->query_length()) <= 0)
5004 {
5005 PSI_statement_locker *parent_locker;
5006 MYSQL_QUERY_EXEC_START(thd->query(),
5007 thd->thread_id,
5008 thd->get_db(),
5009 &thd->security_ctx->priv_user[0],
5010 (char *) thd->security_ctx->host_or_ip,
5011 1);
5012 parent_locker= thd->m_statement_psi;
5013 thd->m_statement_psi= NULL;
5014 error= mysql_execute_command(thd);
5015 thd->m_statement_psi= parent_locker;
5016 MYSQL_QUERY_EXEC_DONE(error);
5017 }
5018 else
5019 {
5020 thd->lex->sql_command= SQLCOM_SELECT;
5021 status_var_increment(thd->status_var.com_stat[SQLCOM_SELECT]);
5022 thd->update_stats();
5023 qc_executed= TRUE;
5024 }
5025 }
5026
5027 /*
5028 Restore the current database (if changed).
5029
5030 Force switching back to the saved current database (if changed),
5031 because it may be NULL. In this case, mysql_change_db() would generate
5032 an error.
5033 */
5034
5035 if (cur_db_changed)
5036 mysql_change_db(thd, (LEX_CSTRING*) &saved_cur_db_name, TRUE);
5037
5038 /* Assert that if an error, no cursor is open */
5039 DBUG_ASSERT(! (error && cursor));
5040
5041 if (! cursor)
5042 cleanup_stmt();
5043
5044 /*
5045 EXECUTE command has its own dummy "explain data". We don't need it,
5046 instead, we want to keep the query plan of the statement that was
5047 executed.
5048 */
5049 if (!stmt_backup.lex->explain ||
5050 !stmt_backup.lex->explain->have_query_plan())
5051 {
5052 delete_explain_query(stmt_backup.lex);
5053 stmt_backup.lex->explain = thd->lex->explain;
5054 thd->lex->explain= NULL;
5055 }
5056 else
5057 delete_explain_query(thd->lex);
5058
5059 thd->set_statement(&stmt_backup);
5060 thd->stmt_arena= old_stmt_arena;
5061
5062 if (state == Query_arena::STMT_PREPARED && !qc_executed)
5063 state= Query_arena::STMT_EXECUTED;
5064
5065 if (likely(error == 0) && this->lex->sql_command == SQLCOM_CALL)
5066 {
5067 if (is_sql_prepare())
5068 {
5069 /*
5070 Here we have the diagnostics area status already set to DA_OK.
5071 sent_out_parameters() can raise errors when assigning OUT parameters:
5072 DECLARE a DATETIME;
5073 EXECUTE IMMEDIATE 'CALL p1(?)' USING a;
5074 when the procedure p1 assigns a DATETIME-incompatible value (e.g. 10)
5075 to the out parameter. Allow to overwrite status (to DA_ERROR).
5076 */
5077 thd->get_stmt_da()->set_overwrite_status(true);
5078 thd->protocol_text.send_out_parameters(&this->lex->param_list);
5079 thd->get_stmt_da()->set_overwrite_status(false);
5080 }
5081 else
5082 thd->protocol->send_out_parameters(&this->lex->param_list);
5083 }
5084
5085 /*
5086 Log COM_EXECUTE to the general log. Note, that in case of SQL
5087 prepared statements this causes two records to be output:
5088
5089 Query EXECUTE <statement name>
5090 Execute <statement SQL text>
5091
5092 This is considered user-friendly, since in the
5093 second log entry we output values of parameter markers.
5094
5095 Do not print anything if this is an SQL prepared statement and
5096 we're inside a stored procedure (also called Dynamic SQL) --
5097 sub-statements inside stored procedures are not logged into
5098 the general log.
5099 */
5100 if (likely(error == 0 && thd->spcont == NULL))
5101 general_log_write(thd, COM_STMT_EXECUTE, thd->query(), thd->query_length());
5102
5103 error:
5104 thd->lex->restore_set_statement_var();
5105 flags&= ~ (uint) IS_IN_USE;
5106 return error;
5107 }
5108
5109
5110 /**
5111 Prepare, execute and clean-up a statement.
5112 @param query - query text
5113 @param length - query text length
5114 @retval true - the query was not executed (parse error, wrong parameters)
5115 @retval false - the query was prepared and executed
5116
5117 Note, if some error happened during execution, it still returns "false".
5118 */
execute_immediate(const char * query,uint query_len)5119 bool Prepared_statement::execute_immediate(const char *query, uint query_len)
5120 {
5121 DBUG_ENTER("Prepared_statement::execute_immediate");
5122 String expanded_query;
5123 static LEX_CSTRING execute_immediate_stmt_name=
5124 {STRING_WITH_LEN("(immediate)") };
5125
5126 set_sql_prepare();
5127 name= execute_immediate_stmt_name; // for DBUG_PRINT etc
5128 if (unlikely(prepare(query, query_len)))
5129 DBUG_RETURN(true);
5130
5131 if (param_count != thd->lex->prepared_stmt.param_count())
5132 {
5133 my_error(ER_WRONG_ARGUMENTS, MYF(0), "EXECUTE");
5134 deallocate_immediate();
5135 DBUG_RETURN(true);
5136 }
5137
5138 (void) execute_loop(&expanded_query, FALSE, NULL, NULL);
5139 deallocate_immediate();
5140 DBUG_RETURN(false);
5141 }
5142
5143
5144 /**
5145 Common part of DEALLOCATE PREPARE, EXECUTE IMMEDIATE, mysqld_stmt_close.
5146 */
deallocate_immediate()5147 void Prepared_statement::deallocate_immediate()
5148 {
5149 /* We account deallocate in the same manner as mysqld_stmt_close */
5150 status_var_increment(thd->status_var.com_stmt_close);
5151
5152 /* It should now be safe to reset CHANGE MASTER parameters */
5153 lex_end(lex);
5154 }
5155
5156
5157 /** Common part of DEALLOCATE PREPARE and mysqld_stmt_close. */
5158
deallocate()5159 void Prepared_statement::deallocate()
5160 {
5161 deallocate_immediate();
5162 /* Statement map calls delete stmt on erase */
5163 thd->stmt_map.erase(this);
5164 }
5165
5166
5167 /***************************************************************************
5168 * Ed_result_set
5169 ***************************************************************************/
5170 /**
5171 Use operator delete to free memory of Ed_result_set.
5172 Accessing members of a class after the class has been destroyed
5173 is a violation of the C++ standard but is commonly used in the
5174 server code.
5175 */
5176
operator delete(void * ptr,size_t size)5177 void Ed_result_set::operator delete(void *ptr, size_t size) throw ()
5178 {
5179 if (ptr)
5180 {
5181 /*
5182 Make a stack copy, otherwise free_root() will attempt to
5183 write to freed memory.
5184 */
5185 MEM_ROOT own_root= ((Ed_result_set*) ptr)->m_mem_root;
5186 free_root(&own_root, MYF(0));
5187 }
5188 }
5189
5190
5191 /**
5192 Initialize an instance of Ed_result_set.
5193
5194 Instances of the class, as well as all result set rows, are
5195 always allocated in the memory root passed over as the second
5196 argument. In the constructor, we take over ownership of the
5197 memory root. It will be freed when the class is destroyed.
5198
5199 sic: Ed_result_est is not designed to be allocated on stack.
5200 */
5201
Ed_result_set(List<Ed_row> * rows_arg,size_t column_count_arg,MEM_ROOT * mem_root_arg)5202 Ed_result_set::Ed_result_set(List<Ed_row> *rows_arg,
5203 size_t column_count_arg,
5204 MEM_ROOT *mem_root_arg)
5205 :m_mem_root(*mem_root_arg),
5206 m_column_count(column_count_arg),
5207 m_rows(rows_arg),
5208 m_next_rset(NULL)
5209 {
5210 /* Take over responsibility for the memory */
5211 clear_alloc_root(mem_root_arg);
5212 }
5213
5214 /***************************************************************************
5215 * Ed_result_set
5216 ***************************************************************************/
5217
5218 /**
5219 Create a new "execute direct" connection.
5220 */
5221
Ed_connection(THD * thd)5222 Ed_connection::Ed_connection(THD *thd)
5223 :m_diagnostics_area(thd->query_id, false, true),
5224 m_thd(thd),
5225 m_rsets(0),
5226 m_current_rset(0)
5227 {
5228 }
5229
5230
5231 /**
5232 Free all result sets of the previous statement, if any,
5233 and reset warnings and errors.
5234
5235 Called before execution of the next query.
5236 */
5237
5238 void
free_old_result()5239 Ed_connection::free_old_result()
5240 {
5241 while (m_rsets)
5242 {
5243 Ed_result_set *rset= m_rsets->m_next_rset;
5244 delete m_rsets;
5245 m_rsets= rset;
5246 }
5247 m_current_rset= m_rsets;
5248 m_diagnostics_area.reset_diagnostics_area();
5249 m_diagnostics_area.clear_warning_info(m_thd->query_id);
5250 }
5251
5252
5253 /**
5254 A simple wrapper that uses a helper class to execute SQL statements.
5255 */
5256
5257 bool
execute_direct(LEX_STRING sql_text)5258 Ed_connection::execute_direct(LEX_STRING sql_text)
5259 {
5260 Execute_sql_statement execute_sql_statement(sql_text);
5261 DBUG_PRINT("ed_query", ("%s", sql_text.str));
5262
5263 return execute_direct(&execute_sql_statement);
5264 }
5265
5266
5267 /**
5268 Execute a fragment of server functionality without an effect on
5269 thd, and store results in memory.
5270
5271 Conventions:
5272 - the code fragment must finish with OK, EOF or ERROR.
5273 - the code fragment doesn't have to close thread tables,
5274 free memory, commit statement transaction or do any other
5275 cleanup that is normally done in the end of dispatch_command().
5276
5277 @param server_runnable A code fragment to execute.
5278 */
5279
execute_direct(Server_runnable * server_runnable)5280 bool Ed_connection::execute_direct(Server_runnable *server_runnable)
5281 {
5282 bool rc= FALSE;
5283 Protocol_local protocol_local(m_thd, this);
5284 Prepared_statement stmt(m_thd);
5285 Protocol *save_protocol= m_thd->protocol;
5286 Diagnostics_area *save_diagnostics_area= m_thd->get_stmt_da();
5287
5288 DBUG_ENTER("Ed_connection::execute_direct");
5289
5290 free_old_result(); /* Delete all data from previous execution, if any */
5291
5292 m_thd->protocol= &protocol_local;
5293 m_thd->set_stmt_da(&m_diagnostics_area);
5294
5295 rc= stmt.execute_server_runnable(server_runnable);
5296 m_thd->protocol->end_statement();
5297
5298 m_thd->protocol= save_protocol;
5299 m_thd->set_stmt_da(save_diagnostics_area);
5300 /*
5301 Protocol_local makes use of m_current_rset to keep
5302 track of the last result set, while adding result sets to the end.
5303 Reset it to point to the first result set instead.
5304 */
5305 m_current_rset= m_rsets;
5306
5307 DBUG_RETURN(rc);
5308 }
5309
5310
5311 /**
5312 A helper method that is called only during execution.
5313
5314 Although Ed_connection doesn't support multi-statements,
5315 a statement may generate many result sets. All subsequent
5316 result sets are appended to the end.
5317
5318 @pre This is called only by Protocol_local.
5319 */
5320
5321 void
add_result_set(Ed_result_set * ed_result_set)5322 Ed_connection::add_result_set(Ed_result_set *ed_result_set)
5323 {
5324 if (m_rsets)
5325 {
5326 m_current_rset->m_next_rset= ed_result_set;
5327 /* While appending, use m_current_rset as a pointer to the tail. */
5328 m_current_rset= ed_result_set;
5329 }
5330 else
5331 m_current_rset= m_rsets= ed_result_set;
5332 }
5333
5334
5335 /**
5336 Release ownership of the current result set to the client.
5337
5338 Since we use a simple linked list for result sets,
5339 this method uses a linear search of the previous result
5340 set to exclude the released instance from the list.
5341
5342 @todo Use double-linked list, when this is really used.
5343
5344 XXX: This has never been tested with more than one result set!
5345
5346 @pre There must be a result set.
5347 */
5348
5349 Ed_result_set *
store_result_set()5350 Ed_connection::store_result_set()
5351 {
5352 Ed_result_set *ed_result_set;
5353
5354 DBUG_ASSERT(m_current_rset);
5355
5356 if (m_current_rset == m_rsets)
5357 {
5358 /* Assign the return value */
5359 ed_result_set= m_current_rset;
5360 /* Exclude the return value from the list. */
5361 m_current_rset= m_rsets= m_rsets->m_next_rset;
5362 }
5363 else
5364 {
5365 Ed_result_set *prev_rset= m_rsets;
5366 /* Assign the return value. */
5367 ed_result_set= m_current_rset;
5368
5369 /* Exclude the return value from the list */
5370 while (prev_rset->m_next_rset != m_current_rset)
5371 prev_rset= ed_result_set->m_next_rset;
5372 m_current_rset= prev_rset->m_next_rset= m_current_rset->m_next_rset;
5373 }
5374 ed_result_set->m_next_rset= NULL; /* safety */
5375
5376 return ed_result_set;
5377 }
5378
5379 /*************************************************************************
5380 * Protocol_local
5381 **************************************************************************/
5382
Protocol_local(THD * thd,Ed_connection * ed_connection)5383 Protocol_local::Protocol_local(THD *thd, Ed_connection *ed_connection)
5384 :Protocol(thd),
5385 m_connection(ed_connection),
5386 m_rset(NULL),
5387 m_column_count(0),
5388 m_current_row(NULL),
5389 m_current_column(NULL)
5390 {
5391 clear_alloc_root(&m_rset_root);
5392 }
5393
5394 /**
5395 Called between two result set rows.
5396
5397 Prepare structures to fill result set rows.
5398 Unfortunately, we can't return an error here. If memory allocation
5399 fails, we'll have to return an error later. And so is done
5400 in methods such as @sa store_column().
5401 */
5402
prepare_for_resend()5403 void Protocol_local::prepare_for_resend()
5404 {
5405 DBUG_ASSERT(alloc_root_inited(&m_rset_root));
5406
5407 opt_add_row_to_rset();
5408 /* Start a new row. */
5409 m_current_row= (Ed_column *) alloc_root(&m_rset_root,
5410 sizeof(Ed_column) * m_column_count);
5411 m_current_column= m_current_row;
5412 }
5413
5414
5415 /**
5416 In "real" protocols this is called to finish a result set row.
5417 Unused in the local implementation.
5418 */
5419
write()5420 bool Protocol_local::write()
5421 {
5422 return FALSE;
5423 }
5424
5425 /**
5426 A helper function to add the current row to the current result
5427 set. Called in @sa prepare_for_resend(), when a new row is started,
5428 and in send_eof(), when the result set is finished.
5429 */
5430
opt_add_row_to_rset()5431 void Protocol_local::opt_add_row_to_rset()
5432 {
5433 if (m_current_row)
5434 {
5435 /* Add the old row to the result set */
5436 Ed_row *ed_row= new (&m_rset_root) Ed_row(m_current_row, m_column_count);
5437 if (ed_row)
5438 m_rset->push_back(ed_row, &m_rset_root);
5439 }
5440 }
5441
5442
5443 /**
5444 Add a NULL column to the current row.
5445 */
5446
store_null()5447 bool Protocol_local::store_null()
5448 {
5449 if (m_current_column == NULL)
5450 return TRUE; /* prepare_for_resend() failed to allocate memory. */
5451
5452 bzero(m_current_column, sizeof(*m_current_column));
5453 ++m_current_column;
5454 return FALSE;
5455 }
5456
5457
5458 /**
5459 A helper method to add any column to the current row
5460 in its binary form.
5461
5462 Allocates memory for the data in the result set memory root.
5463 */
5464
store_column(const void * data,size_t length)5465 bool Protocol_local::store_column(const void *data, size_t length)
5466 {
5467 if (m_current_column == NULL)
5468 return TRUE; /* prepare_for_resend() failed to allocate memory. */
5469 /*
5470 alloc_root() automatically aligns memory, so we don't need to
5471 do any extra alignment if we're pointing to, say, an integer.
5472 */
5473 m_current_column->str= (char*) memdup_root(&m_rset_root,
5474 data,
5475 length + 1 /* Safety */);
5476 if (! m_current_column->str)
5477 return TRUE;
5478 m_current_column->str[length]= '\0'; /* Safety */
5479 m_current_column->length= length;
5480 ++m_current_column;
5481 return FALSE;
5482 }
5483
5484
5485 /**
5486 Store a string value in a result set column, optionally
5487 having converted it to character_set_results.
5488 */
5489
5490 bool
store_string(const char * str,size_t length,CHARSET_INFO * src_cs,CHARSET_INFO * dst_cs)5491 Protocol_local::store_string(const char *str, size_t length,
5492 CHARSET_INFO *src_cs, CHARSET_INFO *dst_cs)
5493 {
5494 /* Store with conversion */
5495 uint error_unused;
5496
5497 if (dst_cs && !my_charset_same(src_cs, dst_cs) &&
5498 src_cs != &my_charset_bin &&
5499 dst_cs != &my_charset_bin)
5500 {
5501 if (unlikely(convert->copy(str, length, src_cs, dst_cs, &error_unused)))
5502 return TRUE;
5503 str= convert->ptr();
5504 length= convert->length();
5505 }
5506 return store_column(str, length);
5507 }
5508
5509
5510 /** Store a tiny int as is (1 byte) in a result set column. */
5511
store_tiny(longlong value)5512 bool Protocol_local::store_tiny(longlong value)
5513 {
5514 char v= (char) value;
5515 return store_column(&v, 1);
5516 }
5517
5518
5519 /** Store a short as is (2 bytes, host order) in a result set column. */
5520
store_short(longlong value)5521 bool Protocol_local::store_short(longlong value)
5522 {
5523 int16 v= (int16) value;
5524 return store_column(&v, 2);
5525 }
5526
5527
5528 /** Store a "long" as is (4 bytes, host order) in a result set column. */
5529
store_long(longlong value)5530 bool Protocol_local::store_long(longlong value)
5531 {
5532 int32 v= (int32) value;
5533 return store_column(&v, 4);
5534 }
5535
5536
5537 /** Store a "longlong" as is (8 bytes, host order) in a result set column. */
5538
store_longlong(longlong value,bool unsigned_flag)5539 bool Protocol_local::store_longlong(longlong value, bool unsigned_flag)
5540 {
5541 int64 v= (int64) value;
5542 return store_column(&v, 8);
5543 }
5544
5545
5546 /** Store a decimal in string format in a result set column */
5547
store_decimal(const my_decimal * value)5548 bool Protocol_local::store_decimal(const my_decimal *value)
5549 {
5550 DBUG_ASSERT(0); // This method is not used yet
5551 StringBuffer<DECIMAL_MAX_STR_LENGTH> str;
5552 return value->to_string(&str) ? store_column(str.ptr(), str.length()) : true;
5553 }
5554
5555
5556 /** Convert to cs_results and store a string. */
5557
store(const char * str,size_t length,CHARSET_INFO * src_cs)5558 bool Protocol_local::store(const char *str, size_t length,
5559 CHARSET_INFO *src_cs)
5560 {
5561 CHARSET_INFO *dst_cs;
5562
5563 dst_cs= m_connection->m_thd->variables.character_set_results;
5564 return store_string(str, length, src_cs, dst_cs);
5565 }
5566
5567
5568 /** Store a string. */
5569
store(const char * str,size_t length,CHARSET_INFO * src_cs,CHARSET_INFO * dst_cs)5570 bool Protocol_local::store(const char *str, size_t length,
5571 CHARSET_INFO *src_cs, CHARSET_INFO *dst_cs)
5572 {
5573 return store_string(str, length, src_cs, dst_cs);
5574 }
5575
5576
5577 /* Store MYSQL_TIME (in binary format) */
5578
store(MYSQL_TIME * time,int decimals)5579 bool Protocol_local::store(MYSQL_TIME *time, int decimals)
5580 {
5581 if (decimals != AUTO_SEC_PART_DIGITS)
5582 my_datetime_trunc(time, decimals);
5583 return store_column(time, sizeof(MYSQL_TIME));
5584 }
5585
5586
5587 /** Store MYSQL_TIME (in binary format) */
5588
store_date(MYSQL_TIME * time)5589 bool Protocol_local::store_date(MYSQL_TIME *time)
5590 {
5591 return store_column(time, sizeof(MYSQL_TIME));
5592 }
5593
5594
5595 /** Store MYSQL_TIME (in binary format) */
5596
store_time(MYSQL_TIME * time,int decimals)5597 bool Protocol_local::store_time(MYSQL_TIME *time, int decimals)
5598 {
5599 if (decimals != AUTO_SEC_PART_DIGITS)
5600 my_time_trunc(time, decimals);
5601 return store_column(time, sizeof(MYSQL_TIME));
5602 }
5603
5604
5605 /* Store a floating point number, as is. */
5606
store(float value,uint32 decimals,String * buffer)5607 bool Protocol_local::store(float value, uint32 decimals, String *buffer)
5608 {
5609 return store_column(&value, sizeof(float));
5610 }
5611
5612
5613 /* Store a double precision number, as is. */
5614
store(double value,uint32 decimals,String * buffer)5615 bool Protocol_local::store(double value, uint32 decimals, String *buffer)
5616 {
5617 return store_column(&value, sizeof (double));
5618 }
5619
5620
5621 /* Store a Field. */
5622
store(Field * field)5623 bool Protocol_local::store(Field *field)
5624 {
5625 if (field->is_null())
5626 return store_null();
5627 return field->send_binary(this);
5628 }
5629
5630
5631 /** Called to start a new result set. */
5632
send_result_set_metadata(List<Item> * columns,uint)5633 bool Protocol_local::send_result_set_metadata(List<Item> *columns, uint)
5634 {
5635 DBUG_ASSERT(m_rset == 0 && !alloc_root_inited(&m_rset_root));
5636
5637 init_sql_alloc(&m_rset_root, "send_result_set_metadata",
5638 MEM_ROOT_BLOCK_SIZE, 0, MYF(MY_THREAD_SPECIFIC));
5639
5640 if (! (m_rset= new (&m_rset_root) List<Ed_row>))
5641 return TRUE;
5642
5643 m_column_count= columns->elements;
5644
5645 return FALSE;
5646 }
5647
5648
5649 /**
5650 Normally this is a separate result set with OUT parameters
5651 of stored procedures. Currently unsupported for the local
5652 version.
5653 */
5654
send_out_parameters(List<Item_param> * sp_params)5655 bool Protocol_local::send_out_parameters(List<Item_param> *sp_params)
5656 {
5657 return FALSE;
5658 }
5659
5660
5661 /** Called for statements that don't have a result set, at statement end. */
5662
5663 bool
send_ok(uint server_status,uint statement_warn_count,ulonglong affected_rows,ulonglong last_insert_id,const char * message,bool skip_flush)5664 Protocol_local::send_ok(uint server_status, uint statement_warn_count,
5665 ulonglong affected_rows, ulonglong last_insert_id,
5666 const char *message, bool skip_flush)
5667 {
5668 /*
5669 Just make sure nothing is sent to the client, we have grabbed
5670 the status information in the connection diagnostics area.
5671 */
5672 return FALSE;
5673 }
5674
5675
5676 /**
5677 Called at the end of a result set. Append a complete
5678 result set to the list in Ed_connection.
5679
5680 Don't send anything to the client, but instead finish
5681 building of the result set at hand.
5682 */
5683
send_eof(uint server_status,uint statement_warn_count)5684 bool Protocol_local::send_eof(uint server_status, uint statement_warn_count)
5685 {
5686 Ed_result_set *ed_result_set;
5687
5688 DBUG_ASSERT(m_rset);
5689
5690 opt_add_row_to_rset();
5691 m_current_row= 0;
5692
5693 ed_result_set= new (&m_rset_root) Ed_result_set(m_rset, m_column_count,
5694 &m_rset_root);
5695
5696 m_rset= NULL;
5697
5698 if (! ed_result_set)
5699 return TRUE;
5700
5701 /* In case of successful allocation memory ownership was transferred. */
5702 DBUG_ASSERT(!alloc_root_inited(&m_rset_root));
5703
5704 /*
5705 Link the created Ed_result_set instance into the list of connection
5706 result sets. Never fails.
5707 */
5708 m_connection->add_result_set(ed_result_set);
5709 return FALSE;
5710 }
5711
5712
5713 /** Called to send an error to the client at the end of a statement. */
5714
5715 bool
send_error(uint sql_errno,const char * err_msg,const char *)5716 Protocol_local::send_error(uint sql_errno, const char *err_msg, const char*)
5717 {
5718 /*
5719 Just make sure that nothing is sent to the client (default
5720 implementation).
5721 */
5722 return FALSE;
5723 }
5724
5725
5726 #ifdef EMBEDDED_LIBRARY
remove_last_row()5727 void Protocol_local::remove_last_row()
5728 { }
5729 #endif
5730