Commit 5788294f authored by Michael Widenius's avatar Michael Widenius

Added HANDLER support for MEMORY tables

Added key and file version numbers to MEMORY tables so that we can detect if someone has changed them between HANDLER calls.


mysql-test/suite/handler/aria.result:
  Fixed result after test changes
mysql-test/suite/handler/handler.inc:
  Changed test to use combined key to ensure rows are returned in a pre-determinated order.
mysql-test/suite/handler/heap.result:
  New result
mysql-test/suite/handler/heap.test:
  Added test for HANDLER + HEAP
mysql-test/suite/handler/innodb.result:
  Fixed result after test changes
mysql-test/suite/handler/myisam.result:
  Fixed result after test changes
sql/sql_handler.cc:
  Fixed wrong parameter to ha_index_next_same()
storage/heap/ha_heap.cc:
  Abort key scan if table has changed.
  Abort table scan if table has been recreated.
storage/heap/ha_heap.h:
  Added support for HANDLER
storage/heap/hp_clear.c:
  Increase version number so that we can notice changes if using HANDLER
storage/heap/hp_delete.c:
  Increase key data version number on key changes.
storage/heap/hp_rfirst.c:
  Remember version of key data
  Give error if using read-first on hash key.
storage/heap/hp_rkey.c:
  Remember version of key data
storage/heap/hp_rlast.c:
  Remember version of key data
  Give error if using read-last on hash key.
storage/heap/hp_rnext.c:
  Fixed that we get next key from last search.
storage/heap/hp_rprev.c:
  Fixed that we get previous key from last search.
storage/heap/hp_scan.c:
  Remember version of key and file data
storage/heap/hp_update.c:
  Increase key data version number on key changes.
storage/heap/hp_write.c:
  Increase key data version number on key changes.
