summaryrefslogtreecommitdiff
path: root/sql/sql_handler.cc
diff options
context:
space:
mode:
authorunknown <sergefp@mysql.com>2004-05-18 22:59:43 +0400
committerunknown <sergefp@mysql.com>2004-05-18 22:59:43 +0400
commitcdf7471c2c504840bd6feb1e7c634a2d1ad8ed89 (patch)
treef4ce42bf90156e47e2c2a60ee12cf3d1d4bb0ea2 /sql/sql_handler.cc
parentd4f6c7a4c7e836fb81bd4b21a1ea8b1e69d0c917 (diff)
downloadmariadb-git-cdf7471c2c504840bd6feb1e7c634a2d1ad8ed89.tar.gz
Fix and test case for BUG#3649.
mysql-test/r/handler.result: Test case for BUG#3649 mysql-test/t/handler.test: Test case for BUG#3649 sql/sql_handler.cc: Fix for BUG#3649: when doing an index scan for an equality condition, use index_next_same to retrieve subsequent rows.
Diffstat (limited to 'sql/sql_handler.cc')
-rw-r--r--sql/sql_handler.cc68
1 files changed, 39 insertions, 29 deletions
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc
index a80b4040882..6f7bb319258 100644
--- a/sql/sql_handler.cc
+++ b/sql/sql_handler.cc
@@ -103,7 +103,7 @@ int mysql_ha_closeall(THD *thd, TABLE_LIST *tables)
}
static enum enum_ha_read_modes rkey_to_rnext[]=
- { RNEXT, RNEXT, RPREV, RNEXT, RPREV, RNEXT, RPREV };
+ { RKEY, RNEXT, RPREV, RNEXT, RPREV, RNEXT, RPREV };
int mysql_ha_read(THD *thd, TABLE_LIST *tables,
@@ -151,6 +151,10 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
HANDLER_TABLES_HACK(thd);
MYSQL_LOCK *lock=mysql_lock_tables(thd,&tables->table,1);
HANDLER_TABLES_HACK(thd);
+
+ byte *key= NULL;
+ uint key_len;
+ LINT_INIT(key_len); /* protected by key key variable */
if (!lock)
goto err0; // mysql_lock_tables() printed error message already
@@ -185,40 +189,46 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
break;
case RKEY:
{
- DBUG_ASSERT(keyname != 0);
- KEY *keyinfo=table->key_info+keyno;
- KEY_PART_INFO *key_part=keyinfo->key_part;
- uint key_len;
- byte *key;
- if (key_expr->elements > keyinfo->key_parts)
+ if (key)
{
- my_printf_error(ER_TOO_MANY_KEY_PARTS,ER(ER_TOO_MANY_KEY_PARTS),
- MYF(0),keyinfo->key_parts);
- goto err;
+ /* Continue scan on "(keypart1,keypart2,...)=(c1, c2, ...) */
+ err= table->file->index_next_same(table->record[0], key, key_len);
}
- List_iterator_fast<Item> it_ke(*key_expr);
- Item *item;
- for (key_len=0 ; (item=it_ke++) ; key_part++)
+ else
{
- if (item->fix_fields(thd, tables))
- goto err;
- if (item->used_tables() & ~RAND_TABLE_BIT)
+ DBUG_ASSERT(keyname != 0);
+ KEY *keyinfo=table->key_info+keyno;
+ KEY_PART_INFO *key_part=keyinfo->key_part;
+ if (key_expr->elements > keyinfo->key_parts)
{
- my_error(ER_WRONG_ARGUMENTS,MYF(0),"HANDLER ... READ");
- goto err;
+ my_printf_error(ER_TOO_MANY_KEY_PARTS,ER(ER_TOO_MANY_KEY_PARTS),
+ MYF(0),keyinfo->key_parts);
+ goto err;
}
- item->save_in_field(key_part->field, 1);
- key_len+=key_part->store_length;
- }
- if (!(key= (byte*) thd->calloc(ALIGN_SIZE(key_len))))
- {
- send_error(&thd->net,ER_OUTOFMEMORY);
- goto err;
+ List_iterator_fast<Item> it_ke(*key_expr);
+ Item *item;
+ for (key_len=0 ; (item=it_ke++) ; key_part++)
+ {
+ if (item->fix_fields(thd, tables))
+ goto err;
+ if (item->used_tables() & ~RAND_TABLE_BIT)
+ {
+ my_error(ER_WRONG_ARGUMENTS,MYF(0),"HANDLER ... READ");
+ goto err;
+ }
+ item->save_in_field(key_part->field, 1);
+ key_len+=key_part->store_length;
+ }
+ if (!(key= (byte*) thd->calloc(ALIGN_SIZE(key_len))))
+ {
+ send_error(&thd->net,ER_OUTOFMEMORY);
+ goto err;
+ }
+ key_copy(key, table, keyno, key_len);
+ err=table->file->index_read(table->record[0],
+ key,key_len,ha_rkey_mode);
+ mode=rkey_to_rnext[(int)ha_rkey_mode];
}
- key_copy(key, table, keyno, key_len);
- err=table->file->index_read(table->record[0],
- key,key_len,ha_rkey_mode);
- mode=rkey_to_rnext[(int)ha_rkey_mode];
break;
}
default: