summaryrefslogtreecommitdiff
path: root/sql/sql_handler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_handler.cc')
-rw-r--r--sql/sql_handler.cc64
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);
}