diff options
Diffstat (limited to 'sql/sql_handler.cc')
-rw-r--r-- | sql/sql_handler.cc | 64 |
1 files changed, 43 insertions, 21 deletions
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index ddc9c4a99d7..02d5bbfc84f 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -345,7 +345,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, SQL_HANDLER *reopen) error= (thd->open_temporary_tables(tables) || open_tables(thd, &tables, &counter, 0)); - if (error) + if (unlikely(error)) goto err; table= tables->table; @@ -371,7 +371,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, SQL_HANDLER *reopen) /* The ticket returned is within a savepoint. Make a copy. */ error= thd->mdl_context.clone_ticket(&table_list->mdl_request); table_list->table->mdl_ticket= table_list->mdl_request.ticket; - if (error) + if (unlikely(error)) goto err; } } @@ -426,8 +426,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, SQL_HANDLER *reopen) thd->set_n_backup_active_arena(&sql_handler->arena, &backup_arena); error= table->fill_item_list(&sql_handler->fields); thd->restore_active_arena(&sql_handler->arena, &backup_arena); - - if (error) + if (unlikely(error)) goto err; /* Always read all columns */ @@ -619,7 +618,7 @@ static SQL_HANDLER *mysql_ha_find_handler(THD *thd, const LEX_CSTRING *name) static bool mysql_ha_fix_cond_and_key(SQL_HANDLER *handler, enum enum_ha_read_modes mode, const char *keyname, - List<Item> *key_expr, + List<Item> *key_expr, enum ha_rkey_function ha_rkey_mode, Item *cond, bool in_prepare) { THD *thd= handler->thd; @@ -661,6 +660,18 @@ mysql_ha_fix_cond_and_key(SQL_HANDLER *handler, Item *item; key_part_map keypart_map; uint key_len; + const KEY *c_key= table->s->key_info + handler->keyno; + + if ((c_key->flags & HA_SPATIAL) || + c_key->algorithm == HA_KEY_ALG_FULLTEXT || + (ha_rkey_mode != HA_READ_KEY_EXACT && + (table->file->index_flags(handler->keyno, 0, TRUE) & + (HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE)) == 0)) + { + my_error(ER_KEY_DOESNT_SUPPORT, MYF(0), + table->file->index_type(handler->keyno), keyinfo->name); + return 1; + } if (key_expr->elements > keyinfo->user_defined_key_parts) { @@ -668,6 +679,16 @@ mysql_ha_fix_cond_and_key(SQL_HANDLER *handler, keyinfo->user_defined_key_parts); return 1; } + + if (key_expr->elements < keyinfo->user_defined_key_parts && + (table->file->index_flags(handler->keyno, 0, TRUE) & + HA_ONLY_WHOLE_INDEX)) + { + my_error(ER_KEY_DOESNT_SUPPORT, MYF(0), + table->file->index_type(handler->keyno), keyinfo->name); + return 1; + } + for (keypart_map= key_len=0 ; (item=it_ke++) ; key_part++) { my_bitmap_map *old_map; @@ -838,11 +859,12 @@ retry: goto retry; } - if (lock_error) + if (unlikely(lock_error)) goto err0; // mysql_lock_tables() printed error message already } - if (mysql_ha_fix_cond_and_key(handler, mode, keyname, key_expr, cond, 0)) + if (mysql_ha_fix_cond_and_key(handler, mode, keyname, key_expr, + ha_rkey_mode, cond, 0)) goto err; mode= handler->mode; keyno= handler->keyno; @@ -880,14 +902,14 @@ retry: case RFIRST: if (keyname) { - if (!(error= table->file->ha_index_or_rnd_end()) && - !(error= table->file->ha_index_init(keyno, 1))) + if (likely(!(error= table->file->ha_index_or_rnd_end())) && + likely(!(error= table->file->ha_index_init(keyno, 1)))) error= table->file->ha_index_first(table->record[0]); } else { - if (!(error= table->file->ha_index_or_rnd_end()) && - !(error= table->file->ha_rnd_init(1))) + if (likely(!(error= table->file->ha_index_or_rnd_end())) && + likely(!(error= table->file->ha_rnd_init(1)))) error= table->file->ha_rnd_next(table->record[0]); } mode= RNEXT; @@ -906,8 +928,8 @@ retry: /* else fall through */ case RLAST: DBUG_ASSERT(keyname != 0); - if (!(error= table->file->ha_index_or_rnd_end()) && - !(error= table->file->ha_index_init(keyno, 1))) + if (likely(!(error= table->file->ha_index_or_rnd_end())) && + likely(!(error= table->file->ha_index_init(keyno, 1)))) error= table->file->ha_index_last(table->record[0]); mode=RPREV; break; @@ -921,13 +943,13 @@ retry: { DBUG_ASSERT(keyname != 0); - if (!(key= (uchar*) thd->calloc(ALIGN_SIZE(handler->key_len)))) + if (unlikely(!(key= (uchar*) thd->calloc(ALIGN_SIZE(handler->key_len))))) goto err; - if ((error= table->file->ha_index_or_rnd_end())) + if (unlikely((error= table->file->ha_index_or_rnd_end()))) break; key_copy(key, table->record[0], table->key_info + keyno, handler->key_len); - if (!(error= table->file->ha_index_init(keyno, 1))) + if (unlikely(!(error= table->file->ha_index_init(keyno, 1)))) error= table->file->ha_index_read_map(table->record[0], key, handler->keypart_map, ha_rkey_mode); @@ -940,10 +962,8 @@ retry: goto err; } - if (error) + if (unlikely(error)) { - if (error == HA_ERR_RECORD_DELETED) - continue; if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) { /* Don't give error in the log file for some expected problems */ @@ -1003,14 +1023,16 @@ err0: SQL_HANDLER *mysql_ha_read_prepare(THD *thd, TABLE_LIST *tables, enum enum_ha_read_modes mode, const char *keyname, - List<Item> *key_expr, Item *cond) + List<Item> *key_expr, enum ha_rkey_function ha_rkey_mode, + Item *cond) { SQL_HANDLER *handler; DBUG_ENTER("mysql_ha_read_prepare"); if (!(handler= mysql_ha_find_handler(thd, &tables->alias))) DBUG_RETURN(0); tables->table= handler->table; // This is used by fix_fields - if (mysql_ha_fix_cond_and_key(handler, mode, keyname, key_expr, cond, 1)) + if (mysql_ha_fix_cond_and_key(handler, mode, keyname, key_expr, + ha_rkey_mode, cond, 1)) DBUG_RETURN(0); DBUG_RETURN(handler); } |