List:Commits« Previous MessageNext Message »
From:Sergey Petrunia Date:September 28 2007 1:03pm
Subject:bk commit into 5.2 tree (sergefp:1.2597)
View as plain text  
Below is the list of changes that have just been committed into a local
5.2 repository of psergey. When psergey does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-09-28 17:03:45+04:00, sergefp@stripped +9 -0
  BUG30622: ORDER BY on a SELECT causes results to be missed
  - Added DsMrr_impl::call_position_for which tells whether the position() call is made
    to the primary or to the secondary table handler.
  - Made MyISAM and InnoDB to use call_position_for.
  - Removed deadcode and redundant DsMrr_impl members.

  mysql-test/r/innodb_mrr.result@stripped, 2007-09-28 17:03:41+04:00, sergefp@stripped +51 -1
    BUG30622: ORDER BY on a SELECT causes results to be missed
    - Testcase

  mysql-test/r/myisam_mrr.result@stripped, 2007-09-28 17:03:41+04:00, sergefp@stripped +28 -0
    BUG30622: ORDER BY on a SELECT causes results to be missed
    - Testcase

  mysql-test/t/innodb_mrr.test@stripped, 2007-09-28 17:03:41+04:00, sergefp@stripped +48 -1
    BUG30622: ORDER BY on a SELECT causes results to be missed
    - Testcase

  mysql-test/t/myisam_mrr.test@stripped, 2007-09-28 17:03:41+04:00, sergefp@stripped +29 -0
    BUG30622: ORDER BY on a SELECT causes results to be missed
    - Testcase

  sql/handler.cc@stripped, 2007-09-28 17:03:41+04:00, sergefp@stripped +27 -49
    BUG30622: ORDER BY on a SELECT causes results to be missed
    - Added DsMrr_impl::call_position_for which tells whether the position() call is made
      to the primary or to the secondary table handler.
    - Removed deadcode and redundant DsMrr_impl members.

  sql/handler.h@stripped, 2007-09-28 17:03:41+04:00, sergefp@stripped +43 -23
    BUG30622: ORDER BY on a SELECT causes results to be missed
    - Added DsMrr_impl::call_position_for which tells whether the position() call is made
      to the primary or to the secondary table handler.
    - Removed deadcode and redundant DsMrr_impl members.

  storage/innobase/handler/ha_innodb.cc@stripped, 2007-09-28 17:03:41+04:00, sergefp@stripped +8 -4
    BUG30622: ORDER BY on a SELECT causes results to be missed
    - Let ::position() use the new DsMrr_impl::call_position_for member

  storage/myisam/ha_myisam.cc@stripped, 2007-09-28 17:03:41+04:00, sergefp@stripped +11 -4
    BUG30622: ORDER BY on a SELECT causes results to be missed
    - Let ::position() use the new DsMrr_impl::call_position_for member

  storage/myisam/ha_myisam.h@stripped, 2007-09-28 17:03:41+04:00, sergefp@stripped +1 -0
    BUG30622: ORDER BY on a SELECT causes results to be missed
    - Let ::position() use the new DsMrr_impl::call_position_for member

diff -Nrup a/mysql-test/r/innodb_mrr.result b/mysql-test/r/innodb_mrr.result
--- a/mysql-test/r/innodb_mrr.result	2007-03-10 00:08:20 +03:00
+++ b/mysql-test/r/innodb_mrr.result	2007-09-28 17:03:41 +04:00
@@ -297,5 +297,55 @@ insert into t2 select A.a, B.a, B.a, A.a
 explain select * from t2 force index (d) where d < 10;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	SIMPLE	t2	range	d	d	5	NULL	47	Using index condition; Using MRR
-drop table t2;
+drop table t1, t2;
 set @@read_rnd_buffer_size= @read_rnd_buffer_size_save;
+CREATE TABLE t1 (
+ID int(10) unsigned NOT NULL AUTO_INCREMENT,
+col1 int(10) unsigned DEFAULT NULL,
+key1 int(10) unsigned NOT NULL DEFAULT '0',
+key2 int(10) unsigned DEFAULT NULL,
+text1 text,
+text2 text,
+col2 smallint(6) DEFAULT '100',
+col3 enum('headers','bodyandsubject') NOT NULL DEFAULT 'bodyandsubject',
+col4 tinyint(3) unsigned NOT NULL DEFAULT '0',
+PRIMARY KEY (ID),
+KEY (key1),
+KEY (key2)
+) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
+INSERT INTO t1 VALUES
+(1,NULL,1130,NULL,'Hello',NULL,100,'bodyandsubject',0),
+(2,NULL,1130,NULL,'bye',NULL,100,'bodyandsubject',0),
+(3,NULL,1130,NULL,'red',NULL,100,'bodyandsubject',0),
+(4,NULL,1130,NULL,'yellow',NULL,100,'bodyandsubject',0),
+(5,NULL,1130,NULL,'blue',NULL,100,'bodyandsubject',0);
+select * FROM t1 WHERE key1=1130 AND col1 IS NULL;
+ID	col1	key1	key2	text1	text2	col2	col3	col4
+1	NULL	1130	NULL	Hello	NULL	100	bodyandsubject	0
+2	NULL	1130	NULL	bye	NULL	100	bodyandsubject	0
+3	NULL	1130	NULL	red	NULL	100	bodyandsubject	0
+4	NULL	1130	NULL	yellow	NULL	100	bodyandsubject	0
+5	NULL	1130	NULL	blue	NULL	100	bodyandsubject	0
+CREATE TABLE t2 (
+ID int(10) unsigned NOT NULL AUTO_INCREMENT,
+col1 int(10) unsigned DEFAULT NULL,
+key1 int(10) unsigned NOT NULL DEFAULT '0',
+key2 int(10) unsigned DEFAULT NULL,
+text1 text,
+text2 text,
+col2 smallint(6) DEFAULT '100',
+col3 enum('headers','bodyandsubject') NOT NULL DEFAULT 'bodyandsubject',
+col4 tinyint(3) unsigned NOT NULL DEFAULT '0',
+KEY (ID),
+KEY (key1),
+KEY (key2)
+) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
+insert into t2 select * from t1;
+select * FROM t2 WHERE key1=1130 AND col1 IS NULL;
+ID	col1	key1	key2	text1	text2	col2	col3	col4
+1	NULL	1130	NULL	Hello	NULL	100	bodyandsubject	0
+2	NULL	1130	NULL	bye	NULL	100	bodyandsubject	0
+3	NULL	1130	NULL	red	NULL	100	bodyandsubject	0
+4	NULL	1130	NULL	yellow	NULL	100	bodyandsubject	0
+5	NULL	1130	NULL	blue	NULL	100	bodyandsubject	0
+drop table t1, t2;
diff -Nrup a/mysql-test/r/myisam_mrr.result b/mysql-test/r/myisam_mrr.result
--- a/mysql-test/r/myisam_mrr.result	2007-03-10 00:08:20 +03:00
+++ b/mysql-test/r/myisam_mrr.result	2007-09-28 17:03:41 +04:00
@@ -275,3 +275,31 @@ bb-1	NULL	cc-2	NULL-2
 bb-1	NULL	cc-2	NULL-1
 set @@read_rnd_buffer_size= @read_rnd_buffer_size_save;
 drop table t1, t2, t3, t4;
+CREATE TABLE t1 (
+ID int(10) unsigned NOT NULL AUTO_INCREMENT,
+col1 int(10) unsigned DEFAULT NULL,
+key1 int(10) unsigned NOT NULL DEFAULT '0',
+key2 int(10) unsigned DEFAULT NULL,
+text1 text,
+text2 text,
+col2 smallint(6) DEFAULT '100',
+col3 enum('headers','bodyandsubject') NOT NULL DEFAULT 'bodyandsubject',
+col4 tinyint(3) unsigned NOT NULL DEFAULT '0',
+PRIMARY KEY (ID),
+KEY (key1),
+KEY (key2)
+) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
+INSERT INTO t1 VALUES
+(1,NULL,1130,NULL,'Hello',NULL,100,'bodyandsubject',0),
+(2,NULL,1130,NULL,'bye',NULL,100,'bodyandsubject',0),
+(3,NULL,1130,NULL,'red',NULL,100,'bodyandsubject',0),
+(4,NULL,1130,NULL,'yellow',NULL,100,'bodyandsubject',0),
+(5,NULL,1130,NULL,'blue',NULL,100,'bodyandsubject',0);
+select * FROM t1 WHERE key1=1130 AND col1 IS NULL;
+ID	col1	key1	key2	text1	text2	col2	col3	col4
+1	NULL	1130	NULL	Hello	NULL	100	bodyandsubject	0
+2	NULL	1130	NULL	bye	NULL	100	bodyandsubject	0
+3	NULL	1130	NULL	red	NULL	100	bodyandsubject	0
+4	NULL	1130	NULL	yellow	NULL	100	bodyandsubject	0
+5	NULL	1130	NULL	blue	NULL	100	bodyandsubject	0
+drop table t1;
diff -Nrup a/mysql-test/t/innodb_mrr.test b/mysql-test/t/innodb_mrr.test
--- a/mysql-test/t/innodb_mrr.test	2007-03-10 00:08:20 +03:00
+++ b/mysql-test/t/innodb_mrr.test	2007-09-28 17:03:41 +04:00
@@ -41,7 +41,54 @@ create table t2 (a char(100), b char(100
                  filler char(10), key(d), primary key (a,b,c)) engine= innodb;
 insert into t2 select A.a, B.a, B.a, A.a, 'filler' from t1 A, t1 B;
 explain select * from t2 force index (d) where d < 10;
-drop table t2;
+drop table t1, t2;
 
 set @@read_rnd_buffer_size= @read_rnd_buffer_size_save;
+#
+# BUG#30622: Incorrect query results for MRR + filesort
+# 
+CREATE TABLE t1 (
+  ID int(10) unsigned NOT NULL AUTO_INCREMENT,
+  col1 int(10) unsigned DEFAULT NULL,
+  key1 int(10) unsigned NOT NULL DEFAULT '0',
+  key2 int(10) unsigned DEFAULT NULL,
+  text1 text,
+  text2 text,
+  col2 smallint(6) DEFAULT '100',
+  col3 enum('headers','bodyandsubject') NOT NULL DEFAULT 'bodyandsubject',
+  col4 tinyint(3) unsigned NOT NULL DEFAULT '0',
+  PRIMARY KEY (ID),
+  KEY (key1),
+  KEY (key2)
+) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
+
+INSERT INTO t1 VALUES
+(1,NULL,1130,NULL,'Hello',NULL,100,'bodyandsubject',0),
+(2,NULL,1130,NULL,'bye',NULL,100,'bodyandsubject',0),
+(3,NULL,1130,NULL,'red',NULL,100,'bodyandsubject',0),
+(4,NULL,1130,NULL,'yellow',NULL,100,'bodyandsubject',0),
+(5,NULL,1130,NULL,'blue',NULL,100,'bodyandsubject',0);
+
+select * FROM t1 WHERE key1=1130 AND col1 IS NULL;
+
+CREATE TABLE t2 (
+  ID int(10) unsigned NOT NULL AUTO_INCREMENT,
+  col1 int(10) unsigned DEFAULT NULL,
+  key1 int(10) unsigned NOT NULL DEFAULT '0',
+  key2 int(10) unsigned DEFAULT NULL,
+  text1 text,
+  text2 text,
+  col2 smallint(6) DEFAULT '100',
+  col3 enum('headers','bodyandsubject') NOT NULL DEFAULT 'bodyandsubject',
+  col4 tinyint(3) unsigned NOT NULL DEFAULT '0',
+  KEY (ID),
+  KEY (key1),
+  KEY (key2)
+) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
+insert into t2 select * from t1;
+
+select * FROM t2 WHERE key1=1130 AND col1 IS NULL;
+
+drop table t1, t2;
+
 
diff -Nrup a/mysql-test/t/myisam_mrr.test b/mysql-test/t/myisam_mrr.test
--- a/mysql-test/t/myisam_mrr.test	2007-03-10 00:08:20 +03:00
+++ b/mysql-test/t/myisam_mrr.test	2007-09-28 17:03:41 +04:00
@@ -16,3 +16,32 @@ set @@read_rnd_buffer_size= @read_rnd_bu
 
 drop table t1, t2, t3, t4;
 
+#
+# BUG#30622: Incorrect query results for MRR + filesort
+# 
+CREATE TABLE t1 (
+  ID int(10) unsigned NOT NULL AUTO_INCREMENT,
+  col1 int(10) unsigned DEFAULT NULL,
+  key1 int(10) unsigned NOT NULL DEFAULT '0',
+  key2 int(10) unsigned DEFAULT NULL,
+  text1 text,
+  text2 text,
+  col2 smallint(6) DEFAULT '100',
+  col3 enum('headers','bodyandsubject') NOT NULL DEFAULT 'bodyandsubject',
+  col4 tinyint(3) unsigned NOT NULL DEFAULT '0',
+  PRIMARY KEY (ID),
+  KEY (key1),
+  KEY (key2)
+) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
+
+INSERT INTO t1 VALUES
+(1,NULL,1130,NULL,'Hello',NULL,100,'bodyandsubject',0),
+(2,NULL,1130,NULL,'bye',NULL,100,'bodyandsubject',0),
+(3,NULL,1130,NULL,'red',NULL,100,'bodyandsubject',0),
+(4,NULL,1130,NULL,'yellow',NULL,100,'bodyandsubject',0),
+(5,NULL,1130,NULL,'blue',NULL,100,'bodyandsubject',0);
+
+select * FROM t1 WHERE key1=1130 AND col1 IS NULL;
+
+drop table t1;
+
diff -Nrup a/sql/handler.cc b/sql/handler.cc
--- a/sql/handler.cc	2007-09-21 19:23:13 +04:00
+++ b/sql/handler.cc	2007-09-28 17:03:41 +04:00
@@ -3363,39 +3363,7 @@ int handler::multi_range_read_next(char 
     /* Save a call if there can be only one row in range. */
     if (mrr_cur_range.range_flag != (UNIQUE_RANGE | EQ_RANGE))
     {
-#if 0      
-      if (mrr_restore_scan)
-      {
-        result= mrr_restore_scan_res;
-        if (!result)
-          result= (compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE);
-        else
-        {
-          if (result == HA_ERR_KEY_NOT_FOUND)
-            result= HA_ERR_END_OF_FILE;
-        }
-        mrr_restore_scan= FALSE;
-        if (!result)
-        {
-          /*
-            Continue as if we're scanning a generic (i.e. not necessarily
-            equality) range. The point is that if we're in the middle of
-            equality range, we can't continue scanning it as equality range.
-            The call sequence is:
-              file->index_read( ... , HA_READ_KEY_EXACT);
-              file->index_next_same(...)
-              ...
-              file->index_read(..., HA_READ_AFTER_KEY) // restore the scan
-            That is, the "restore the scan" call has interrupted the
-            equality range and we can't use index_next_same() anymore.
-          */
-          eq_range= FALSE; 
-        }
-      }
-      else
-#endif      
-        result= read_range_next();
-
+      result= read_range_next();
       /* On success or non-EOF errors jump to the end. */
       if (result != HA_ERR_END_OF_FILE)
         break;
@@ -3463,17 +3431,17 @@ int DsMrr_impl::dsmrr_init(handler *h, K
 {
   int res;
   uint elem_size;
+  uint keyno;
   DBUG_ENTER("DsMrr_impl::dsmrr_init");
+  keyno= h->active_index;
   if (mode & HA_MRR_USE_DEFAULT_IMPL || mode & HA_MRR_SORTED)
   {
     use_default_impl= TRUE;
     DBUG_RETURN(h->handler::multi_range_read_init(seq_funcs, seq_init_param,
                                                   n_ranges, mode, buf));
   }
-  use_default_impl= FALSE;
   
   rowids_buf= buf->buffer;
-  last_idx_tuple= rowids_buf;
   rowids_buf += key->key_length + h->ref_length;
 
   is_mrr_assoc= !test(mode & HA_MRR_NO_ASSOCIATION);
@@ -3488,11 +3456,6 @@ int DsMrr_impl::dsmrr_init(handler *h, K
                                          mode, buf);
   DBUG_ASSERT(!res);
 
-  mrr_key= key;
-  mrr_keyno= h->active_index;
-  //h->mrr_restore_scan= FALSE;
-  /* h->mrr_restore_scan_res needs no initialization */
-  
   /* Create a separate handler object to do rndpos() calls. */
   THD *thd= current_thd;
   if (!(h2= h->clone(thd->mem_root)) || h2->ha_external_lock(thd, F_RDLCK))
@@ -3515,8 +3478,14 @@ int DsMrr_impl::dsmrr_init(handler *h, K
  
   h->table->key_read= TRUE;
   h->table->prepare_for_position();
-  h->table->mark_columns_used_by_index_no_reset(mrr_keyno, h->table->read_set);
-  if (h->index_init(mrr_keyno, FALSE) || dsmrr_fill_buffer(h))
+  h->table->mark_columns_used_by_index_no_reset(keyno, h->table->read_set);
+
+  if (h->index_init(keyno, FALSE))
+    goto error;
+
+  use_default_impl= FALSE;
+  
+  if (dsmrr_fill_buffer(h))
     goto error;
 
   /*
@@ -3530,7 +3499,9 @@ int DsMrr_impl::dsmrr_init(handler *h, K
                                          &row_access_bitmap);
   if (h2->rnd_init(FALSE))
     goto error;
-
+  
+  /* Prepare for position() calls on the primary object */
+  call_position_for= h2;
   DBUG_RETURN(0);
 error:
   h2->ha_external_lock(thd, F_UNLCK);
@@ -3544,14 +3515,19 @@ error:
 void DsMrr_impl::dsmrr_close()
 {
   DBUG_ENTER("DsMrr_impl::dsmrr_close");
-  if (h2)
+  if (!use_default_impl)
   {
-    h2->ha_external_lock(current_thd, F_UNLCK);
-    h2->close();
-    delete h2;
-    h2= NULL;
+    if (h2)
+    {
+      h2->ha_external_lock(current_thd, F_UNLCK);
+      h2->close();
+      delete h2;
+      h2= NULL;
+    }
+    h->table->column_bitmaps_set(save_read_set, save_write_set);
+    use_default_impl= TRUE;
+    call_position_for= h;
   }
-  h->table->column_bitmaps_set(save_read_set, save_write_set);
   DBUG_VOID_RETURN;
 }
 
@@ -3640,7 +3616,9 @@ int DsMrr_impl::dsmrr_next(handler *h, c
       goto end;
     }
 
+    call_position_for= h;
     res= dsmrr_fill_buffer(h);
+    call_position_for= h2;
     h->table->column_bitmaps_set_no_signal(&row_access_bitmap,
                                            &row_access_bitmap);
     if (res)
diff -Nrup a/sql/handler.h b/sql/handler.h
--- a/sql/handler.h	2007-09-14 13:20:43 +04:00
+++ b/sql/handler.h	2007-09-28 17:03:41 +04:00
@@ -1217,10 +1217,6 @@ public:
   /* Current range (the one we're now returning rows from) */
   KEY_MULTI_RANGE mrr_cur_range;
   
-  /* Default MRR implementation: */
-  //bool mrr_restore_scan; /* TRUE <=> we're restoring the scan */
-  //int mrr_restore_scan_res; /* iff mrr_restore_scan: return value of next call */
-
   /* The following are for read_range() */
   key_range save_end_range, *end_range;
   KEY_PART_INFO *range_key_part;
@@ -1268,7 +1264,7 @@ public:
   handler(handlerton *ht_arg, TABLE_SHARE *share_arg)
     :table_share(share_arg), table(0),
     estimation_rows_to_insert(0), ht(ht_arg),
-    ref(0), /*mrr_restore_scan(FALSE), */ in_range_check_pushed_down(FALSE),
+    ref(0), in_range_check_pushed_down(FALSE),
     key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
     ref_length(sizeof(my_off_t)),
     ft_handler(0), inited(NONE),
@@ -2175,34 +2171,58 @@ class DsMrr_impl
 public:
   typedef void (handler::*range_check_toggle_func_t)(bool on);
 
-  DsMrr_impl(range_check_toggle_func_t func)
-    : last_idx_tuple(NULL), range_check_toggle_func(func) {};
+  DsMrr_impl()
+    : use_default_impl(TRUE) {};
+
+  handler *h; /* The "owner" handler object. It is used for scanning the index */
+  
+  /*
+    Needed in h->position():
+    The owner handler object will get two kinds of ::position() calls 
+      - "Normal" calls which retrieve the current position of that handler. 
+        Those calls are made
+         = by SQL layer when doing a non-DS-MRR scan
+         = by DS-MRR when it accumulates record rowids
+
+      - Calls that need to return position of the "Slave" handler object
+        (which was created from the primary with ::clone() call. 
+        Those are the calls that are made by SQL-layer during a DS-MRR scan.
+  */
+  handler *call_position_for;
+private:
+  /*
+    Secondary handler object. It is used to retrieve full table rows by
+    calling rnd_pos().
+  */
+  handler *h2;
 
-  uchar *rowids_buf;       /* ROWIDs buffer */
+  /* Buffer to store rowids, or (rowid, range_id) pairs */
+  uchar *rowids_buf;
   uchar *rowids_buf_cur;   /* Current position when reading/writing */
-  uchar *rowids_buf_last;  /* Wen reading: end of used buffer space */
+  uchar *rowids_buf_last;  /* When reading: end of used buffer space */
   uchar *rowids_buf_end;   /* End of the buffer */
-  
-  KEY  *mrr_key;           /* Index to use */
-  uint mrr_keyno;          /* Number of the index */
 
-  uchar *last_idx_tuple; //TODO: remove 
-  bool dsmrr_eof;        //TODO: remove 
+  bool dsmrr_eof; /* TRUE <=> We have reached EOF when reading index tuples */
 
   /* TRUE <=> need range association, buffer holds {rowid, range_id} pairs */
-  bool is_mrr_assoc; 
+  bool is_mrr_assoc;
 
-  handler *h; /* Owner table handler */
-  handler *h2; /* Slave handler for doing rnd_pos(). */
-   
-  /* Bitmaps for the rnd_pos()-calling handler object */
+  /*
+    Column bitmaps to be used with slave handler object. Those are necessary
+    as we set primary handler object's bitmap to contain index columns only.
+  */
   MY_BITMAP row_access_bitmap;
   MY_BITMAP *save_read_set, *save_write_set;
-
-  bool use_default_impl; /* TRUE <=> shortcut the calls to default MRR impl */
+  
+  bool use_default_impl; /* TRUE <=> shortcut all calls to default MRR impl */
+  
   range_check_toggle_func_t range_check_toggle_func;
-
-
+public:
+  void init(handler *h_arg, range_check_toggle_func_t func_arg)
+  {
+    h= call_position_for= h_arg; 
+    range_check_toggle_func= func_arg;
+  }
   int dsmrr_init(handler *h, KEY *key, RANGE_SEQ_IF *seq_funcs, 
                  void *seq_init_param, uint n_ranges, uint mode, 
                  HANDLER_BUFFER *buf);
diff -Nrup a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
--- a/storage/innobase/handler/ha_innodb.cc	2007-09-21 14:42:32 +04:00
+++ b/storage/innobase/handler/ha_innodb.cc	2007-09-28 17:03:41 +04:00
@@ -990,11 +990,10 @@ ha_innobase::ha_innobase(handlerton *hto
                      HA_DO_INDEX_COND_PUSHDOWN bit from those "early" calls */
   start_of_scan(0),
   num_write_row(0),
-  ds_mrr((DsMrr_impl::range_check_toggle_func_t)
-         &ha_innobase::toggle_range_check),
   cond_keyno(MAX_KEY)
 {
-  ds_mrr.h= this;
+  ds_mrr.init(this, (DsMrr_impl::range_check_toggle_func_t)
+                     &ha_innobase::toggle_range_check);
 }
 
 /*************************************************************************
@@ -4000,7 +3999,8 @@ ha_innobase::index_end(void)
 	int	error	= 0;
 	DBUG_ENTER("index_end");
 	active_index=MAX_KEY;
-        in_range_check_pushed_down= FALSE;
+	in_range_check_pushed_down= FALSE;
+	ds_mrr.dsmrr_close();
 	DBUG_RETURN(error);
 }
 
@@ -4590,6 +4590,10 @@ ha_innobase::position(
 
 	ut_a(prebuilt->trx == thd_to_trx(ha_thd()));
 
+        if (ds_mrr.call_position_for != this) {
+                ((ha_innobase*)ds_mrr.call_position_for)->position(record);
+                return;
+        }
 	if (prebuilt->clust_index_was_generated) {
 		/* No primary key was defined for the table and we
 		generated the clustered index from row id: the
diff -Nrup a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
--- a/storage/myisam/ha_myisam.cc	2007-09-21 14:42:33 +04:00
+++ b/storage/myisam/ha_myisam.cc	2007-09-28 17:03:41 +04:00
@@ -489,10 +489,10 @@ ha_myisam::ha_myisam(handlerton *hton, T
                   HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT |
                   HA_NEED_READ_RANGE_BUFFER | HA_MRR_CANT_SORT),
    can_enable_indexes(1),
-   cond_keyno(MAX_KEY),
-   ds_mrr((DsMrr_impl::range_check_toggle_func_t)&ha_myisam::toggle_range_check)
+   cond_keyno(MAX_KEY)
 {
-  ds_mrr.h= this;
+  ds_mrr.init(this, (DsMrr_impl::range_check_toggle_func_t)
+                    &ha_myisam::toggle_range_check);
 }
 
 handler *ha_myisam::clone(MEM_ROOT *mem_root)
@@ -1432,6 +1432,7 @@ int ha_myisam::index_end()
   active_index=MAX_KEY;
   mi_set_index_cond_func(file, NULL, 0);
   in_range_check_pushed_down= FALSE;
+  ds_mrr.dsmrr_close();
   return 0; 
 }
 
@@ -1570,10 +1571,16 @@ int ha_myisam::rnd_pos(uchar *buf, uchar
   return error;
 }
 
-void ha_myisam::position(const uchar *record)
+void ha_myisam::position_impl(const uchar *record)
 {
   my_off_t row_position= mi_position(file);
   my_store_ptr(ref, ref_length, row_position);
+}
+
+void ha_myisam::position(const uchar *record)
+{
+  ((ha_myisam*)ds_mrr.call_position_for)->position_impl(record);
+  //psergey! ((ds_mrr.use_default_impl)? this: (ha_myisam*)ds_mrr.h2)->position_impl(record);
 }
 
 int ha_myisam::info(uint flag)
diff -Nrup a/storage/myisam/ha_myisam.h b/storage/myisam/ha_myisam.h
--- a/storage/myisam/ha_myisam.h	2007-08-26 15:31:22 +04:00
+++ b/storage/myisam/ha_myisam.h	2007-09-28 17:03:41 +04:00
@@ -172,6 +172,7 @@ private:
   {
     in_range_read= on;
   }
+  void position_impl(const uchar *record);
   friend my_bool index_cond_func_myisam(void *arg);
 };
 
Thread
bk commit into 5.2 tree (sergefp:1.2597)Sergey Petrunia28 Sep