1 /* Copyright (c) 2002, 2010, 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 as published by 5 the Free Software Foundation; version 2 of the License. 6 7 This program is distributed in the hope that it will be useful, 8 but WITHOUT ANY WARRANTY; without even the implied warranty of 9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 GNU General Public License for more details. 11 12 You should have received a copy of the GNU General Public License 13 along with this program; if not, write to the Free Software 14 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ 15 16 #include "mariadb.h" 17 #include "sql_priv.h" 18 #include "unireg.h" 19 #ifdef USE_PRAGMA_IMPLEMENTATION 20 #pragma implementation 21 #endif 22 23 #include "mysql.h" 24 #include "sp_head.h" 25 #include "sql_cursor.h" 26 #include "sp_rcontext.h" 27 #include "sp_pcontext.h" 28 #include "sql_select.h" // create_virtual_tmp_table 29 #include "sql_base.h" // open_tables_only_view_structure 30 #include "sql_acl.h" // SELECT_ACL 31 #include "sql_parse.h" // check_table_access 32 33 34 Sp_rcontext_handler_local sp_rcontext_handler_local; 35 Sp_rcontext_handler_package_body sp_rcontext_handler_package_body; 36 37 sp_rcontext *Sp_rcontext_handler_local::get_rcontext(sp_rcontext *ctx) const 38 { 39 return ctx; 40 } 41 42 sp_rcontext *Sp_rcontext_handler_package_body::get_rcontext(sp_rcontext *ctx) const 43 { 44 return ctx->m_sp->m_parent->m_rcontext; 45 } 46 47 const LEX_CSTRING *Sp_rcontext_handler_local::get_name_prefix() const 48 { 49 return &empty_clex_str; 50 } 51 52 const LEX_CSTRING *Sp_rcontext_handler_package_body::get_name_prefix() const 53 { 54 static const LEX_CSTRING sp_package_body_variable_prefix_clex_str= 55 {STRING_WITH_LEN("PACKAGE_BODY.")}; 56 return &sp_package_body_variable_prefix_clex_str; 57 } 58 59 60 /////////////////////////////////////////////////////////////////////////// 61 // sp_rcontext implementation. 62 /////////////////////////////////////////////////////////////////////////// 63 64 65 sp_rcontext::sp_rcontext(const sp_head *owner, 66 const sp_pcontext *root_parsing_ctx, 67 Field *return_value_fld, 68 bool in_sub_stmt) 69 :end_partial_result_set(false), 70 pause_state(false), quit_func(false), instr_ptr(0), 71 m_sp(owner), 72 m_root_parsing_ctx(root_parsing_ctx), 73 m_var_table(NULL), 74 m_return_value_fld(return_value_fld), 75 m_return_value_set(false), 76 m_in_sub_stmt(in_sub_stmt), 77 m_ccount(0) 78 { 79 } 80 81 82 sp_rcontext::~sp_rcontext() 83 { 84 delete m_var_table; 85 // Leave m_handlers, m_handler_call_stack, m_var_items, m_cstack 86 // and m_case_expr_holders untouched. 87 // They are allocated in mem roots and will be freed accordingly. 88 } 89 90 91 sp_rcontext *sp_rcontext::create(THD *thd, 92 const sp_head *owner, 93 const sp_pcontext *root_parsing_ctx, 94 Field *return_value_fld, 95 Row_definition_list &field_def_lst) 96 { 97 SELECT_LEX *save_current_select; 98 sp_rcontext *ctx= new (thd->mem_root) sp_rcontext(owner, 99 root_parsing_ctx, 100 return_value_fld, 101 thd->in_sub_stmt); 102 if (!ctx) 103 return NULL; 104 105 /* Reset current_select as it's checked in Item_ident::Item_ident */ 106 save_current_select= thd->lex->current_select; 107 thd->lex->current_select= 0; 108 109 if (ctx->alloc_arrays(thd) || 110 ctx->init_var_table(thd, field_def_lst) || 111 ctx->init_var_items(thd, field_def_lst)) 112 { 113 delete ctx; 114 ctx= 0; 115 } 116 117 thd->lex->current_select= save_current_select; 118 return ctx; 119 } 120 121 122 bool Row_definition_list:: 123 adjust_formal_params_to_actual_params(THD *thd, List<Item> *args) 124 { 125 List_iterator<Spvar_definition> it(*this); 126 List_iterator<Item> it_args(*args); 127 DBUG_ASSERT(elements >= args->elements ); 128 Spvar_definition *def; 129 Item *arg; 130 while ((def= it++) && (arg= it_args++)) 131 { 132 if (def->type_handler()->adjust_spparam_type(def, arg)) 133 return true; 134 } 135 return false; 136 } 137 138 139 bool Row_definition_list:: 140 adjust_formal_params_to_actual_params(THD *thd, 141 Item **args, uint arg_count) 142 { 143 List_iterator<Spvar_definition> it(*this); 144 DBUG_ASSERT(elements >= arg_count ); 145 Spvar_definition *def; 146 for (uint i= 0; (def= it++) && (i < arg_count) ; i++) 147 { 148 if (def->type_handler()->adjust_spparam_type(def, args[i])) 149 return true; 150 } 151 return false; 152 } 153 154 155 bool sp_rcontext::alloc_arrays(THD *thd) 156 { 157 { 158 size_t n= m_root_parsing_ctx->max_cursor_index(); 159 m_cstack.reset( 160 static_cast<sp_cursor **> ( 161 thd->alloc(n * sizeof (sp_cursor*))), 162 n); 163 } 164 165 { 166 size_t n= m_root_parsing_ctx->get_num_case_exprs(); 167 m_case_expr_holders.reset( 168 static_cast<Item_cache **> ( 169 thd->calloc(n * sizeof (Item_cache*))), 170 n); 171 } 172 173 return !m_cstack.array() || !m_case_expr_holders.array(); 174 } 175 176 177 bool sp_rcontext::init_var_table(THD *thd, 178 List<Spvar_definition> &field_def_lst) 179 { 180 if (!m_root_parsing_ctx->max_var_index()) 181 return false; 182 183 DBUG_ASSERT(field_def_lst.elements == m_root_parsing_ctx->max_var_index()); 184 185 if (!(m_var_table= create_virtual_tmp_table(thd, field_def_lst))) 186 return true; 187 188 return false; 189 } 190 191 192 /** 193 Check if we have access to use a column as a %TYPE reference. 194 @return false - OK 195 @return true - access denied 196 */ 197 static inline bool 198 check_column_grant_for_type_ref(THD *thd, TABLE_LIST *table_list, 199 const char *str, size_t length, 200 Field *fld) 201 { 202 #ifndef NO_EMBEDDED_ACCESS_CHECKS 203 table_list->table->grant.want_privilege= SELECT_ACL; 204 return check_column_grant_in_table_ref(thd, table_list, str, length, fld); 205 #else 206 return false; 207 #endif 208 } 209 210 211 /** 212 This method implementation is very close to fill_schema_table_by_open(). 213 */ 214 bool Qualified_column_ident::resolve_type_ref(THD *thd, Column_definition *def) 215 { 216 Open_tables_backup open_tables_state_backup; 217 thd->reset_n_backup_open_tables_state(&open_tables_state_backup); 218 219 TABLE_LIST *table_list; 220 Field *src; 221 LEX *save_lex= thd->lex; 222 bool rc= true; 223 224 sp_lex_local lex(thd, thd->lex); 225 thd->lex= &lex; 226 227 lex.context_analysis_only= CONTEXT_ANALYSIS_ONLY_VIEW; 228 // Make %TYPE variables see temporary tables that shadow permanent tables 229 thd->temporary_tables= open_tables_state_backup.temporary_tables; 230 231 if ((table_list= lex.select_lex.add_table_to_list(thd, this, NULL, 0, 232 TL_READ_NO_INSERT, 233 MDL_SHARED_READ)) && 234 !check_table_access(thd, SELECT_ACL, table_list, TRUE, UINT_MAX, FALSE) && 235 !open_tables_only_view_structure(thd, table_list, 236 thd->mdl_context.has_locks())) 237 { 238 if (likely((src= lex.query_tables->table->find_field_by_name(&m_column)))) 239 { 240 if (!(rc= check_column_grant_for_type_ref(thd, table_list, 241 m_column.str, 242 m_column.length, src))) 243 { 244 *def= Column_definition(thd, src, NULL/*No defaults,no constraints*/); 245 def->flags&= (uint) ~NOT_NULL_FLAG; 246 rc= def->sp_prepare_create_field(thd, thd->mem_root); 247 } 248 } 249 else 250 my_error(ER_BAD_FIELD_ERROR, MYF(0), m_column.str, table.str); 251 } 252 253 lex.unit.cleanup(); 254 thd->temporary_tables= NULL; // Avoid closing temporary tables 255 close_thread_tables(thd); 256 thd->lex= save_lex; 257 thd->restore_backup_open_tables_state(&open_tables_state_backup); 258 return rc; 259 } 260 261 262 /** 263 This method resolves the structure of a variable declared as: 264 rec t1%ROWTYPE; 265 It opens the table "t1" and copies its structure to %ROWTYPE variable. 266 */ 267 bool Table_ident::resolve_table_rowtype_ref(THD *thd, 268 Row_definition_list &defs) 269 { 270 Open_tables_backup open_tables_state_backup; 271 thd->reset_n_backup_open_tables_state(&open_tables_state_backup); 272 273 TABLE_LIST *table_list; 274 LEX *save_lex= thd->lex; 275 bool rc= true; 276 277 /* 278 Create a temporary LEX on stack and switch to it. 279 In case of VIEW, open_tables_only_view_structure() will open more 280 tables/views recursively. We want to avoid them to stick to the current LEX. 281 */ 282 sp_lex_local lex(thd, thd->lex); 283 thd->lex= &lex; 284 285 lex.context_analysis_only= CONTEXT_ANALYSIS_ONLY_VIEW; 286 // Make %ROWTYPE variables see temporary tables that shadow permanent tables 287 thd->temporary_tables= open_tables_state_backup.temporary_tables; 288 289 if ((table_list= lex.select_lex.add_table_to_list(thd, this, NULL, 0, 290 TL_READ_NO_INSERT, 291 MDL_SHARED_READ)) && 292 !check_table_access(thd, SELECT_ACL, table_list, TRUE, UINT_MAX, FALSE) && 293 !open_tables_only_view_structure(thd, table_list, 294 thd->mdl_context.has_locks())) 295 { 296 for (Field **src= lex.query_tables->table->field; *src; src++) 297 { 298 /* 299 Make field names on the THD memory root, 300 as the table will be closed and freed soon, 301 in the end of this method. 302 */ 303 LEX_CSTRING tmp= src[0]->field_name; 304 Spvar_definition *def; 305 if ((rc= check_column_grant_for_type_ref(thd, table_list, 306 tmp.str, tmp.length,src[0])) || 307 (rc= !(src[0]->field_name.str= thd->strmake(tmp.str, tmp.length))) || 308 (rc= !(def= new (thd->mem_root) Spvar_definition(thd, *src)))) 309 break; 310 src[0]->field_name.str= tmp.str; // Restore field name, just in case. 311 def->flags&= (uint) ~NOT_NULL_FLAG; 312 if ((rc= def->sp_prepare_create_field(thd, thd->mem_root))) 313 break; 314 defs.push_back(def, thd->mem_root); 315 } 316 } 317 318 lex.unit.cleanup(); 319 thd->temporary_tables= NULL; // Avoid closing temporary tables 320 close_thread_tables(thd); 321 thd->lex= save_lex; 322 thd->restore_backup_open_tables_state(&open_tables_state_backup); 323 return rc; 324 } 325 326 327 bool Row_definition_list::resolve_type_refs(THD *thd) 328 { 329 List_iterator<Spvar_definition> it(*this); 330 Spvar_definition *def; 331 while ((def= it++)) 332 { 333 if (def->is_column_type_ref() && 334 def->column_type_ref()->resolve_type_ref(thd, def)) 335 return true; 336 } 337 return false; 338 }; 339 340 341 bool sp_rcontext::init_var_items(THD *thd, 342 List<Spvar_definition> &field_def_lst) 343 { 344 uint num_vars= m_root_parsing_ctx->max_var_index(); 345 346 m_var_items.reset( 347 static_cast<Item_field **> ( 348 thd->alloc(num_vars * sizeof (Item *))), 349 num_vars); 350 351 if (!m_var_items.array()) 352 return true; 353 354 DBUG_ASSERT(field_def_lst.elements == num_vars); 355 List_iterator<Spvar_definition> it(field_def_lst); 356 Spvar_definition *def= it++; 357 358 for (uint idx= 0; idx < num_vars; ++idx, def= it++) 359 { 360 Field *field= m_var_table->field[idx]; 361 if (def->is_table_rowtype_ref()) 362 { 363 Row_definition_list defs; 364 Item_field_row *item= new (thd->mem_root) Item_field_row(thd, field); 365 if (!(m_var_items[idx]= item) || 366 def->table_rowtype_ref()->resolve_table_rowtype_ref(thd, defs) || 367 item->row_create_items(thd, &defs)) 368 return true; 369 } 370 else if (def->is_cursor_rowtype_ref()) 371 { 372 Row_definition_list defs; 373 Item_field_row *item= new (thd->mem_root) Item_field_row(thd, field); 374 if (!(m_var_items[idx]= item)) 375 return true; 376 } 377 else if (def->is_row()) 378 { 379 Item_field_row *item= new (thd->mem_root) Item_field_row(thd, field); 380 if (!(m_var_items[idx]= item) || 381 item->row_create_items(thd, def->row_field_definitions())) 382 return true; 383 } 384 else 385 { 386 if (!(m_var_items[idx]= new (thd->mem_root) Item_field(thd, field))) 387 return true; 388 } 389 } 390 return false; 391 } 392 393 394 bool Item_field_row::row_create_items(THD *thd, List<Spvar_definition> *list) 395 { 396 DBUG_ASSERT(list); 397 DBUG_ASSERT(field); 398 Virtual_tmp_table **ptable= field->virtual_tmp_table_addr(); 399 DBUG_ASSERT(ptable); 400 if (!(ptable[0]= create_virtual_tmp_table(thd, *list))) 401 return true; 402 403 if (alloc_arguments(thd, list->elements)) 404 return true; 405 406 List_iterator<Spvar_definition> it(*list); 407 Spvar_definition *def; 408 for (arg_count= 0; (def= it++); arg_count++) 409 { 410 if (!(args[arg_count]= new (thd->mem_root) 411 Item_field(thd, ptable[0]->field[arg_count]))) 412 return true; 413 } 414 return false; 415 } 416 417 418 bool sp_rcontext::set_return_value(THD *thd, Item **return_value_item) 419 { 420 DBUG_ASSERT(m_return_value_fld); 421 422 m_return_value_set = true; 423 424 return thd->sp_eval_expr(m_return_value_fld, return_value_item); 425 } 426 427 428 void sp_rcontext::push_cursor(sp_cursor *c) 429 { 430 m_cstack[m_ccount++]= c; 431 } 432 433 434 void sp_rcontext::pop_cursor(THD *thd) 435 { 436 DBUG_ASSERT(m_ccount > 0); 437 if (m_cstack[m_ccount - 1]->is_open()) 438 m_cstack[m_ccount - 1]->close(thd); 439 m_ccount--; 440 } 441 442 443 void sp_rcontext::pop_cursors(THD *thd, size_t count) 444 { 445 DBUG_ASSERT(m_ccount >= count); 446 while (count--) 447 pop_cursor(thd); 448 } 449 450 451 bool sp_rcontext::push_handler(sp_instr_hpush_jump *entry) 452 { 453 return m_handlers.append(entry); 454 } 455 456 457 void sp_rcontext::pop_handlers(size_t count) 458 { 459 DBUG_ASSERT(m_handlers.elements() >= count); 460 461 for (size_t i= 0; i < count; ++i) 462 m_handlers.pop(); 463 } 464 465 466 bool sp_rcontext::handle_sql_condition(THD *thd, 467 uint *ip, 468 const sp_instr *cur_spi) 469 { 470 DBUG_ENTER("sp_rcontext::handle_sql_condition"); 471 472 /* 473 If this is a fatal sub-statement error, and this runtime 474 context corresponds to a sub-statement, no CONTINUE/EXIT 475 handlers from this context are applicable: try to locate one 476 in the outer scope. 477 */ 478 if (unlikely(thd->is_fatal_sub_stmt_error) && m_in_sub_stmt) 479 DBUG_RETURN(false); 480 481 Diagnostics_area *da= thd->get_stmt_da(); 482 const sp_handler *found_handler= NULL; 483 const Sql_condition *found_condition= NULL; 484 485 if (unlikely(thd->is_error())) 486 { 487 found_handler= 488 cur_spi->m_ctx->find_handler(da->get_error_condition_identity()); 489 490 if (found_handler) 491 found_condition= da->get_error_condition(); 492 493 /* 494 Found condition can be NULL if the diagnostics area was full 495 when the error was raised. It can also be NULL if 496 Diagnostics_area::set_error_status(uint sql_error) was used. 497 In these cases, make a temporary Sql_condition here so the 498 error can be handled. 499 */ 500 if (!found_condition) 501 { 502 found_condition= 503 new (callers_arena->mem_root) Sql_condition(callers_arena->mem_root, 504 da->get_error_condition_identity(), 505 da->message()); 506 } 507 } 508 else if (da->current_statement_warn_count()) 509 { 510 Diagnostics_area::Sql_condition_iterator it= da->sql_conditions(); 511 const Sql_condition *c; 512 513 // Here we need to find the last warning/note from the stack. 514 // In MySQL most substantial warning is the last one. 515 // (We could have used a reverse iterator here if one existed) 516 517 while ((c= it++)) 518 { 519 if (c->get_level() == Sql_condition::WARN_LEVEL_WARN || 520 c->get_level() == Sql_condition::WARN_LEVEL_NOTE) 521 { 522 const sp_handler *handler= cur_spi->m_ctx->find_handler(*c); 523 if (handler) 524 { 525 found_handler= handler; 526 found_condition= c; 527 } 528 } 529 } 530 } 531 532 if (!found_handler) 533 DBUG_RETURN(false); 534 535 // At this point, we know that: 536 // - there is a pending SQL-condition (error or warning); 537 // - there is an SQL-handler for it. 538 539 DBUG_ASSERT(found_condition); 540 541 sp_instr_hpush_jump *handler_entry= NULL; 542 for (size_t i= 0; i < m_handlers.elements(); ++i) 543 { 544 sp_instr_hpush_jump *h= m_handlers.at(i); 545 546 if (h->get_handler() == found_handler) 547 { 548 handler_entry= h; 549 break; 550 } 551 } 552 553 /* 554 handler_entry usually should not be NULL here, as that indicates 555 that the parser context thinks a HANDLER should be activated, 556 but the runtime context cannot find it. 557 558 However, this can happen (and this is in line with the Standard) 559 if SQL-condition has been raised before DECLARE HANDLER instruction 560 is processed. 561 562 For example: 563 CREATE PROCEDURE p() 564 BEGIN 565 DECLARE v INT DEFAULT 'get'; -- raises SQL-warning here 566 DECLARE EXIT HANDLER ... -- this handler does not catch the warning 567 END 568 */ 569 if (!handler_entry) 570 DBUG_RETURN(false); 571 572 // Mark active conditions so that they can be deleted when the handler exits. 573 da->mark_sql_conditions_for_removal(); 574 575 uint continue_ip= handler_entry->get_handler()->type == sp_handler::CONTINUE ? 576 cur_spi->get_cont_dest() : 0; 577 578 /* End aborted result set. */ 579 if (end_partial_result_set) 580 thd->protocol->end_partial_result_set(thd); 581 582 /* Reset error state. */ 583 thd->clear_error(); 584 thd->reset_killed(); // Some errors set thd->killed, (e.g. "bad data"). 585 586 /* Add a frame to handler-call-stack. */ 587 Sql_condition_info *cond_info= 588 new (callers_arena->mem_root) Sql_condition_info(found_condition, 589 callers_arena); 590 Handler_call_frame *frame= 591 new (callers_arena->mem_root) Handler_call_frame(cond_info, continue_ip); 592 m_handler_call_stack.append(frame); 593 594 *ip= handler_entry->m_ip + 1; 595 596 DBUG_RETURN(true); 597 } 598 599 600 uint sp_rcontext::exit_handler(Diagnostics_area *da) 601 { 602 DBUG_ENTER("sp_rcontext::exit_handler"); 603 DBUG_ASSERT(m_handler_call_stack.elements() > 0); 604 605 Handler_call_frame *f= m_handler_call_stack.pop(); 606 607 /* 608 Remove the SQL conditions that were present in DA when the 609 handler was activated. 610 */ 611 da->remove_marked_sql_conditions(); 612 613 uint continue_ip= f->continue_ip; 614 615 DBUG_RETURN(continue_ip); 616 } 617 618 619 int sp_rcontext::set_variable(THD *thd, uint idx, Item **value) 620 { 621 DBUG_ENTER("sp_rcontext::set_variable"); 622 DBUG_ASSERT(value); 623 DBUG_RETURN(thd->sp_eval_expr(m_var_table->field[idx], value)); 624 } 625 626 627 int sp_rcontext::set_variable_row_field(THD *thd, uint var_idx, uint field_idx, 628 Item **value) 629 { 630 DBUG_ENTER("sp_rcontext::set_variable_row_field"); 631 DBUG_ASSERT(value); 632 Virtual_tmp_table *vtable= virtual_tmp_table_for_row(var_idx); 633 DBUG_RETURN(thd->sp_eval_expr(vtable->field[field_idx], value)); 634 } 635 636 637 int sp_rcontext::set_variable_row_field_by_name(THD *thd, uint var_idx, 638 const LEX_CSTRING &field_name, 639 Item **value) 640 { 641 DBUG_ENTER("sp_rcontext::set_variable_row_field_by_name"); 642 uint field_idx; 643 if (find_row_field_by_name_or_error(&field_idx, var_idx, field_name)) 644 DBUG_RETURN(1); 645 DBUG_RETURN(set_variable_row_field(thd, var_idx, field_idx, value)); 646 } 647 648 649 int sp_rcontext::set_variable_row(THD *thd, uint var_idx, List<Item> &items) 650 { 651 DBUG_ENTER("sp_rcontext::set_variable_row"); 652 DBUG_ASSERT(get_variable(var_idx)->cols() == items.elements); 653 Virtual_tmp_table *vtable= virtual_tmp_table_for_row(var_idx); 654 Sp_eval_expr_state state(thd); 655 DBUG_RETURN(vtable->sp_set_all_fields_from_item_list(thd, items)); 656 } 657 658 659 Virtual_tmp_table *sp_rcontext::virtual_tmp_table_for_row(uint var_idx) 660 { 661 DBUG_ASSERT(get_variable(var_idx)->type() == Item::FIELD_ITEM); 662 DBUG_ASSERT(get_variable(var_idx)->cmp_type() == ROW_RESULT); 663 Field *field= m_var_table->field[var_idx]; 664 Virtual_tmp_table **ptable= field->virtual_tmp_table_addr(); 665 DBUG_ASSERT(ptable); 666 DBUG_ASSERT(ptable[0]); 667 return ptable[0]; 668 } 669 670 671 bool sp_rcontext::find_row_field_by_name_or_error(uint *field_idx, 672 uint var_idx, 673 const LEX_CSTRING &field_name) 674 { 675 Virtual_tmp_table *vtable= virtual_tmp_table_for_row(var_idx); 676 Field *row= m_var_table->field[var_idx]; 677 return vtable->sp_find_field_by_name_or_error(field_idx, 678 row->field_name, field_name); 679 } 680 681 682 Item_cache *sp_rcontext::create_case_expr_holder(THD *thd, 683 const Item *item) const 684 { 685 Item_cache *holder; 686 Query_arena current_arena; 687 688 thd->set_n_backup_active_arena(thd->spcont->callers_arena, ¤t_arena); 689 690 holder= item->get_cache(thd); 691 692 thd->restore_active_arena(thd->spcont->callers_arena, ¤t_arena); 693 694 return holder; 695 } 696 697 698 bool sp_rcontext::set_case_expr(THD *thd, int case_expr_id, 699 Item **case_expr_item_ptr) 700 { 701 Item *case_expr_item= thd->sp_prepare_func_item(case_expr_item_ptr); 702 if (!case_expr_item) 703 return true; 704 705 if (!m_case_expr_holders[case_expr_id] || 706 m_case_expr_holders[case_expr_id]->result_type() != 707 case_expr_item->result_type()) 708 { 709 m_case_expr_holders[case_expr_id]= 710 create_case_expr_holder(thd, case_expr_item); 711 } 712 713 m_case_expr_holders[case_expr_id]->store(case_expr_item); 714 m_case_expr_holders[case_expr_id]->cache_value(); 715 return false; 716 } 717 718 719 /////////////////////////////////////////////////////////////////////////// 720 // sp_cursor implementation. 721 /////////////////////////////////////////////////////////////////////////// 722 723 724 /* 725 Open an SP cursor 726 727 SYNOPSIS 728 open() 729 THD Thread handler 730 731 732 RETURN 733 0 in case of success, -1 otherwise 734 */ 735 736 int sp_cursor::open(THD *thd) 737 { 738 if (server_side_cursor) 739 { 740 my_message(ER_SP_CURSOR_ALREADY_OPEN, 741 ER_THD(thd, ER_SP_CURSOR_ALREADY_OPEN), 742 MYF(0)); 743 return -1; 744 } 745 if (mysql_open_cursor(thd, &result, &server_side_cursor)) 746 return -1; 747 return 0; 748 } 749 750 751 int sp_cursor::close(THD *thd) 752 { 753 if (! server_side_cursor) 754 { 755 my_message(ER_SP_CURSOR_NOT_OPEN, ER_THD(thd, ER_SP_CURSOR_NOT_OPEN), 756 MYF(0)); 757 return -1; 758 } 759 sp_cursor_statistics::reset(); 760 destroy(); 761 return 0; 762 } 763 764 765 void sp_cursor::destroy() 766 { 767 delete server_side_cursor; 768 server_side_cursor= NULL; 769 } 770 771 772 int sp_cursor::fetch(THD *thd, List<sp_variable> *vars, bool error_on_no_data) 773 { 774 if (! server_side_cursor) 775 { 776 my_message(ER_SP_CURSOR_NOT_OPEN, ER_THD(thd, ER_SP_CURSOR_NOT_OPEN), 777 MYF(0)); 778 return -1; 779 } 780 if (vars->elements != result.get_field_count() && 781 (vars->elements != 1 || 782 result.get_field_count() != 783 thd->spcont->get_variable(vars->head()->offset)->cols())) 784 { 785 my_message(ER_SP_WRONG_NO_OF_FETCH_ARGS, 786 ER_THD(thd, ER_SP_WRONG_NO_OF_FETCH_ARGS), MYF(0)); 787 return -1; 788 } 789 790 m_fetch_count++; 791 DBUG_EXECUTE_IF("bug23032_emit_warning", 792 push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 793 ER_UNKNOWN_ERROR, 794 ER_THD(thd, ER_UNKNOWN_ERROR));); 795 796 result.set_spvar_list(vars); 797 798 DBUG_ASSERT(!thd->is_error()); 799 800 /* Attempt to fetch one row */ 801 if (server_side_cursor->is_open()) 802 { 803 server_side_cursor->fetch(1); 804 if (thd->is_error()) 805 return -1; // e.g. data type conversion failed 806 } 807 808 /* 809 If the cursor was pointing after the last row, the fetch will 810 close it instead of sending any rows. 811 */ 812 if (! server_side_cursor->is_open()) 813 { 814 m_found= false; 815 if (!error_on_no_data) 816 return 0; 817 my_message(ER_SP_FETCH_NO_DATA, ER_THD(thd, ER_SP_FETCH_NO_DATA), MYF(0)); 818 return -1; 819 } 820 821 m_found= true; 822 m_row_count++; 823 return 0; 824 } 825 826 827 bool sp_cursor::export_structure(THD *thd, Row_definition_list *list) 828 { 829 return server_side_cursor->export_structure(thd, list); 830 } 831 832 /////////////////////////////////////////////////////////////////////////// 833 // sp_cursor::Select_fetch_into_spvars implementation. 834 /////////////////////////////////////////////////////////////////////////// 835 836 837 int sp_cursor::Select_fetch_into_spvars::prepare(List<Item> &fields, 838 SELECT_LEX_UNIT *u) 839 { 840 /* 841 Cache the number of columns in the result set in order to easily 842 return an error if column count does not match value count. 843 */ 844 field_count= fields.elements; 845 return select_result_interceptor::prepare(fields, u); 846 } 847 848 849 bool sp_cursor::Select_fetch_into_spvars:: 850 send_data_to_variable_list(List<sp_variable> &vars, List<Item> &items) 851 { 852 List_iterator_fast<sp_variable> spvar_iter(vars); 853 List_iterator_fast<Item> item_iter(items); 854 sp_variable *spvar; 855 Item *item; 856 857 /* Must be ensured by the caller */ 858 DBUG_ASSERT(vars.elements == items.elements); 859 860 /* 861 Assign the row fetched from a server side cursor to stored 862 procedure variables. 863 */ 864 for (; spvar= spvar_iter++, item= item_iter++; ) 865 { 866 if (thd->spcont->set_variable(thd, spvar->offset, &item)) 867 return true; 868 } 869 return false; 870 } 871 872 873 int sp_cursor::Select_fetch_into_spvars::send_data(List<Item> &items) 874 { 875 Item *item; 876 /* 877 If we have only one variable in spvar_list, and this is a ROW variable, 878 and the number of fields in the ROW variable matches the number of 879 fields in the query result, we fetch to this ROW variable. 880 881 If there is one variable, and it is a ROW variable, but its number 882 of fields does not match the number of fields in the query result, 883 we go through send_data_to_variable_list(). It will report an error 884 on attempt to assign a scalar value to a ROW variable. 885 */ 886 return spvar_list->elements == 1 && 887 (item= thd->spcont->get_variable(spvar_list->head()->offset)) && 888 item->type_handler() == &type_handler_row && 889 item->cols() == items.elements ? 890 thd->spcont->set_variable_row(thd, spvar_list->head()->offset, items) : 891 send_data_to_variable_list(*spvar_list, items); 892 } 893