1 /* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software Foundation,
21    51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
22 
23 #include "sql_priv.h"
24 #include "unireg.h"
25 #include "mysql.h"
26 #include "sp.h"                                // sp_eval_expr
27 #include "sql_cursor.h"
28 #include "sp_rcontext.h"
29 #include "sp_pcontext.h"
30 #include "sql_tmp_table.h"                     // create_virtual_tmp_table
31 #include "sp_instr.h"
32 
33 extern "C" void sql_alloc_error_handler(void);
34 
35 ///////////////////////////////////////////////////////////////////////////
36 // sp_rcontext implementation.
37 ///////////////////////////////////////////////////////////////////////////
38 
39 
sp_rcontext(const sp_pcontext * root_parsing_ctx,Field * return_value_fld,bool in_sub_stmt)40 sp_rcontext::sp_rcontext(const sp_pcontext *root_parsing_ctx,
41                          Field *return_value_fld,
42                          bool in_sub_stmt)
43   :end_partial_result_set(false),
44    m_root_parsing_ctx(root_parsing_ctx),
45    m_var_table(NULL),
46    m_return_value_fld(return_value_fld),
47    m_return_value_set(false),
48    m_in_sub_stmt(in_sub_stmt),
49    m_ccount(0)
50 {
51 }
52 
53 
~sp_rcontext()54 sp_rcontext::~sp_rcontext()
55 {
56   if (m_var_table)
57     free_blobs(m_var_table);
58 
59   while (m_activated_handlers.elements())
60     delete m_activated_handlers.pop();
61 
62   while (m_visible_handlers.elements())
63     delete m_visible_handlers.pop();
64 
65   pop_all_cursors();
66 
67   // Leave m_var_items and m_case_expr_holders untouched.
68   // They are allocated in mem roots and will be freed accordingly.
69 }
70 
71 
create(THD * thd,const sp_pcontext * root_parsing_ctx,Field * return_value_fld)72 sp_rcontext *sp_rcontext::create(THD *thd,
73                                  const sp_pcontext *root_parsing_ctx,
74                                  Field *return_value_fld)
75 {
76   sp_rcontext *ctx= new (thd->mem_root) sp_rcontext(root_parsing_ctx,
77                                                     return_value_fld,
78                                                     thd->in_sub_stmt);
79 
80   if (!ctx)
81     return NULL;
82 
83   if (ctx->alloc_arrays(thd) ||
84       ctx->init_var_table(thd) ||
85       ctx->init_var_items(thd))
86   {
87     delete ctx;
88     return NULL;
89   }
90 
91   return ctx;
92 }
93 
94 
alloc_arrays(THD * thd)95 bool sp_rcontext::alloc_arrays(THD *thd)
96 {
97   {
98     size_t n= m_root_parsing_ctx->max_cursor_index();
99     m_cstack.reset(
100       static_cast<sp_cursor **> (
101         thd->alloc(n * sizeof (sp_cursor*))),
102       n);
103   }
104 
105   {
106     size_t n= m_root_parsing_ctx->get_num_case_exprs();
107     m_case_expr_holders.reset(
108       static_cast<Item_cache **> (
109         thd->calloc(n * sizeof (Item_cache*))),
110       n);
111   }
112 
113   return !m_cstack.array() || !m_case_expr_holders.array();
114 }
115 
116 
init_var_table(THD * thd)117 bool sp_rcontext::init_var_table(THD *thd)
118 {
119   List<Create_field> field_def_lst;
120 
121   if (!m_root_parsing_ctx->max_var_index())
122     return false;
123 
124   m_root_parsing_ctx->retrieve_field_definitions(&field_def_lst);
125 
126   DBUG_ASSERT(field_def_lst.elements == m_root_parsing_ctx->max_var_index());
127 
128   if (!(m_var_table= create_virtual_tmp_table(thd, field_def_lst)))
129     return true;
130 
131   m_var_table->copy_blobs= true;
132   m_var_table->alias= "";
133 
134   return false;
135 }
136 
137 
init_var_items(THD * thd)138 bool sp_rcontext::init_var_items(THD *thd)
139 {
140   uint num_vars= m_root_parsing_ctx->max_var_index();
141 
142   m_var_items.reset(
143     static_cast<Item **> (
144       thd->alloc(num_vars * sizeof (Item *))),
145     num_vars);
146 
147   if (!m_var_items.array())
148     return true;
149 
150   for (uint idx = 0; idx < num_vars; ++idx)
151   {
152     if (!(m_var_items[idx]= new Item_field(m_var_table->field[idx])))
153       return true;
154   }
155 
156   return false;
157 }
158 
159 
set_return_value(THD * thd,Item ** return_value_item)160 bool sp_rcontext::set_return_value(THD *thd, Item **return_value_item)
161 {
162   DBUG_ASSERT(m_return_value_fld);
163 
164   m_return_value_set = true;
165 
166   return sp_eval_expr(thd, m_return_value_fld, return_value_item);
167 }
168 
169 
push_cursor(sp_instr_cpush * i)170 bool sp_rcontext::push_cursor(sp_instr_cpush *i)
171 {
172   /*
173     We should create cursors on the system heap because:
174      - they could be (and usually are) used in several instructions,
175        thus they can not be stored on an execution mem-root;
176      - a cursor can be pushed/popped many times in a loop, having these objects
177        on callers' mem-root would lead to a memory leak in every iteration.
178   */
179   sp_cursor *c= new (std::nothrow) sp_cursor(i);
180 
181   if (!c)
182   {
183     sql_alloc_error_handler();
184     return true;
185   }
186 
187   m_cstack[m_ccount++]= c;
188   return false;
189 }
190 
191 
pop_cursors(uint count)192 void sp_rcontext::pop_cursors(uint count)
193 {
194   DBUG_ASSERT(m_ccount >= count);
195 
196   while (count--)
197     delete m_cstack[--m_ccount];
198 }
199 
200 
push_handler(sp_handler * handler,uint first_ip)201 bool sp_rcontext::push_handler(sp_handler *handler, uint first_ip)
202 {
203   /*
204     We should create handler entries on the system heap because:
205       - they could be (and usually are) used in several instructions,
206         thus they can not be stored on an execution mem-root;
207       - a handler can be pushed/popped many times in a loop, having these
208         objects on callers' mem-root would lead to a memory leak in every
209         iteration.
210   */
211 
212   sp_handler_entry *he=
213     new (std::nothrow) sp_handler_entry(handler, first_ip);
214 
215   if (!he)
216   {
217     sql_alloc_error_handler();
218     return true;
219   }
220 
221   return m_visible_handlers.append(he);
222 }
223 
224 
pop_handlers(sp_pcontext * current_scope)225 void sp_rcontext::pop_handlers(sp_pcontext *current_scope)
226 {
227   for (int i= m_visible_handlers.elements() - 1; i >= 0; --i)
228   {
229     int handler_level= m_visible_handlers.at(i)->handler->scope->get_level();
230 
231     if (handler_level >= current_scope->get_level())
232       delete m_visible_handlers.pop();
233   }
234 }
235 
236 
exit_handler(sp_pcontext * target_scope)237 void sp_rcontext::exit_handler(sp_pcontext *target_scope)
238 {
239   // Pop the current handler frame.
240 
241   delete m_activated_handlers.pop();
242 
243   // Pop frames below the target scope level.
244 
245   for (int i= m_activated_handlers.elements() - 1; i >= 0; --i)
246   {
247     int handler_level= m_activated_handlers.at(i)->handler->scope->get_level();
248 
249     /*
250       Only pop until we hit the first handler with appropriate scope level.
251       Otherwise we can end up popping handlers from separate scopes.
252     */
253     if (handler_level > target_scope->get_level())
254       delete m_activated_handlers.pop();
255     else
256       break;
257   }
258 }
259 
260 
handle_sql_condition(THD * thd,uint * ip,const sp_instr * cur_spi)261 bool sp_rcontext::handle_sql_condition(THD *thd,
262                                        uint *ip,
263                                        const sp_instr *cur_spi)
264 {
265   DBUG_ENTER("sp_rcontext::handle_sql_condition");
266 
267   /*
268     If this is a fatal sub-statement error, and this runtime
269     context corresponds to a sub-statement, no CONTINUE/EXIT
270     handlers from this context are applicable: try to locate one
271     in the outer scope.
272   */
273   if (thd->is_fatal_sub_stmt_error && m_in_sub_stmt)
274     DBUG_RETURN(false);
275 
276   Diagnostics_area *da= thd->get_stmt_da();
277   const sp_handler *found_handler= NULL;
278 
279   uint condition_sql_errno= 0;
280   Sql_condition::enum_warning_level condition_level=
281                                     Sql_condition::WARN_LEVEL_NOTE;
282   const char *condition_sqlstate= NULL;
283   const char *condition_message= NULL;
284 
285   if (thd->is_error())
286   {
287     sp_pcontext *cur_pctx= cur_spi->get_parsing_ctx();
288 
289     found_handler= cur_pctx->find_handler(da->get_sqlstate(),
290                                           da->sql_errno(),
291                                           Sql_condition::WARN_LEVEL_ERROR);
292 
293     if (!found_handler)
294       DBUG_RETURN(false);
295 
296     if (da->get_error_condition())
297     {
298       const Sql_condition *c= da->get_error_condition();
299       condition_sql_errno= c->get_sql_errno();
300       condition_level= c->get_level();
301       condition_sqlstate= c->get_sqlstate();
302       condition_message= c->get_message_text();
303     }
304     else
305     {
306       /*
307         SQL condition can be NULL if the diagnostics area was full
308         when the error was raised. It can also be NULL if
309         Diagnostics_area::set_error_status(uint sql_error) was used.
310       */
311 
312       condition_sql_errno= da->sql_errno();
313       condition_level= Sql_condition::WARN_LEVEL_ERROR;
314       condition_sqlstate= da->get_sqlstate();
315       condition_message= da->message();
316     }
317   }
318   else if (da->current_statement_warn_count())
319   {
320     Diagnostics_area::Sql_condition_iterator it= da->sql_conditions();
321     const Sql_condition *c;
322 
323     // Here we need to find the last warning/note from the stack.
324     // In MySQL most substantial warning is the last one.
325     // (We could have used a reverse iterator here if one existed)
326 
327     while ((c= it++))
328     {
329       if (c->get_level() == Sql_condition::WARN_LEVEL_WARN ||
330           c->get_level() == Sql_condition::WARN_LEVEL_NOTE)
331       {
332         sp_pcontext *cur_pctx= cur_spi->get_parsing_ctx();
333 
334         const sp_handler *handler= cur_pctx->find_handler(c->get_sqlstate(),
335                                                           c->get_sql_errno(),
336                                                           c->get_level());
337         if (handler)
338         {
339           found_handler= handler;
340 
341           condition_sql_errno= c->get_sql_errno();
342           condition_level= c->get_level();
343           condition_sqlstate= c->get_sqlstate();
344           condition_message= c->get_message_text();
345         }
346       }
347     }
348   }
349 
350   if (!found_handler)
351     DBUG_RETURN(false);
352 
353   // At this point, we know that:
354   //  - there is a pending SQL-condition (error or warning);
355   //  - there is an SQL-handler for it.
356 
357   DBUG_ASSERT(condition_sql_errno != 0);
358 
359   sp_handler_entry *handler_entry= NULL;
360   for (int i= 0; i < m_visible_handlers.elements(); ++i)
361   {
362     sp_handler_entry *h= m_visible_handlers.at(i);
363 
364     if (h->handler == found_handler)
365     {
366       handler_entry= h;
367       break;
368     }
369   }
370 
371   /*
372     handler_entry usually should not be NULL here, as that indicates
373     that the parser context thinks a HANDLER should be activated,
374     but the runtime context cannot find it.
375 
376     However, this can happen (and this is in line with the Standard)
377     if SQL-condition has been raised before DECLARE HANDLER instruction
378     is processed.
379 
380     For example:
381     CREATE PROCEDURE p()
382     BEGIN
383       DECLARE v INT DEFAULT 'get'; -- raises SQL-warning here
384       DECLARE EXIT HANDLER ...     -- this handler does not catch the warning
385     END
386   */
387   if (!handler_entry)
388     DBUG_RETURN(false);
389 
390   // Mark active conditions so that they can be deleted when the handler exits.
391   da->mark_sql_conditions_for_removal();
392 
393   uint continue_ip= handler_entry->handler->type == sp_handler::CONTINUE ?
394     cur_spi->get_cont_dest() : 0;
395 
396   /* End aborted result set. */
397   if (end_partial_result_set)
398     thd->protocol->end_partial_result_set(thd);
399 
400   /* Add a frame to handler-call-stack. */
401   Handler_call_frame *frame=
402     new (std::nothrow) Handler_call_frame(found_handler,
403                                           condition_sql_errno,
404                                           condition_sqlstate,
405                                           condition_level,
406                                           condition_message,
407                                           continue_ip);
408 
409   /* Reset error state. */
410   thd->clear_error();
411   thd->killed= THD::NOT_KILLED; // Some errors set thd->killed
412                                 // (e.g. "bad data").
413 
414   if (!frame)
415   {
416     sql_alloc_error_handler();
417     DBUG_RETURN(false);
418   }
419 
420   m_activated_handlers.append(frame);
421 
422   *ip= handler_entry->first_ip;
423 
424   DBUG_RETURN(true);
425 }
426 
427 
set_variable(THD * thd,Field * field,Item ** value)428 bool sp_rcontext::set_variable(THD *thd, Field *field, Item **value)
429 {
430   if (!value)
431   {
432     field->set_null();
433     return false;
434   }
435 
436   return sp_eval_expr(thd, field, value);
437 }
438 
439 
create_case_expr_holder(THD * thd,const Item * item) const440 Item_cache *sp_rcontext::create_case_expr_holder(THD *thd,
441                                                  const Item *item) const
442 {
443   Item_cache *holder;
444   Query_arena current_arena;
445 
446   thd->set_n_backup_active_arena(thd->sp_runtime_ctx->callers_arena,
447                                  &current_arena);
448 
449   holder= Item_cache::get_cache(item);
450 
451   thd->restore_active_arena(thd->sp_runtime_ctx->callers_arena, &current_arena);
452 
453   return holder;
454 }
455 
456 
set_case_expr(THD * thd,int case_expr_id,Item ** case_expr_item_ptr)457 bool sp_rcontext::set_case_expr(THD *thd, int case_expr_id,
458                                 Item **case_expr_item_ptr)
459 {
460   Item *case_expr_item= sp_prepare_func_item(thd, case_expr_item_ptr);
461   if (!case_expr_item)
462     return true;
463 
464   if (!m_case_expr_holders[case_expr_id] ||
465       m_case_expr_holders[case_expr_id]->result_type() !=
466         case_expr_item->result_type())
467   {
468     m_case_expr_holders[case_expr_id]=
469       create_case_expr_holder(thd, case_expr_item);
470   }
471 
472   m_case_expr_holders[case_expr_id]->store(case_expr_item);
473   m_case_expr_holders[case_expr_id]->cache_value();
474   return false;
475 }
476 
477 
478 ///////////////////////////////////////////////////////////////////////////
479 // sp_cursor implementation.
480 ///////////////////////////////////////////////////////////////////////////
481 
482 
483 /**
484   Open an SP cursor
485 
486   @param thd  Thread context
487 
488   @return Error status
489 */
490 
open(THD * thd)491 bool sp_cursor::open(THD *thd)
492 {
493   if (m_server_side_cursor)
494   {
495     my_message(ER_SP_CURSOR_ALREADY_OPEN, ER(ER_SP_CURSOR_ALREADY_OPEN),
496                MYF(0));
497     return true;
498   }
499 
500   return mysql_open_cursor(thd, &m_result, &m_server_side_cursor);
501 }
502 
503 
close(THD * thd)504 bool sp_cursor::close(THD *thd)
505 {
506   if (! m_server_side_cursor)
507   {
508     my_message(ER_SP_CURSOR_NOT_OPEN, ER(ER_SP_CURSOR_NOT_OPEN), MYF(0));
509     return true;
510   }
511 
512   destroy();
513   return false;
514 }
515 
516 
destroy()517 void sp_cursor::destroy()
518 {
519   delete m_server_side_cursor;
520   m_server_side_cursor= NULL;
521 }
522 
523 
fetch(THD * thd,List<sp_variable> * vars)524 bool sp_cursor::fetch(THD *thd, List<sp_variable> *vars)
525 {
526   if (! m_server_side_cursor)
527   {
528     my_message(ER_SP_CURSOR_NOT_OPEN, ER(ER_SP_CURSOR_NOT_OPEN), MYF(0));
529     return true;
530   }
531 
532   if (vars->elements != m_result.get_field_count())
533   {
534     my_message(ER_SP_WRONG_NO_OF_FETCH_ARGS,
535                ER(ER_SP_WRONG_NO_OF_FETCH_ARGS), MYF(0));
536     return true;
537   }
538 
539   DBUG_EXECUTE_IF("bug23032_emit_warning",
540                   push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
541                                ER_UNKNOWN_ERROR,
542                                ER(ER_UNKNOWN_ERROR)););
543 
544   m_result.set_spvar_list(vars);
545 
546   /* Attempt to fetch one row */
547   if (m_server_side_cursor->is_open())
548     m_server_side_cursor->fetch(1);
549 
550   /*
551     If the cursor was pointing after the last row, the fetch will
552     close it instead of sending any rows.
553   */
554   if (! m_server_side_cursor->is_open())
555   {
556     my_message(ER_SP_FETCH_NO_DATA, ER(ER_SP_FETCH_NO_DATA), MYF(0));
557     return true;
558   }
559 
560   return false;
561 }
562 
563 
564 ///////////////////////////////////////////////////////////////////////////
565 // sp_cursor::Select_fetch_into_spvars implementation.
566 ///////////////////////////////////////////////////////////////////////////
567 
568 
prepare(List<Item> & fields,SELECT_LEX_UNIT * u)569 int sp_cursor::Select_fetch_into_spvars::prepare(List<Item> &fields,
570                                                  SELECT_LEX_UNIT *u)
571 {
572   /*
573     Cache the number of columns in the result set in order to easily
574     return an error if column count does not match value count.
575   */
576   field_count= fields.elements;
577   return select_result_interceptor::prepare(fields, u);
578 }
579 
580 
send_data(List<Item> & items)581 bool sp_cursor::Select_fetch_into_spvars::send_data(List<Item> &items)
582 {
583   List_iterator_fast<sp_variable> spvar_iter(*spvar_list);
584   List_iterator_fast<Item> item_iter(items);
585   sp_variable *spvar;
586   Item *item;
587 
588   /* Must be ensured by the caller */
589   DBUG_ASSERT(spvar_list->elements == items.elements);
590 
591   /*
592     Assign the row fetched from a server side cursor to stored
593     procedure variables.
594   */
595   for (; spvar= spvar_iter++, item= item_iter++; )
596   {
597     if (thd->sp_runtime_ctx->set_variable(thd, spvar->offset, &item))
598       return true;
599   }
600   return false;
601 }
602