The world's most popular open source database
#include "mysql_priv.h"#include "sql_select.h"#include <assert.h>Include dependency graph for sql_handler.cc:

Go to the source code of this file.
Defines | |
| #define | HANDLER_TABLES_HASH_SIZE 120 |
| #define | HANDLER_TABLES_HACK(thd) |
Functions | |
| static int | mysql_ha_flush_table (THD *thd, TABLE **table_ptr, uint mode_flags) |
| static char * | mysql_ha_hash_get_key (TABLE_LIST *tables, uint *key_len_p, my_bool first __attribute__((unused))) |
| static void | mysql_ha_hash_free (TABLE_LIST *tables) |
| bool | mysql_ha_open (THD *thd, TABLE_LIST *tables, bool reopen) |
| bool | mysql_ha_close (THD *thd, TABLE_LIST *tables) |
| bool | mysql_ha_read (THD *thd, TABLE_LIST *tables, enum enum_ha_read_modes mode, char *keyname, List< Item > *key_expr, enum ha_rkey_function ha_rkey_mode, Item *cond, ha_rows select_limit_cnt, ha_rows offset_limit_cnt) |
| int | mysql_ha_flush (THD *thd, TABLE_LIST *tables, uint mode_flags, bool is_locked) |
Variables | |
| static enum enum_ha_read_modes | rkey_to_rnext [] |
| #define HANDLER_TABLES_HACK | ( | thd | ) |
Value:
{ \
TABLE *tmp=thd->open_tables; \
thd->open_tables=thd->handler_tables; \
thd->handler_tables=tmp; }
Definition at line 69 of file sql_handler.cc.
Referenced by mysql_ha_open(), and mysql_ha_read().
| #define HANDLER_TABLES_HASH_SIZE 120 |
| bool mysql_ha_close | ( | THD * | thd, | |
| TABLE_LIST * | tables | |||
| ) |
Definition at line 265 of file sql_handler.cc.
References st_table_list::alias, broadcast_refresh(), close_thread_table(), st_table_list::db, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, ER_UNKNOWN_TABLE, FALSE, hash_delete(), hash_search(), LOCK_open, my_error(), MYF, st_table::next, pthread_mutex_lock, pthread_mutex_unlock, send_ok(), strlen(), st_table_list::table, st_table_list::table_name, TRUE, and VOID.
Referenced by mysql_execute_command(), and mysql_ha_open().
00266 { 00267 TABLE_LIST *hash_tables; 00268 TABLE **table_ptr; 00269 DBUG_ENTER("mysql_ha_close"); 00270 DBUG_PRINT("enter",("'%s'.'%s' as '%s'", 00271 tables->db, tables->table_name, tables->alias)); 00272 00273 if ((hash_tables= (TABLE_LIST*) hash_search(&thd->handler_tables_hash, 00274 (byte*) tables->alias, 00275 strlen(tables->alias) + 1))) 00276 { 00277 /* 00278 Though we could take the table pointer from hash_tables->table, 00279 we must follow the thd->handler_tables chain anyway, as we need the 00280 address of the 'next' pointer referencing this table 00281 for close_thread_table(). 00282 */ 00283 for (table_ptr= &(thd->handler_tables); 00284 *table_ptr && (*table_ptr != hash_tables->table); 00285 table_ptr= &(*table_ptr)->next) 00286 ; 00287 00288 if (*table_ptr) 00289 { 00290 (*table_ptr)->file->ha_index_or_rnd_end(); 00291 VOID(pthread_mutex_lock(&LOCK_open)); 00292 if (close_thread_table(thd, table_ptr)) 00293 { 00294 /* Tell threads waiting for refresh that something has happened */ 00295 broadcast_refresh(); 00296 } 00297 VOID(pthread_mutex_unlock(&LOCK_open)); 00298 } 00299 hash_delete(&thd->handler_tables_hash, (byte*) hash_tables); 00300 } 00301 else 00302 { 00303 my_error(ER_UNKNOWN_TABLE, MYF(0), tables->alias, "HANDLER"); 00304 DBUG_PRINT("exit",("ERROR")); 00305 DBUG_RETURN(TRUE); 00306 } 00307 00308 send_ok(thd); 00309 DBUG_PRINT("exit", ("OK")); 00310 DBUG_RETURN(FALSE); 00311 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int mysql_ha_flush | ( | THD * | thd, | |
| TABLE_LIST * | tables, | |||
| uint | mode_flags, | |||
| bool | is_locked | |||
| ) |
Definition at line 629 of file sql_handler.cc.
References st_table_list::alias, st_table_list::db, DBUG_ENTER, DBUG_PRINT, FALSE, LOCK_open, my_charset_latin1, my_strcasecmp, mysql_ha_flush_table(), st_table::next, st_table_list::next_local, pthread_mutex_lock, st_table_list::table_name, TRUE, and VOID.
Referenced by close_cached_tables(), mysql_admin_table(), mysql_alter_table(), mysql_rm_table_part2(), open_table(), and wait_for_tables().
00631 { 00632 TABLE_LIST *tmp_tables; 00633 TABLE **table_ptr; 00634 bool did_lock= FALSE; 00635 DBUG_ENTER("mysql_ha_flush"); 00636 DBUG_PRINT("enter", ("tables: %p mode_flags: 0x%02x", tables, mode_flags)); 00637 00638 if (tables) 00639 { 00640 /* Close all tables in the list. */ 00641 for (tmp_tables= tables ; tmp_tables; tmp_tables= tmp_tables->next_local) 00642 { 00643 DBUG_PRINT("info-in-tables-list",("'%s'.'%s' as '%s'", 00644 tmp_tables->db, tmp_tables->table_name, 00645 tmp_tables->alias)); 00646 /* Close all currently open handler tables with the same base table. */ 00647 table_ptr= &(thd->handler_tables); 00648 while (*table_ptr) 00649 { 00650 if ((!*tmp_tables->db || 00651 !my_strcasecmp(&my_charset_latin1, (*table_ptr)->s->db.str, 00652 tmp_tables->db)) && 00653 ! my_strcasecmp(&my_charset_latin1, 00654 (*table_ptr)->s->table_name.str, 00655 tmp_tables->table_name)) 00656 { 00657 DBUG_PRINT("info",("*table_ptr '%s'.'%s' as '%s'", 00658 (*table_ptr)->s->db.str, 00659 (*table_ptr)->s->table_name.str, 00660 (*table_ptr)->alias)); 00661 /* The first time it is required, lock for close_thread_table(). */ 00662 if (! did_lock && ! is_locked) 00663 { 00664 VOID(pthread_mutex_lock(&LOCK_open)); 00665 did_lock= TRUE; 00666 } 00667 mysql_ha_flush_table(thd, table_ptr, mode_flags); 00668 continue; 00669 } 00670 table_ptr= &(*table_ptr)->next; 00671 } 00672 /* end of handler_tables list */ 00673 } 00674 /* end of flush tables list */ 00675 } 00676 else 00677 { 00678 /* Close all currently open tables [which are marked for flush]. */ 00679 table_ptr= &(thd->handler_tables); 00680 while (*table_ptr) 00681 { 00682 if ((mode_flags & MYSQL_HA_FLUSH_ALL) || 00683 ((*table_ptr)->s->version != refresh_version)) 00684 { 00685 /* The first time it is required, lock for close_thread_table(). */ 00686 if (! did_lock && ! is_locked) 00687 { 00688 VOID(pthread_mutex_lock(&LOCK_open)); 00689 did_lock= TRUE; 00690 } 00691 mysql_ha_flush_table(thd, table_ptr, mode_flags); 00692 continue; 00693 } 00694 table_ptr= &(*table_ptr)->next; 00695 } 00696 } 00697 00698 /* Release the lock if it was taken by this function. */ 00699 if (did_lock) 00700 VOID(pthread_mutex_unlock(&LOCK_open)); 00701 00702 DBUG_RETURN(0); 00703 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 723 of file sql_handler.cc.
References st_table::alias, broadcast_refresh(), close_thread_table(), st_table_share::db, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, hash_delete(), hash_search(), LOCK_open, NULL, st_table::s, safe_mutex_assert_owner, LEX_STRING::str, strlen(), st_table_list::table, and st_table_share::table_name.
Referenced by mysql_ha_flush().
00724 { 00725 TABLE_LIST *hash_tables; 00726 TABLE *table= *table_ptr; 00727 DBUG_ENTER("mysql_ha_flush_table"); 00728 DBUG_PRINT("enter",("'%s'.'%s' as '%s' flags: 0x%02x", 00729 table->s->db.str, table->s->table_name.str, 00730 table->alias, mode_flags)); 00731 00732 if ((hash_tables= (TABLE_LIST*) hash_search(&thd->handler_tables_hash, 00733 (byte*) table->alias, 00734 strlen(table->alias) + 1))) 00735 { 00736 if (! (mode_flags & MYSQL_HA_REOPEN_ON_USAGE)) 00737 { 00738 /* This is a final close. Remove from hash. */ 00739 hash_delete(&thd->handler_tables_hash, (byte*) hash_tables); 00740 } 00741 else 00742 { 00743 /* Mark table as closed, ready for re-open. */ 00744 hash_tables->table= NULL; 00745 } 00746 } 00747 00748 safe_mutex_assert_owner(&LOCK_open); 00749 (*table_ptr)->file->ha_index_or_rnd_end(); 00750 safe_mutex_assert_owner(&LOCK_open); 00751 if (close_thread_table(thd, table_ptr)) 00752 { 00753 /* Tell threads waiting for refresh that something has happened */ 00754 broadcast_refresh(); 00755 } 00756 00757 DBUG_RETURN(0); 00758 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void mysql_ha_hash_free | ( | TABLE_LIST * | tables | ) | [static] |
Definition at line 118 of file sql_handler.cc.
Referenced by mysql_ha_open().
Here is the caller graph for this function:

| static char* mysql_ha_hash_get_key | ( | TABLE_LIST * | tables, | |
| uint * | key_len_p, | |||
| my_bool first | __attribute__((unused)) | |||
| ) | [static] |
Definition at line 96 of file sql_handler.cc.
References st_table_list::alias, and strlen().
Referenced by mysql_ha_open().
00098 { 00099 *key_len_p= strlen(tables->alias) + 1 ; /* include '\0' in comparisons */ 00100 return tables->alias; 00101 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool mysql_ha_open | ( | THD * | thd, | |
| TABLE_LIST * | tables, | |||
| bool | reopen | |||
| ) |
Definition at line 147 of file sql_handler.cc.
References st_table_list::alias, counter, st_table_list::db, db, DBUG_ASSERT, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, ER_ILLEGAL_HA, ER_NONUNIQ_TABLE, err, error, FALSE, st_table::file, FRMTYPE_TABLE, HA_CAN_SQL_HANDLER, handler::ha_table_flags(), HANDLER_TABLES_HACK, HANDLER_TABLES_HASH_SIZE, hash_init, hash_inited, hash_search(), memcpy, my_charset_latin1, my_error(), my_free, my_hash_insert(), my_multi_malloc(), MY_WME, MYF, mysql_ha_close(), mysql_ha_hash_free(), mysql_ha_hash_get_key(), name, NullS, open_tables(), st_table_list::required_type, send_ok(), strlen(), st_table_list::table, st_table_list::table_name, and TRUE.
Referenced by mysql_execute_command(), and mysql_ha_read().
00148 { 00149 TABLE_LIST *hash_tables; 00150 char *db, *name, *alias; 00151 uint dblen, namelen, aliaslen, counter; 00152 int error; 00153 DBUG_ENTER("mysql_ha_open"); 00154 DBUG_PRINT("enter",("'%s'.'%s' as '%s' reopen: %d", 00155 tables->db, tables->table_name, tables->alias, 00156 (int) reopen)); 00157 00158 if (! hash_inited(&thd->handler_tables_hash)) 00159 { 00160 /* 00161 HASH entries are of type TABLE_LIST. 00162 */ 00163 if (hash_init(&thd->handler_tables_hash, &my_charset_latin1, 00164 HANDLER_TABLES_HASH_SIZE, 0, 0, 00165 (hash_get_key) mysql_ha_hash_get_key, 00166 (hash_free_key) mysql_ha_hash_free, 0)) 00167 goto err; 00168 } 00169 else if (! reopen) /* Otherwise we have 'tables' already. */ 00170 { 00171 if (hash_search(&thd->handler_tables_hash, (byte*) tables->alias, 00172 strlen(tables->alias) + 1)) 00173 { 00174 DBUG_PRINT("info",("duplicate '%s'", tables->alias)); 00175 if (! reopen) 00176 my_error(ER_NONUNIQ_TABLE, MYF(0), tables->alias); 00177 goto err; 00178 } 00179 } 00180 00181 /* 00182 open_tables() will set 'tables->table' if successful. 00183 It must be NULL for a real open when calling open_tables(). 00184 */ 00185 DBUG_ASSERT(! tables->table); 00186 HANDLER_TABLES_HACK(thd); 00187 00188 /* for now HANDLER can be used only for real TABLES */ 00189 tables->required_type= FRMTYPE_TABLE; 00190 error= open_tables(thd, &tables, &counter, 0); 00191 HANDLER_TABLES_HACK(thd); 00192 00193 if (error) 00194 goto err; 00195 00196 /* There can be only one table in '*tables'. */ 00197 if (! (tables->table->file->ha_table_flags() & HA_CAN_SQL_HANDLER)) 00198 { 00199 if (! reopen) 00200 my_error(ER_ILLEGAL_HA, MYF(0), tables->alias); 00201 mysql_ha_close(thd, tables); 00202 goto err; 00203 } 00204 00205 if (! reopen) 00206 { 00207 /* copy the TABLE_LIST struct */ 00208 dblen= strlen(tables->db) + 1; 00209 namelen= strlen(tables->table_name) + 1; 00210 aliaslen= strlen(tables->alias) + 1; 00211 if (!(my_multi_malloc(MYF(MY_WME), 00212 &hash_tables, sizeof(*hash_tables), 00213 &db, dblen, 00214 &name, namelen, 00215 &alias, aliaslen, 00216 NullS))) 00217 goto err; 00218 /* structure copy */ 00219 *hash_tables= *tables; 00220 hash_tables->db= db; 00221 hash_tables->table_name= name; 00222 hash_tables->alias= alias; 00223 memcpy(hash_tables->db, tables->db, dblen); 00224 memcpy(hash_tables->table_name, tables->table_name, namelen); 00225 memcpy(hash_tables->alias, tables->alias, aliaslen); 00226 00227 /* add to hash */ 00228 if (my_hash_insert(&thd->handler_tables_hash, (byte*) hash_tables)) 00229 { 00230 my_free((char*) hash_tables, MYF(0)); 00231 mysql_ha_close(thd, tables); 00232 goto err; 00233 } 00234 } 00235 00236 if (! reopen) 00237 send_ok(thd); 00238 DBUG_PRINT("exit",("OK")); 00239 DBUG_RETURN(FALSE); 00240 00241 err: 00242 DBUG_PRINT("exit",("ERROR")); 00243 DBUG_RETURN(TRUE); 00244 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool mysql_ha_read | ( | THD * | thd, | |
| TABLE_LIST * | tables, | |||
| enum enum_ha_read_modes | mode, | |||
| char * | keyname, | |||
| List< Item > * | key_expr, | |||
| enum ha_rkey_function | ha_rkey_mode, | |||
| Item * | cond, | |||
| ha_rows | select_limit_cnt, | |||
| ha_rows | offset_limit_cnt | |||
| ) |
Definition at line 334 of file sql_handler.cc.
References st_table_list::alias, ALIGN_SIZE, st_table_share::all_set, buffer, cond, st_table_list::db, DBUG_ASSERT, DBUG_ENTER, DBUG_PRINT, dbug_tmp_restore_column_map(), dbug_tmp_use_all_columns(), base_list::elements, ER, ER_ILLEGAL_HA, ER_KEY_DOES_NOT_EXITS, ER_OUT_OF_RESOURCES, ER_TOO_MANY_KEY_PARTS, ER_UNKNOWN_TABLE, ER_WRONG_ARGUMENTS, err, error, st_key_part_info::field, st_table::file, find_type(), Item::fix_fields(), Item::fixed, Protocol::free(), HA_ERR_END_OF_FILE, HA_ERR_KEY_NOT_FOUND, HA_ERR_RECORD_DELETED, handler::ha_index_init(), handler::ha_index_or_rnd_end(), handler::ha_rnd_init(), HANDLER_TABLES_HACK, hash_search(), handler::index_first(), handler::index_last(), handler::index_next(), handler::index_next_same(), handler::index_prev(), handler::index_read(), handler::init_table_handle_for_HANDLER(), handler::inited, insert_fields(), int(), key, key_copy(), st_table::key_info, keyinfo, st_table_share::keynames, LINT_INIT, list(), lock, MAX_DBKEY_LENGTH, MAX_FIELD_WIDTH, my_error(), my_message(), MYF, mysql_ha_open(), mysql_lock_tables(), handler::NONE, NULL, NullS, ok(), Protocol::prepare_for_resend(), handler::print_error(), st_table::query_id, RAND_TABLE_BIT, st_table::read_set, st_table::record, List_iterator< T >::ref(), List_iterator< T >::rewind(), RFIRST, RKEY, rkey_to_rnext, RLAST, handler::rnd_next(), RNEXT, RNEXT_SAME, RPREV, st_table::s, Item::save_in_field(), Item::send(), Protocol::SEND_EOF, Protocol::send_fields(), Protocol::SEND_NUM_ROWS, sql_print_error(), st_key_part_info::store_length, strcmp(), strlen(), strxnmov(), system_charset_info, st_table_list::table, st_table_list::table_name, Item::used_tables(), Protocol::write(), and st_table::write_set.
Referenced by mysql_execute_command().
00339 { 00340 TABLE_LIST *hash_tables; 00341 TABLE *table; 00342 MYSQL_LOCK *lock; 00343 List<Item> list; 00344 Protocol *protocol= thd->protocol; 00345 char buff[MAX_FIELD_WIDTH]; 00346 String buffer(buff, sizeof(buff), system_charset_info); 00347 int error, keyno= -1; 00348 uint num_rows; 00349 byte *key; 00350 uint key_len; 00351 bool not_used; 00352 DBUG_ENTER("mysql_ha_read"); 00353 DBUG_PRINT("enter",("'%s'.'%s' as '%s'", 00354 tables->db, tables->table_name, tables->alias)); 00355 00356 LINT_INIT(key); 00357 LINT_INIT(key_len); 00358 00359 thd->lex->select_lex.context.resolve_in_table_list_only(tables); 00360 list.push_front(new Item_field(&thd->lex->select_lex.context, 00361 NULL, NULL, "*")); 00362 List_iterator<Item> it(list); 00363 it++; 00364 00365 if ((hash_tables= (TABLE_LIST*) hash_search(&thd->handler_tables_hash, 00366 (byte*) tables->alias, 00367 strlen(tables->alias) + 1))) 00368 { 00369 table= hash_tables->table; 00370 DBUG_PRINT("info-in-hash",("'%s'.'%s' as '%s' tab %p", 00371 hash_tables->db, hash_tables->table_name, 00372 hash_tables->alias, table)); 00373 if (!table) 00374 { 00375 /* 00376 The handler table has been closed. Re-open it. 00377 */ 00378 if (mysql_ha_open(thd, hash_tables, 1)) 00379 { 00380 DBUG_PRINT("exit",("reopen failed")); 00381 goto err0; 00382 } 00383 00384 table= hash_tables->table; 00385 DBUG_PRINT("info",("re-opened '%s'.'%s' as '%s' tab %p", 00386 hash_tables->db, hash_tables->table_name, 00387 hash_tables->alias, table)); 00388 } 00389 00390 #if MYSQL_VERSION_ID < 40100 00391 if (*tables->db && strcmp(table->table_cache_key, tables->db)) 00392 { 00393 DBUG_PRINT("info",("wrong db")); 00394 table= NULL; 00395 } 00396 #endif 00397 } 00398 else 00399 table= NULL; 00400 00401 if (!table) 00402 { 00403 #if MYSQL_VERSION_ID < 40100 00404 char buff[MAX_DBKEY_LENGTH]; 00405 if (*tables->db) 00406 strxnmov(buff, sizeof(buff)-1, tables->db, ".", tables->table_name, 00407 NullS); 00408 else 00409 strncpy(buff, tables->alias, sizeof(buff)); 00410 my_error(ER_UNKNOWN_TABLE, MYF(0), buff, "HANDLER"); 00411 #else 00412 my_error(ER_UNKNOWN_TABLE, MYF(0), tables->alias, "HANDLER"); 00413 #endif 00414 goto err0; 00415 } 00416 tables->table=table; 00417 00418 HANDLER_TABLES_HACK(thd); 00419 lock= mysql_lock_tables(thd, &tables->table, 1, 0, ¬_used); 00420 HANDLER_TABLES_HACK(thd); 00421 00422 if (!lock) 00423 goto err0; // mysql_lock_tables() printed error message already 00424 00425 // Always read all columns 00426 tables->table->read_set= &tables->table->s->all_set; 00427 00428 if (cond) 00429 { 00430 if (table->query_id != thd->query_id) 00431 cond->cleanup(); // File was reopened 00432 if ((!cond->fixed && 00433 cond->fix_fields(thd, &cond)) || cond->check_cols(1)) 00434 goto err0; 00435 } 00436 00437 if (keyname) 00438 { 00439 if ((keyno=find_type(keyname, &table->s->keynames, 1+2)-1)<0) 00440 { 00441 my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), keyname, tables->alias); 00442 goto err0; 00443 } 00444 } 00445 00446 if (insert_fields(thd, &thd->lex->select_lex.context, 00447 tables->db, tables->alias, &it, 0)) 00448 goto err0; 00449 00450 protocol->send_fields(&list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF); 00451 00452 /* 00453 In ::external_lock InnoDB resets the fields which tell it that 00454 the handle is used in the HANDLER interface. Tell it again that 00455 we are using it for HANDLER. 00456 */ 00457 00458 table->file->init_table_handle_for_HANDLER(); 00459 00460 for (num_rows=0; num_rows < select_limit_cnt; ) 00461 { 00462 switch (mode) { 00463 case RNEXT: 00464 if (table->file->inited != handler::NONE) 00465 { 00466 error=keyname ? 00467 table->file->index_next(table->record[0]) : 00468 table->file->rnd_next(table->record[0]); 00469 break; 00470 } 00471 /* else fall through */ 00472 case RFIRST: 00473 if (keyname) 00474 { 00475 table->file->ha_index_or_rnd_end(); 00476 table->file->ha_index_init(keyno, 1); 00477 error= table->file->index_first(table->record[0]); 00478 } 00479 else 00480 { 00481 table->file->ha_index_or_rnd_end(); 00482 if (!(error= table->file->ha_rnd_init(1))) 00483 error= table->file->rnd_next(table->record[0]); 00484 } 00485 mode=RNEXT; 00486 break; 00487 case RPREV: 00488 DBUG_ASSERT(keyname != 0); 00489 if (table->file->inited != handler::NONE) 00490 { 00491 error=table->file->index_prev(table->record[0]); 00492 break; 00493 } 00494 /* else fall through */ 00495 case RLAST: 00496 DBUG_ASSERT(keyname != 0); 00497 table->file->ha_index_or_rnd_end(); 00498 table->file->ha_index_init(keyno, 1); 00499 error= table->file->index_last(table->record[0]); 00500 mode=RPREV; 00501 break; 00502 case RNEXT_SAME: 00503 /* Continue scan on "(keypart1,keypart2,...)=(c1, c2, ...) */ 00504 DBUG_ASSERT(keyname != 0); 00505 error= table->file->index_next_same(table->record[0], key, key_len); 00506 break; 00507 case RKEY: 00508 { 00509 DBUG_ASSERT(keyname != 0); 00510 KEY *keyinfo=table->key_info+keyno; 00511 KEY_PART_INFO *key_part=keyinfo->key_part; 00512 if (key_expr->elements > keyinfo->key_parts) 00513 { 00514 my_error(ER_TOO_MANY_KEY_PARTS, MYF(0), keyinfo->key_parts); 00515 goto err; 00516 } 00517 List_iterator<Item> it_ke(*key_expr); 00518 Item *item; 00519 for (key_len=0 ; (item=it_ke++) ; key_part++) 00520 { 00521 my_bitmap_map *old_map; 00522 // 'item' can be changed by fix_fields() call 00523 if ((!item->fixed && 00524 item->fix_fields(thd, it_ke.ref())) || 00525 (item= *it_ke.ref())->check_cols(1)) 00526 goto err; 00527 if (item->used_tables() & ~RAND_TABLE_BIT) 00528 { 00529 my_error(ER_WRONG_ARGUMENTS,MYF(0),"HANDLER ... READ"); 00530 goto err; 00531 } 00532 old_map= dbug_tmp_use_all_columns(table, table->write_set); 00533 (void) item->save_in_field(key_part->field, 1); 00534 dbug_tmp_restore_column_map(table->write_set, old_map); 00535 key_len+=key_part->store_length; 00536 } 00537 00538 if (!(key= (byte*) thd->calloc(ALIGN_SIZE(key_len)))) 00539 goto err; 00540 table->file->ha_index_or_rnd_end(); 00541 table->file->ha_index_init(keyno, 1); 00542 key_copy(key, table->record[0], table->key_info + keyno, key_len); 00543 error= table->file->index_read(table->record[0], 00544 key,key_len,ha_rkey_mode); 00545 mode=rkey_to_rnext[(int)ha_rkey_mode]; 00546 break; 00547 } 00548 default: 00549 my_message(ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), MYF(0)); 00550 goto err; 00551 } 00552 00553 if (error) 00554 { 00555 if (error == HA_ERR_RECORD_DELETED) 00556 continue; 00557 if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) 00558 { 00559 sql_print_error("mysql_ha_read: Got error %d when reading table '%s'", 00560 error, tables->table_name); 00561 table->file->print_error(error,MYF(0)); 00562 goto err; 00563 } 00564 goto ok; 00565 } 00566 if (cond && !cond->val_int()) 00567 continue; 00568 if (num_rows >= offset_limit_cnt) 00569 { 00570 Item *item; 00571 protocol->prepare_for_resend(); 00572 it.rewind(); 00573 while ((item=it++)) 00574 { 00575 if (item->send(thd->protocol, &buffer)) 00576 { 00577 protocol->free(); // Free used 00578 my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); 00579 goto err; 00580 } 00581 } 00582 protocol->write(); 00583 } 00584 num_rows++; 00585 } 00586 ok: 00587 mysql_unlock_tables(thd,lock); 00588 send_eof(thd); 00589 DBUG_PRINT("exit",("OK")); 00590 DBUG_RETURN(FALSE); 00591 00592 err: 00593 mysql_unlock_tables(thd,lock); 00594 err0: 00595 DBUG_PRINT("exit",("ERROR")); 00596 DBUG_RETURN(TRUE); 00597 }
Here is the call graph for this function:


