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> &params,
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> &params,
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(&copy));
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(&copy);
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