parent 0a73f4ed
...@@ -136,6 +136,8 @@ typedef struct st_heap_share ...@@ -136,6 +136,8 @@ typedef struct st_heap_share
ulong min_records,max_records; /* Params to open */ ulong min_records,max_records; /* Params to open */
ulonglong data_length,index_length,max_table_size; ulonglong data_length,index_length,max_table_size;
uint key_stat_version; /* version to indicate insert/delete */ uint key_stat_version; /* version to indicate insert/delete */
uint key_version; /* Updated on key change */
uint file_version; /* Update on clear */
uint records; /* records */ uint records; /* records */
uint blength; /* records rounded up to 2^n */ uint blength; /* records rounded up to 2^n */
uint deleted; /* Deleted records in database */ uint deleted; /* Deleted records in database */
...@@ -173,6 +175,8 @@ typedef struct st_heap_info ...@@ -173,6 +175,8 @@ typedef struct st_heap_info
enum ha_rkey_function last_find_flag; enum ha_rkey_function last_find_flag;
TREE_ELEMENT *parents[MAX_TREE_HEIGHT+1]; TREE_ELEMENT *parents[MAX_TREE_HEIGHT+1];
TREE_ELEMENT **last_pos; TREE_ELEMENT **last_pos;
uint key_version; /* Version at last read */
uint file_version; /* Version at scan */
uint lastkey_len; uint lastkey_len;
my_bool implicit_emptied; my_bool implicit_emptied;
#ifdef THREAD #ifdef THREAD
......
...@@ -6,42 +6,42 @@ insert into t1 values ...@@ -6,42 +6,42 @@ insert into t1 values
(14,"aaa"),(16,"ccc"),(16,"xxx"), (14,"aaa"),(16,"ccc"),(16,"xxx"),
(20,"ggg"),(21,"hhh"),(22,"iii"); (20,"ggg"),(21,"hhh"),(22,"iii");
handler t1 open as t2; handler t1 open as t2;
handler t2 read a first; handler t2 read b first;
a b a b
14 aaa 14 aaa
handler t2 read a next; handler t2 read b next;
a b a b
16 ccc 16 ccc
handler t2 read a next; handler t2 read b next;
a b a b
16 xxx 16 xxx
handler t2 read a prev; handler t2 read b prev;
a b a b
16 ccc 16 ccc
handler t2 read a last; handler t2 read b last;
a b a b
22 iii 22 iii
handler t2 read a prev; handler t2 read b prev;
a b a b
21 hhh 21 hhh
handler t2 read a prev; handler t2 read b prev;
a b a b
20 ggg 20 ggg
handler t2 read a first; handler t2 read b first;
a b a b
14 aaa 14 aaa
handler t2 read a prev; handler t2 read b prev;
a b a b
handler t2 read a last; handler t2 read b last;
a b a b
22 iii 22 iii
handler t2 read a prev; handler t2 read b prev;
a b a b
21 hhh 21 hhh
handler t2 read a next; handler t2 read b next;
a b a b
22 iii 22 iii
handler t2 read a next; handler t2 read b next;
a b a b
handler t2 read a=(15); handler t2 read a=(15);
a b a b
...@@ -66,19 +66,19 @@ a b ...@@ -66,19 +66,19 @@ a b
handler t2 read a>=(11); handler t2 read a>=(11);
a b a b
14 aaa 14 aaa
handler t2 read a=(18); handler t2 read b=(18);
a b a b
18 eee 18 eee
handler t2 read a>=(18); handler t2 read b>=(18);
a b a b
18 eee 18 eee
handler t2 read a>(18); handler t2 read b>(18);
a b a b
19 fff 19 fff
handler t2 read a<=(18); handler t2 read b<=(18);
a b a b
18 eee 18 eee
handler t2 read a<(18); handler t2 read b<(18);
a b a b
17 ddd 17 ddd
handler t2 read a=(15); handler t2 read a=(15);
...@@ -119,19 +119,19 @@ handler t2 read a<=(1); ...@@ -119,19 +119,19 @@ handler t2 read a<=(1);
a b a b
handler t2 read a<(1); handler t2 read a<(1);
a b a b
handler t2 read a first limit 5; handler t2 read b first limit 5;
a b a b
14 aaa 14 aaa
16 ccc 16 ccc
16 xxx 16 xxx
17 ddd 17 ddd
18 eee 18 eee
handler t2 read a next limit 3; handler t2 read b next limit 3;
a b a b
19 fff 19 fff
19 yyy 19 yyy
20 ggg 20 ggg
handler t2 read a prev limit 10; handler t2 read b prev limit 10;
a b a b
19 yyy 19 yyy
19 fff 19 fff
...@@ -162,10 +162,10 @@ a b ...@@ -162,10 +162,10 @@ a b
handler t2 read a=(16) limit 1,3; handler t2 read a=(16) limit 1,3;
a b a b
16 xxx 16 xxx
handler t2 read a=(19); handler t2 read b=(19);
a b a b
19 fff 19 fff
handler t2 read a=(19) where b="yyy"; handler t2 read b=(19) where b="yyy";
a b a b
19 yyy 19 yyy
handler t2 read first; handler t2 read first;
...@@ -557,7 +557,7 @@ handler t1_alias READ a next where inexistent > 0; ...@@ -557,7 +557,7 @@ handler t1_alias READ a next where inexistent > 0;
ERROR 42S22: Unknown column 'inexistent' in 'field list' ERROR 42S22: Unknown column 'inexistent' in 'field list'
handler t1_alias close; handler t1_alias close;
drop table t1; drop table t1;
create temporary table t1 (a int, b char(1), key a (a), key b(a,b)); create temporary table t1 (a int, b char(1), key a (a), key b (a,b));
insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"), insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"),
(5,"f"),(6,"g"),(7,"h"),(8,"i"),(9,"j"),(9,'k'); (5,"f"),(6,"g"),(7,"h"),(8,"i"),(9,"j"),(9,'k');
select a,b from t1; select a,b from t1;
...@@ -609,20 +609,20 @@ a b ...@@ -609,20 +609,20 @@ a b
9 j 9 j
9 k 9 k
handler t1 open as a2; handler t1 open as a2;
handler a2 read a=(9); handler a2 read b=(9);
a b a b
9 j 9 j
handler a2 read a next; handler a2 read b next;
a b a b
9 k 9 k
handler a2 read a prev limit 2; handler a2 read b prev limit 2;
a b a b
9 j 9 j
8 i 8 i
handler a2 read a last; handler a2 read b last;
a b a b
9 k 9 k
handler a2 read a prev; handler a2 read b prev;
a b a b
9 j 9 j
handler a2 close; handler a2 close;
......
...@@ -23,21 +23,21 @@ ...@@ -23,21 +23,21 @@
# Start testing the table created in init.inc # Start testing the table created in init.inc
# #
handler t1 open as t2; handler t1 open as t2;
handler t2 read a first; handler t2 read b first;
handler t2 read a next; handler t2 read b next;
handler t2 read a next; handler t2 read b next;
handler t2 read a prev; handler t2 read b prev;
handler t2 read a last; handler t2 read b last;
handler t2 read a prev; handler t2 read b prev;
handler t2 read a prev; handler t2 read b prev;
handler t2 read a first; handler t2 read b first;
handler t2 read a prev; handler t2 read b prev;
handler t2 read a last; handler t2 read b last;
handler t2 read a prev; handler t2 read b prev;
handler t2 read a next; handler t2 read b next;
handler t2 read a next; handler t2 read b next;
handler t2 read a=(15); handler t2 read a=(15);
handler t2 read a=(16); handler t2 read a=(16);
...@@ -55,16 +55,19 @@ handler t1 read a last; ...@@ -55,16 +55,19 @@ handler t1 read a last;
handler t2 read a=(11); handler t2 read a=(11);
handler t2 read a>=(11); handler t2 read a>=(11);
# Search on something we ca nfind # Search on something we can find
handler t2 read a=(18); handler t2 read b=(18);
handler t2 read a>=(18); handler t2 read b>=(18);
handler t2 read a>(18); handler t2 read b>(18);
handler t2 read a<=(18); handler t2 read b<=(18);
handler t2 read a<(18); handler t2 read b<(18);
# Search on something we can't find # Search on something we can't find
--sorted_result
handler t2 read a=(15); handler t2 read a=(15);
--sorted_result
handler t2 read a>=(15); handler t2 read a>=(15);
--sorted_result
handler t2 read a>(15); handler t2 read a>(15);
handler t2 read a<=(15); handler t2 read a<=(15);
handler t2 read a<(15); handler t2 read a<(15);
...@@ -83,17 +86,17 @@ handler t2 read a>(1); ...@@ -83,17 +86,17 @@ handler t2 read a>(1);
handler t2 read a<=(1); handler t2 read a<=(1);
handler t2 read a<(1); handler t2 read a<(1);
handler t2 read a first limit 5; handler t2 read b first limit 5;
handler t2 read a next limit 3; handler t2 read b next limit 3;
handler t2 read a prev limit 10; handler t2 read b prev limit 10;
handler t2 read a>=(16) limit 4; handler t2 read a>=(16) limit 4;
handler t2 read a>=(16) limit 2,2; handler t2 read a>=(16) limit 2,2;
select * from t1 where a>=16 limit 2,2; select * from t1 where a>=16 limit 2,2;
handler t2 read a last limit 3; handler t2 read a last limit 3;
handler t2 read a=(16) limit 1,3; handler t2 read a=(16) limit 1,3;
handler t2 read a=(19); handler t2 read b=(19);
handler t2 read a=(19) where b="yyy"; handler t2 read b=(19) where b="yyy";
handler t2 read first; handler t2 read first;
handler t2 read next; handler t2 read next;
...@@ -450,7 +453,7 @@ drop table t1; ...@@ -450,7 +453,7 @@ drop table t1;
# is open by a HANDLER, no other statement can access it. # is open by a HANDLER, no other statement can access it.
# #
eval create temporary table t1 (a int, b char(1), key a $key_type (a), key b(a,b)); eval create temporary table t1 (a int, b char(1), key a $key_type (a), key b $key_type (a,b));
insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"), insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"),
(5,"f"),(6,"g"),(7,"h"),(8,"i"),(9,"j"),(9,'k'); (5,"f"),(6,"g"),(7,"h"),(8,"i"),(9,"j"),(9,'k');
select a,b from t1; select a,b from t1;
...@@ -466,12 +469,12 @@ handler a1 read a=(6) where b="g"; ...@@ -466,12 +469,12 @@ handler a1 read a=(6) where b="g";
handler a1 close; handler a1 close;
select a,b from t1; select a,b from t1;
handler t1 open as a2; handler t1 open as a2;
handler a2 read a=(9); handler a2 read b=(9);
handler a2 read a next; handler a2 read b next;
handler a2 read a prev limit 2; handler a2 read b prev limit 2;
--error 0,1031 --error 0,1031
handler a2 read a last; handler a2 read b last;
handler a2 read a prev; handler a2 read b prev;
handler a2 close; handler a2 close;
drop table t1; drop table t1;
......
This diff is collapsed.
# test of HANDLER with HEAP tables
#
let $engine_type= MEMORY;
let $key_type=using btree;
--source init.inc
--source handler.inc
#
# Test what happens if table is changed (Unique test for HEAP)
#
connect (con1,localhost,root,,);
connection default;
CREATE TABLE t1(a INT, b INT, KEY(a), KEY b using btree (b), KEY ab using btree(a, b));
INSERT INTO t1 VALUES (2, 20), (2,20), (1, 10), (4, 40), (3, 30), (5,50), (6,50);
HANDLER t1 OPEN;
HANDLER t1 READ a>=(2) limit 3;
HANDLER t1 READ a PREV;
HANDLER t1 READ a PREV;
HANDLER t1 READ a PREV;
HANDLER t1 READ b>=(20) limit 3;
HANDLER t1 READ b PREV;
HANDLER t1 READ b PREV LIMIT 2;
HANDLER t1 READ ab=(3,30) limit 3;
HANDLER t1 READ ab>=(3,30) limit 3;
# Test FIRST/LAST on hash and btree keys
--error ER_ILLEGAL_HA
HANDLER t1 READ a FIRST;
--error ER_ILLEGAL_HA
HANDLER t1 READ a LAST;
HANDLER t1 READ b FIRST LIMIT 2;
HANDLER t1 READ b LAST LIMIT 2;
# Table scan
HANDLER t1 READ FIRST LIMIT 10;
# Index scan
HANDLER t1 READ b FIRST;
insert into t1 values (7,50);
--error ER_CHECKREAD
HANDLER t1 READ b NEXT;
HANDLER t1 READ b FIRST;
connection con1;
insert into t1 values (7,50);
connection default;
--error ER_CHECKREAD
HANDLER t1 READ b NEXT;
HANDLER t1 READ FIRST;
connection con1;
insert into t1 values (8,50);
connection default;
HANDLER t1 READ NEXT;
connection con1;
delete from t1 where a=3;
connection default;
HANDLER t1 READ NEXT LIMIT 2;
connection con1;
delete from t1;
connection default;
--error ER_CHECKREAD
HANDLER t1 READ NEXT LIMIT 2;
HANDLER t1 CLOSE;
DROP TABLE t1;
disconnect con1;
--echo End of 5.1 tests
...@@ -6,42 +6,42 @@ insert into t1 values ...@@ -6,42 +6,42 @@ insert into t1 values
(14,"aaa"),(16,"ccc"),(16,"xxx"), (14,"aaa"),(16,"ccc"),(16,"xxx"),
(20,"ggg"),(21,"hhh"),(22,"iii"); (20,"ggg"),(21,"hhh"),(22,"iii");
handler t1 open as t2; handler t1 open as t2;
handler t2 read a first; handler t2 read b first;
a b a b
14 aaa 14 aaa
handler t2 read a next; handler t2 read b next;
a b a b
16 ccc 16 ccc
handler t2 read a next; handler t2 read b next;
a b a b
16 xxx 16 xxx
handler t2 read a prev; handler t2 read b prev;
a b a b
16 ccc 16 ccc
handler t2 read a last; handler t2 read b last;
a b a b
22 iii 22 iii
handler t2 read a prev; handler t2 read b prev;
a b a b
21 hhh 21 hhh
handler t2 read a prev; handler t2 read b prev;
a b a b
20 ggg 20 ggg
handler t2 read a first; handler t2 read b first;
a b a b
14 aaa 14 aaa
handler t2 read a prev; handler t2 read b prev;
a b a b
handler t2 read a last; handler t2 read b last;
a b a b
22 iii 22 iii
handler t2 read a prev; handler t2 read b prev;
a b a b
21 hhh 21 hhh
handler t2 read a next; handler t2 read b next;
a b a b
22 iii 22 iii
handler t2 read a next; handler t2 read b next;
a b a b
handler t2 read a=(15); handler t2 read a=(15);
a b a b
...@@ -66,19 +66,19 @@ a b ...@@ -66,19 +66,19 @@ a b
handler t2 read a>=(11); handler t2 read a>=(11);
a b a b
14 aaa 14 aaa
handler t2 read a=(18); handler t2 read b=(18);
a b a b
18 eee 18 eee
handler t2 read a>=(18); handler t2 read b>=(18);
a b a b
18 eee 18 eee
handler t2 read a>(18); handler t2 read b>(18);
a b a b
19 fff 19 fff
handler t2 read a<=(18); handler t2 read b<=(18);
a b a b
18 eee 18 eee
handler t2 read a<(18); handler t2 read b<(18);
a b a b
17 ddd 17 ddd
handler t2 read a=(15); handler t2 read a=(15);
...@@ -119,19 +119,19 @@ handler t2 read a<=(1); ...@@ -119,19 +119,19 @@ handler t2 read a<=(1);
a b a b
handler t2 read a<(1); handler t2 read a<(1);
a b a b
handler t2 read a first limit 5; handler t2 read b first limit 5;
a b a b
14 aaa 14 aaa
16 ccc 16 ccc
16 xxx 16 xxx
17 ddd 17 ddd
18 eee 18 eee
handler t2 read a next limit 3; handler t2 read b next limit 3;
a b a b
19 fff 19 fff
19 yyy 19 yyy
20 ggg 20 ggg
handler t2 read a prev limit 10; handler t2 read b prev limit 10;
a b a b
19 yyy 19 yyy
19 fff 19 fff
...@@ -162,10 +162,10 @@ a b ...@@ -162,10 +162,10 @@ a b
handler t2 read a=(16) limit 1,3; handler t2 read a=(16) limit 1,3;
a b a b
16 xxx 16 xxx
handler t2 read a=(19); handler t2 read b=(19);
a b a b
19 fff 19 fff
handler t2 read a=(19) where b="yyy"; handler t2 read b=(19) where b="yyy";
a b a b
19 yyy 19 yyy
handler t2 read first; handler t2 read first;
...@@ -558,7 +558,7 @@ handler t1_alias READ a next where inexistent > 0; ...@@ -558,7 +558,7 @@ handler t1_alias READ a next where inexistent > 0;
ERROR 42S22: Unknown column 'inexistent' in 'field list' ERROR 42S22: Unknown column 'inexistent' in 'field list'
handler t1_alias close; handler t1_alias close;
drop table t1; drop table t1;
create temporary table t1 (a int, b char(1), key a (a), key b(a,b)); create temporary table t1 (a int, b char(1), key a (a), key b (a,b));
insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"), insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"),
(5,"f"),(6,"g"),(7,"h"),(8,"i"),(9,"j"),(9,'k'); (5,"f"),(6,"g"),(7,"h"),(8,"i"),(9,"j"),(9,'k');
select a,b from t1; select a,b from t1;
...@@ -610,20 +610,20 @@ a b ...@@ -610,20 +610,20 @@ a b
9 j 9 j
9 k 9 k
handler t1 open as a2; handler t1 open as a2;
handler a2 read a=(9); handler a2 read b=(9);
a b a b
9 j 9 j
handler a2 read a next; handler a2 read b next;
a b a b
9 k 9 k
handler a2 read a prev limit 2; handler a2 read b prev limit 2;
a b a b
9 j 9 j
8 i 8 i
handler a2 read a last; handler a2 read b last;
a b a b
9 k 9 k
handler a2 read a prev; handler a2 read b prev;
a b a b
9 j 9 j
handler a2 close; handler a2 close;
......
...@@ -6,42 +6,42 @@ insert into t1 values ...@@ -6,42 +6,42 @@ insert into t1 values
(14,"aaa"),(16,"ccc"),(16,"xxx"), (14,"aaa"),(16,"ccc"),(16,"xxx"),
(20,"ggg"),(21,"hhh"),(22,"iii"); (20,"ggg"),(21,"hhh"),(22,"iii");
handler t1 open as t2; handler t1 open as t2;
handler t2 read a first; handler t2 read b first;
a b a b
14 aaa 14 aaa
handler t2 read a next; handler t2 read b next;
a b a b
16 ccc 16 ccc
handler t2 read a next; handler t2 read b next;
a b a b
16 xxx 16 xxx
handler t2 read a prev; handler t2 read b prev;
a b a b
16 ccc 16 ccc
handler t2 read a last; handler t2 read b last;
a b a b
22 iii 22 iii
handler t2 read a prev; handler t2 read b prev;
a b a b
21 hhh 21 hhh
handler t2 read a prev; handler t2 read b prev;
a b a b
20 ggg 20 ggg
handler t2 read a first; handler t2 read b first;
a b a b
14 aaa 14 aaa
handler t2 read a prev; handler t2 read b prev;
a b a b
handler t2 read a last; handler t2 read b last;
a b a b
22 iii 22 iii
handler t2 read a prev; handler t2 read b prev;
a b a b
21 hhh 21 hhh
handler t2 read a next; handler t2 read b next;
a b a b
22 iii 22 iii
handler t2 read a next; handler t2 read b next;
a b a b
handler t2 read a=(15); handler t2 read a=(15);
a b a b
...@@ -66,19 +66,19 @@ a b ...@@ -66,19 +66,19 @@ a b
handler t2 read a>=(11); handler t2 read a>=(11);
a b a b
14 aaa 14 aaa
handler t2 read a=(18); handler t2 read b=(18);
a b a b
18 eee 18 eee
handler t2 read a>=(18); handler t2 read b>=(18);
a b a b
18 eee 18 eee
handler t2 read a>(18); handler t2 read b>(18);
a b a b
19 fff 19 fff
handler t2 read a<=(18); handler t2 read b<=(18);
a b a b
18 eee 18 eee
handler t2 read a<(18); handler t2 read b<(18);
a b a b
17 ddd 17 ddd
handler t2 read a=(15); handler t2 read a=(15);
...@@ -119,19 +119,19 @@ handler t2 read a<=(1); ...@@ -119,19 +119,19 @@ handler t2 read a<=(1);
a b a b
handler t2 read a<(1); handler t2 read a<(1);
a b a b
handler t2 read a first limit 5; handler t2 read b first limit 5;
a b a b
14 aaa 14 aaa
16 ccc 16 ccc
16 xxx 16 xxx
17 ddd 17 ddd
18 eee 18 eee
handler t2 read a next limit 3; handler t2 read b next limit 3;
a b a b
19 fff 19 fff
19 yyy 19 yyy
20 ggg 20 ggg
handler t2 read a prev limit 10; handler t2 read b prev limit 10;
a b a b
19 yyy 19 yyy
19 fff 19 fff
...@@ -162,10 +162,10 @@ a b ...@@ -162,10 +162,10 @@ a b
handler t2 read a=(16) limit 1,3; handler t2 read a=(16) limit 1,3;
a b a b
16 xxx 16 xxx
handler t2 read a=(19); handler t2 read b=(19);
a b a b
19 fff 19 fff
handler t2 read a=(19) where b="yyy"; handler t2 read b=(19) where b="yyy";
a b a b
19 yyy 19 yyy
handler t2 read first; handler t2 read first;
...@@ -557,7 +557,7 @@ handler t1_alias READ a next where inexistent > 0; ...@@ -557,7 +557,7 @@ handler t1_alias READ a next where inexistent > 0;
ERROR 42S22: Unknown column 'inexistent' in 'field list' ERROR 42S22: Unknown column 'inexistent' in 'field list'
handler t1_alias close; handler t1_alias close;
drop table t1; drop table t1;
create temporary table t1 (a int, b char(1), key a (a), key b(a,b)); create temporary table t1 (a int, b char(1), key a (a), key b (a,b));
insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"), insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"),
(5,"f"),(6,"g"),(7,"h"),(8,"i"),(9,"j"),(9,'k'); (5,"f"),(6,"g"),(7,"h"),(8,"i"),(9,"j"),(9,'k');
select a,b from t1; select a,b from t1;
...@@ -609,20 +609,20 @@ a b ...@@ -609,20 +609,20 @@ a b
9 j 9 j
9 k 9 k
handler t1 open as a2; handler t1 open as a2;
handler a2 read a=(9); handler a2 read b=(9);
a b a b
9 j 9 j
handler a2 read a next; handler a2 read b next;
a b a b
9 k 9 k
handler a2 read a prev limit 2; handler a2 read b prev limit 2;
a b a b
9 j 9 j
8 i 8 i
handler a2 read a last; handler a2 read b last;
a b a b
9 k 9 k
handler a2 read a prev; handler a2 read b prev;
a b a b
9 j 9 j
handler a2 close; handler a2 close;
......
...@@ -657,7 +657,6 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, ...@@ -657,7 +657,6 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
int error, keyno; int error, keyno;
uint num_rows; uint num_rows;
uchar *UNINIT_VAR(key); uchar *UNINIT_VAR(key);
uint UNINIT_VAR(key_len);
bool need_reopen; bool need_reopen;
List_iterator<Item> it; List_iterator<Item> it;
DBUG_ENTER("mysql_ha_read"); DBUG_ENTER("mysql_ha_read");
...@@ -784,7 +783,8 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, ...@@ -784,7 +783,8 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
case RNEXT_SAME: case RNEXT_SAME:
/* Continue scan on "(keypart1,keypart2,...)=(c1, c2, ...) */ /* Continue scan on "(keypart1,keypart2,...)=(c1, c2, ...) */
DBUG_ASSERT(keyname != 0); DBUG_ASSERT(keyname != 0);
error= table->file->ha_index_next_same(table->record[0], key, key_len); error= table->file->ha_index_next_same(table->record[0], key,
handler->key_len);
break; break;
case RKEY: case RKEY:
{ {
......
...@@ -183,6 +183,19 @@ void ha_heap::set_keys_for_scanning(void) ...@@ -183,6 +183,19 @@ void ha_heap::set_keys_for_scanning(void)
} }
int ha_heap::can_continue_handler_scan()
{
int error= 0;
if ((file->key_version != file->s->key_version && inited == INDEX) ||
(file->file_version != file->s->file_version && inited == RND))
{
/* Data changed, not safe to do index or rnd scan */
error= HA_ERR_RECORD_CHANGED;
}
return error;
}
void ha_heap::update_key_stats() void ha_heap::update_key_stats()
{ {
for (uint i= 0; i < table->s->keys; i++) for (uint i= 0; i < table->s->keys; i++)
......
/* Copyright (C) 2000-2006 MySQL AB /* Copyright (C) 2000-2006 MySQL AB, 2009-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -52,6 +52,7 @@ class ha_heap: public handler ...@@ -52,6 +52,7 @@ class ha_heap: public handler
{ {
return (HA_FAST_KEY_READ | HA_NO_BLOBS | HA_NULL_IN_KEY | return (HA_FAST_KEY_READ | HA_NO_BLOBS | HA_NULL_IN_KEY |
HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE | HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
HA_CAN_SQL_HANDLER |
HA_REC_NOT_IN_SEQ | HA_CAN_INSERT_DELAYED | HA_NO_TRANSACTIONS | HA_REC_NOT_IN_SEQ | HA_CAN_INSERT_DELAYED | HA_NO_TRANSACTIONS |
HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT); HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT);
} }
...@@ -93,6 +94,7 @@ class ha_heap: public handler ...@@ -93,6 +94,7 @@ class ha_heap: public handler
int rnd_next(uchar *buf); int rnd_next(uchar *buf);
int rnd_pos(uchar * buf, uchar *pos); int rnd_pos(uchar * buf, uchar *pos);
void position(const uchar *record); void position(const uchar *record);
int can_continue_handler_scan();
int info(uint); int info(uint);
int extra(enum ha_extra_function operation); int extra(enum ha_extra_function operation);
int reset(); int reset();
......
...@@ -40,6 +40,8 @@ void hp_clear(HP_SHARE *info) ...@@ -40,6 +40,8 @@ void hp_clear(HP_SHARE *info)
info->blength=1; info->blength=1;
info->changed=0; info->changed=0;
info->del_link=0; info->del_link=0;
info->key_version++;
info->file_version++;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
......
...@@ -47,6 +47,7 @@ int heap_delete(HP_INFO *info, const uchar *record) ...@@ -47,6 +47,7 @@ int heap_delete(HP_INFO *info, const uchar *record)
share->del_link=pos; share->del_link=pos;
pos[share->reclength]=0; /* Record deleted */ pos[share->reclength]=0; /* Record deleted */
share->deleted++; share->deleted++;
share->key_version++;
info->current_hash_ptr=0; info->current_hash_ptr=0;
#if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG) #if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
DBUG_EXECUTE("check_heap",heap_check_heap(info, 0);); DBUG_EXECUTE("check_heap",heap_check_heap(info, 0););
......
...@@ -24,6 +24,8 @@ int heap_rfirst(HP_INFO *info, uchar *record, int inx) ...@@ -24,6 +24,8 @@ int heap_rfirst(HP_INFO *info, uchar *record, int inx)
DBUG_ENTER("heap_rfirst"); DBUG_ENTER("heap_rfirst");
info->lastinx= inx; info->lastinx= inx;
info->key_version= info->s->key_version;
if (keyinfo->algorithm == HA_KEY_ALG_BTREE) if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
{ {
uchar *pos; uchar *pos;
...@@ -57,15 +59,8 @@ int heap_rfirst(HP_INFO *info, uchar *record, int inx) ...@@ -57,15 +59,8 @@ int heap_rfirst(HP_INFO *info, uchar *record, int inx)
} }
else else
{ {
if (!(info->s->records)) /* We can't scan a non existing key value with hash index */
{ my_errno= HA_ERR_WRONG_COMMAND;
my_errno=HA_ERR_END_OF_FILE; DBUG_RETURN(my_errno);
DBUG_RETURN(my_errno);
}
DBUG_ASSERT(0); /* TODO fix it */
info->current_record=0;
info->current_hash_ptr=0;
info->update=HA_STATE_PREV_FOUND;
DBUG_RETURN(heap_rnext(info,record));
} }
} }
...@@ -30,6 +30,7 @@ int heap_rkey(HP_INFO *info, uchar *record, int inx, const uchar *key, ...@@ -30,6 +30,7 @@ int heap_rkey(HP_INFO *info, uchar *record, int inx, const uchar *key,
} }
info->lastinx= inx; info->lastinx= inx;
info->current_record= (ulong) ~0L; /* For heap_rrnd() */ info->current_record= (ulong) ~0L; /* For heap_rrnd() */
info->key_version= info->s->key_version;
if (keyinfo->algorithm == HA_KEY_ALG_BTREE) if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
{ {
......
...@@ -25,6 +25,7 @@ int heap_rlast(HP_INFO *info, uchar *record, int inx) ...@@ -25,6 +25,7 @@ int heap_rlast(HP_INFO *info, uchar *record, int inx)
DBUG_ENTER("heap_rlast"); DBUG_ENTER("heap_rlast");
info->lastinx= inx; info->lastinx= inx;
info->key_version= info->s->key_version;
if (keyinfo->algorithm == HA_KEY_ALG_BTREE) if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
{ {
uchar *pos; uchar *pos;
...@@ -47,9 +48,8 @@ int heap_rlast(HP_INFO *info, uchar *record, int inx) ...@@ -47,9 +48,8 @@ int heap_rlast(HP_INFO *info, uchar *record, int inx)
} }
else else
{ {
info->current_ptr=0; /* We can't scan a non existing key value with hash index */
info->current_hash_ptr=0; my_errno= HA_ERR_WRONG_COMMAND;
info->update=HA_STATE_NEXT_FOUND; DBUG_RETURN(my_errno);
DBUG_RETURN(heap_rprev(info,record));
} }
} }
...@@ -70,6 +70,7 @@ int heap_rnext(HP_INFO *info, uchar *record) ...@@ -70,6 +70,7 @@ int heap_rnext(HP_INFO *info, uchar *record)
custom_arg.keyseg = keyinfo->seg; custom_arg.keyseg = keyinfo->seg;
custom_arg.key_length = info->lastkey_len; custom_arg.key_length = info->lastkey_len;
custom_arg.search_flag = SEARCH_SAME | SEARCH_FIND; custom_arg.search_flag = SEARCH_SAME | SEARCH_FIND;
info->last_find_flag= HA_READ_KEY_OR_NEXT;
pos = tree_search_key(&keyinfo->rb_tree, info->lastkey, info->parents, pos = tree_search_key(&keyinfo->rb_tree, info->lastkey, info->parents,
&info->last_pos, info->last_find_flag, &custom_arg); &info->last_pos, info->last_find_flag, &custom_arg);
} }
......
...@@ -41,6 +41,7 @@ int heap_rprev(HP_INFO *info, uchar *record) ...@@ -41,6 +41,7 @@ int heap_rprev(HP_INFO *info, uchar *record)
custom_arg.keyseg = keyinfo->seg; custom_arg.keyseg = keyinfo->seg;
custom_arg.key_length = keyinfo->length; custom_arg.key_length = keyinfo->length;
custom_arg.search_flag = SEARCH_SAME; custom_arg.search_flag = SEARCH_SAME;
info->last_find_flag= HA_READ_KEY_OR_PREV;
pos = tree_search_key(&keyinfo->rb_tree, info->lastkey, info->parents, pos = tree_search_key(&keyinfo->rb_tree, info->lastkey, info->parents,
&info->last_pos, info->last_find_flag, &custom_arg); &info->last_pos, info->last_find_flag, &custom_arg);
} }
......
...@@ -31,6 +31,8 @@ int heap_scan_init(register HP_INFO *info) ...@@ -31,6 +31,8 @@ int heap_scan_init(register HP_INFO *info)
info->current_record= (ulong) ~0L; /* No current record */ info->current_record= (ulong) ~0L; /* No current record */
info->update=0; info->update=0;
info->next_block=0; info->next_block=0;
info->key_version= info->s->key_version;
info->file_version= info->s->file_version;
DBUG_RETURN(0); DBUG_RETURN(0);
} }
......
...@@ -21,7 +21,7 @@ int heap_update(HP_INFO *info, const uchar *old, const uchar *heap_new) ...@@ -21,7 +21,7 @@ int heap_update(HP_INFO *info, const uchar *old, const uchar *heap_new)
{ {
HP_KEYDEF *keydef, *end, *p_lastinx; HP_KEYDEF *keydef, *end, *p_lastinx;
uchar *pos; uchar *pos;
my_bool auto_key_changed= 0; my_bool auto_key_changed= 0, key_changed= 0;
HP_SHARE *share= info->s; HP_SHARE *share= info->s;
DBUG_ENTER("heap_update"); DBUG_ENTER("heap_update");
...@@ -54,6 +54,8 @@ int heap_update(HP_INFO *info, const uchar *old, const uchar *heap_new) ...@@ -54,6 +54,8 @@ int heap_update(HP_INFO *info, const uchar *old, const uchar *heap_new)
#endif #endif
if (auto_key_changed) if (auto_key_changed)
heap_update_auto_increment(info, heap_new); heap_update_auto_increment(info, heap_new);
if (key_changed)
share->key_version++;
DBUG_RETURN(0); DBUG_RETURN(0);
err: err:
......
...@@ -56,6 +56,7 @@ int heap_write(HP_INFO *info, const uchar *record) ...@@ -56,6 +56,7 @@ int heap_write(HP_INFO *info, const uchar *record)
pos[share->reclength]=1; /* Mark record as not deleted */ pos[share->reclength]=1; /* Mark record as not deleted */
if (++share->records == share->blength) if (++share->records == share->blength)
share->blength+= share->blength; share->blength+= share->blength;
info->s->key_version++;
info->current_ptr=pos; info->current_ptr=pos;
info->current_hash_ptr=0; info->current_hash_ptr=0;
info->update|=HA_STATE_AKTIV; info->update|=HA_STATE_AKTIV;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment