Below is the list of changes that have just been committed into a local
6.0 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, 2008-01-11 01:04:59+03:00, sergefp@stripped +17 -0
BUG#30622: ORDER BY on a SELECT causes results to be missed
- Restore the original table condition if we've done index condition pushdown
for some index but later decided not to use it
- Remove outdated comments
mysql-test/r/grant2.result@stripped, 2008-01-11 01:04:52+03:00, sergefp@stripped +0 -6
BUG#30622: ORDER BY on a SELECT causes results to be missed
- Fix the wrong test results
mysql-test/r/index_merge_myisam.result@stripped, 2008-01-11 01:04:52+03:00, sergefp@stripped +3 -3
BUG#30622: ORDER BY on a SELECT causes results to be missed
- Fix the wrong test results
mysql-test/r/myisam_mrr.result@stripped, 2008-01-11 01:04:52+03:00, sergefp@stripped +28 -0
BUG#30622: ORDER BY on a SELECT causes results to be missed
- Testcases
mysql-test/r/order_by.result@stripped, 2008-01-11 01:04:52+03:00, sergefp@stripped +2 -2
BUG#30622: ORDER BY on a SELECT causes results to be missed
- Update test results
mysql-test/t/disabled.def@stripped, 2008-01-11 01:04:52+03:00, sergefp@stripped +1 -1
BUG#30622: ORDER BY on a SELECT causes results to be missed
- Update test results
mysql-test/t/myisam_mrr.test@stripped, 2008-01-11 01:04:52+03:00, sergefp@stripped +29 -0
BUG#30622: ORDER BY on a SELECT causes results to be missed
- Testcases
sql/handler.cc@stripped, 2008-01-11 01:04:52+03:00, sergefp@stripped +73 -81
BUG#30622: ORDER BY on a SELECT causes results to be missed
- Change the DsMRR_impl: let it use the secondary object to do index scans
and primary object to do rnd_pos() calls. This allows the SQL layer to call
position() on the primary object.
- Remove outdated deadcode
sql/handler.h@stripped, 2008-01-11 01:04:52+03:00, sergefp@stripped +44 -33
BUG#30622: ORDER BY on a SELECT causes results to be missed
- Change the DsMRR_impl: let it use the secondary object to do index scans
and primary object to do rnd_pos() calls. This allows the SQL layer to call
position() on the primary object.
- Remove outdated deadcode
sql/opt_range.cc@stripped, 2008-01-11 01:04:52+03:00, sergefp@stripped +1 -1
BUG#30622: ORDER BY on a SELECT causes results to be missed
- Fix: pass multi_range_read_const() HA_MRR_USE_DEFAULT_IMPL flag if we're told
to use the default MRR implementation.
sql/set_var.cc@stripped, 2008-01-11 01:04:53+03:00, sergefp@stripped +0 -2
BUG#30622: ORDER BY on a SELECT causes results to be missed
- Remove garbage comments
sql/sql_select.cc@stripped, 2008-01-11 01:04:53+03:00, sergefp@stripped +7 -18
BUG#30622: ORDER BY on a SELECT causes results to be missed
- Restore the original table condition if we've done index condition pushdown
for some index but later decided not to use it
- Remove outdated comments
storage/innobase/handler/ha_innodb.cc@stripped, 2008-01-11 01:04:53+03:00, sergefp@stripped +37 -36
BUG#30622: ORDER BY on a SELECT causes results to be missed
- MRR variables moved to class handler
- Remove garbage comments
storage/innobase/handler/ha_innodb.h@stripped, 2008-01-11 01:04:53+03:00, sergefp@stripped +0 -18
BUG#30622: ORDER BY on a SELECT causes results to be missed
- MRR variables moved to class handler
- Remove garbage comments
storage/myisam/ha_myisam.cc@stripped, 2008-01-11 01:04:53+03:00, sergefp@stripped +29 -27
BUG#30622: ORDER BY on a SELECT causes results to be missed
- MRR variables moved to class handler
- Remove garbage comments
storage/myisam/ha_myisam.h@stripped, 2008-01-11 01:04:54+03:00, sergefp@stripped +0 -9
BUG#30622: ORDER BY on a SELECT causes results to be missed
- MRR variables moved to class handler
- Use the new DsMRR_impl use convention
storage/myisam/mi_key.c@stripped, 2008-01-11 01:04:54+03:00, sergefp@stripped +0 -30
BUG#30622: ORDER BY on a SELECT causes results to be missed
- Remove redundant deadcode
storage/myisam/mi_rkey.c@stripped, 2008-01-11 01:04:54+03:00, sergefp@stripped +0 -13
BUG#30622: ORDER BY on a SELECT causes results to be missed
- Remove redundant deadcode
diff -Nrup a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result
--- a/mysql-test/r/grant2.result 2007-10-04 14:37:03 +04:00
+++ b/mysql-test/r/grant2.result 2008-01-11 01:04:52 +03:00
@@ -148,9 +148,7 @@ host user password
% mysqltest_3 fffffffffffffffffffffffffffffffffffffffff
select host,db,user from mysql.db where user like 'mysqltest_%' order by host,db,user;
host db user
-% test
% test mysqltest_2
-% test\_%
select host,db,user,table_name from mysql.tables_priv where user like 'mysqltest_%' order by host,db,user,table_name;
host db user table_name
% test mysqltest_2 t1
@@ -174,9 +172,7 @@ host user password
% mysqltest_3 fffffffffffffffffffffffffffffffffffffffff
select host,db,user from mysql.db where user like 'mysqltest_%' order by host,db,user;
host db user
-% test
% test mysqltest_2
-% test\_%
select host,db,user,table_name from mysql.tables_priv where user like 'mysqltest_%' order by host,db,user,table_name;
host db user table_name
% test mysqltest_2 t1
@@ -193,9 +189,7 @@ host user password
% mysqltest_3 fffffffffffffffffffffffffffffffffffffffff
select host,db,user from mysql.db where user like 'mysqltest_%' order by host,db,user;
host db user
-% test
% test mysqltest_1
-% test\_%
select host,db,user,table_name from mysql.tables_priv where user like 'mysqltest_%' order by host,db,user,table_name;
host db user table_name
% test mysqltest_1 t1
diff -Nrup a/mysql-test/r/index_merge_myisam.result b/mysql-test/r/index_merge_myisam.result
--- a/mysql-test/r/index_merge_myisam.result 2007-12-02 07:19:17 +03:00
+++ b/mysql-test/r/index_merge_myisam.result 2008-01-11 01:04:52 +03:00
@@ -398,13 +398,13 @@ Table Op Msg_type Msg_text
test.t1 optimize status OK
select count(*) from t1;
count(*)
-41984
+8704
explain select * from t1 WHERE cola = 'foo' AND colb = 'bar';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 index_merge cola,colb cola,colb 3,3 NULL 7 Using intersect(cola,colb); Using where
+1 SIMPLE t1 index_merge cola,colb cola,colb 3,3 NULL 32 Using intersect(cola,colb); Using where
explain select * from t1 force index(cola,colb) WHERE cola = 'foo' AND colb = 'bar';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 index_merge cola,colb cola,colb 3,3 NULL 7 Using intersect(cola,colb); Using where
+1 SIMPLE t1 index_merge cola,colb cola,colb 3,3 NULL 32 Using intersect(cola,colb); Using where
drop table t1;
create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
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 2008-01-11 01:04:52 +03: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 ORDER BY text1;
+ID col1 key1 key2 text1 text2 col2 col3 col4
+5 NULL 1130 NULL blue NULL 100 bodyandsubject 0
+2 NULL 1130 NULL bye NULL 100 bodyandsubject 0
+1 NULL 1130 NULL Hello NULL 100 bodyandsubject 0
+3 NULL 1130 NULL red NULL 100 bodyandsubject 0
+4 NULL 1130 NULL yellow NULL 100 bodyandsubject 0
+drop table t1;
diff -Nrup a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result
--- a/mysql-test/r/order_by.result 2007-10-24 03:58:33 +04:00
+++ b/mysql-test/r/order_by.result 2008-01-11 01:04:52 +03:00
@@ -609,7 +609,7 @@ FieldKey LongVal StringVal
1 2 1
EXPLAIN SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY LongVal;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range FieldKey,LongField,StringField FieldKey 38 NULL 4 Using index condition; Using MRR; Using filesort
+1 SIMPLE t1 range FieldKey,LongField,StringField FieldKey 38 NULL 4 Using index condition; Using where; Using MRR; Using filesort
SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY LongVal;
FieldKey LongVal StringVal
3 1 2
@@ -1107,7 +1107,7 @@ id select_type table type possible_keys
1 SIMPLE t2 index k2 k3 5 NULL 73 Using where
EXPLAIN SELECT id,c3 FROM t2 WHERE c2 BETWEEN 20 AND 30 ORDER BY c3 LIMIT 4000;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range k2 k2 5 NULL 386 Using where; Using filesort
+1 SIMPLE t2 range k2 k2 5 NULL 386 Using index condition; Using where; Using MRR; Using filesort
SELECT id,c3 FROM t2 WHERE c2=11 ORDER BY c3 LIMIT 20;
id c3
6 14
diff -Nrup a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def
--- a/mysql-test/t/disabled.def 2007-12-12 11:14:04 +03:00
+++ b/mysql-test/t/disabled.def 2008-01-11 01:04:52 +03:00
@@ -15,7 +15,7 @@ user_limits : Bug#23921 random failu
concurrent_innodb : BUG#21579 2006-08-11 mleich innodb_concurrent random failures with varying differences
ctype_big5 : BUG#26711 2007-06-21 Lars Test has never worked on Double Whopper
-order_by : WL#2475: spetrunia producing ordered streams is not handled correctly
+##order_by : WL#2475: spetrunia producing ordered streams is not handled correctly
federated_transactions : Bug#29523 Transactions do not work
locktrans_innodb : Bug#29929 2007-07-20 ingo LOCK TABLES does not pre-lock tables used in triggers
rpl_locktrans_innodb : Bug#29929 2007-07-20 ingo LOCK TABLES does not pre-lock tables used in triggers
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 2008-01-11 01:04:52 +03: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 ORDER BY text1;
+
+drop table t1;
+
diff -Nrup a/sql/handler.cc b/sql/handler.cc
--- a/sql/handler.cc 2007-12-13 15:56:18 +03:00
+++ b/sql/handler.cc 2008-01-11 01:04:52 +03:00
@@ -3443,39 +3443,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;
@@ -3544,19 +3512,20 @@ int DsMrr_impl::dsmrr_init(handler *h, K
RANGE_SEQ_IF *seq_funcs, void *seq_init_param,
uint n_ranges, uint mode, HANDLER_BUFFER *buf)
{
- int res;
uint elem_size;
+ uint keyno;
+ Item *pushed_cond= NULL;
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;
+ //psergey-todo: don't add key_length as it is not needed anymore
rowids_buf += key->key_length + h->ref_length;
is_mrr_assoc= !test(mode & HA_MRR_NO_ASSOCIATION);
@@ -3567,15 +3536,7 @@ int DsMrr_impl::dsmrr_init(handler *h, K
((rowids_buf_end - rowids_buf)/ elem_size)*
elem_size;
rowids_buf_end= rowids_buf_last;
- res= h->handler::multi_range_read_init(seq_funcs, seq_init_param, n_ranges,
- 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))
@@ -3583,23 +3544,32 @@ int DsMrr_impl::dsmrr_init(handler *h, K
delete h2;
DBUG_RETURN(1);
}
-
my_bitmap_map *bmp_buf;
- if (!(bmp_buf= (my_bitmap_map*)thd->alloc(h->table->s->column_bitmap_size)))
+ if (!(bmp_buf= (my_bitmap_map*)thd->alloc(table->s->column_bitmap_size)))
goto error;
- bitmap_init(&row_access_bitmap, bmp_buf, h->table->s->fields, FALSE);
- bitmap_copy(&row_access_bitmap, h->table->read_set);
- save_read_set= h->table->read_set;
- save_write_set= h->table->write_set;
-
- if (h->index_end() || h->extra(HA_EXTRA_KEYREAD))
+ bitmap_init(&row_access_bitmap, bmp_buf, table->s->fields, FALSE);
+ bitmap_copy(&row_access_bitmap, table->read_set);
+ save_read_set= table->read_set;
+ save_write_set= table->write_set;
+
+ if (keyno == h->pushed_idx_cond_keyno)
+ pushed_cond= h->pushed_idx_cond;
+ if (h->ha_index_end())
goto error;
-
- 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))
+
+ table->prepare_for_position();
+ h2->extra(HA_EXTRA_KEYREAD);
+
+ if (h2->ha_index_init(keyno, FALSE) ||
+ h2->handler::multi_range_read_init(seq_funcs, seq_init_param, n_ranges,
+ mode, buf))
+ goto error;
+ use_default_impl= FALSE;
+
+ if (pushed_cond)
+ h2->idx_cond_push(keyno, pushed_cond);
+ if (dsmrr_fill_buffer(h2))
goto error;
/*
@@ -3609,17 +3579,18 @@ int DsMrr_impl::dsmrr_init(handler *h, K
if (dsmrr_eof)
buf->end_of_used_area= rowids_buf_last;
- h->table->column_bitmaps_set_no_signal(&row_access_bitmap,
+ table->column_bitmaps_set_no_signal(&row_access_bitmap,
&row_access_bitmap);
- if (h2->rnd_init(FALSE))
+ if (h->ha_rnd_init(FALSE))
goto error;
-
+
DBUG_RETURN(0);
error:
+ h2->ha_index_or_rnd_end();
h2->ha_external_lock(thd, F_UNLCK);
h2->close();
delete h2;
- h->table->column_bitmaps_set_no_signal(save_read_set, save_write_set);
+ table->column_bitmaps_set_no_signal(save_read_set, save_write_set);
DBUG_RETURN(1);
}
@@ -3627,14 +3598,18 @@ 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;
+ }
+ table->column_bitmaps_set(save_read_set, save_write_set);
+ use_default_impl= TRUE;
}
- h->table->column_bitmaps_set(save_read_set, save_write_set);
DBUG_VOID_RETURN;
}
@@ -3665,7 +3640,7 @@ static int rowid_cmp(void *h, uchar *a,
other - Error
*/
-int DsMrr_impl::dsmrr_fill_buffer(handler *h)
+int DsMrr_impl::dsmrr_fill_buffer(handler *unused)
{
char *range_info;
int res;
@@ -3673,11 +3648,11 @@ int DsMrr_impl::dsmrr_fill_buffer(handle
rowids_buf_cur= rowids_buf;
while ((rowids_buf_cur < rowids_buf_end) &&
- !(res= h->handler::multi_range_read_next(&range_info)))
+ !(res= h2->handler::multi_range_read_next(&range_info)))
{
/* Put rowid, or {rowid, range_id} pair into the buffer */
- h->position(h->table->record[0]);
- memcpy(rowids_buf_cur, h->ref, h->ref_length);
+ h2->position(table->record[0]);
+ memcpy(rowids_buf_cur, h2->ref, h2->ref_length);
rowids_buf_cur += h->ref_length;
if (is_mrr_assoc)
@@ -3716,7 +3691,7 @@ int DsMrr_impl::dsmrr_next(handler *h, c
if (rowids_buf_cur == rowids_buf_last)
{
- h->table->column_bitmaps_set_no_signal(save_read_set, save_write_set);
+ table->column_bitmaps_set_no_signal(save_read_set, save_write_set);
if (dsmrr_eof)
{
res= HA_ERR_END_OF_FILE;
@@ -3724,7 +3699,8 @@ int DsMrr_impl::dsmrr_next(handler *h, c
}
res= dsmrr_fill_buffer(h);
- h->table->column_bitmaps_set_no_signal(&row_access_bitmap,
+
+ table->column_bitmaps_set_no_signal(&row_access_bitmap,
&row_access_bitmap);
if (res)
goto end;
@@ -3737,7 +3713,7 @@ int DsMrr_impl::dsmrr_next(handler *h, c
goto end;
}
- res= h2->rnd_pos(h->table->record[0], rowids_buf_cur);
+ res= h->rnd_pos(table->record[0], rowids_buf_cur);
rowids_buf_cur += h->ref_length;
if (is_mrr_assoc)
{
@@ -3848,8 +3824,8 @@ ha_rows DsMrr_impl::dsmrr_info_const(uin
bool DsMrr_impl::key_uses_partial_cols(uint keyno)
{
- KEY_PART_INFO *kp= h->table->key_info[keyno].key_part;
- KEY_PART_INFO *kp_end= kp + h->table->key_info[keyno].key_parts;
+ KEY_PART_INFO *kp= table->key_info[keyno].key_part;
+ KEY_PART_INFO *kp_end= kp + table->key_info[keyno].key_parts;
for (; kp != kp_end; kp++)
{
if (!kp->field->part_of_key.is_set(keyno))
@@ -3894,7 +3870,7 @@ bool DsMrr_impl::choose_mrr_impl(uint ke
THD *thd= current_thd;
if ((thd->variables.optimizer_use_mrr == 2) ||
(*flags & HA_MRR_INDEX_ONLY) || (*flags & HA_MRR_SORTED) ||
- (keyno == h->table_share->primary_key &&
+ (keyno == table->s->primary_key &&
h->primary_key_is_clustered()) ||
key_uses_partial_cols(keyno))
{
@@ -3903,7 +3879,7 @@ bool DsMrr_impl::choose_mrr_impl(uint ke
return TRUE;
}
- uint add_len= h->table->key_info[keyno].key_length + h->ref_length;
+ uint add_len= table->key_info[keyno].key_length + h->ref_length;
*bufsz -= add_len;
if (get_disk_sweep_mrr_cost(keyno, rows, *flags, bufsz, &dsmrr_cost))
return TRUE;
@@ -3984,7 +3960,7 @@ bool DsMrr_impl::get_disk_sweep_mrr_cost
/* Adjust buffer size if we expect to use only part of the buffer */
if (n_full_steps)
{
- get_sort_and_sweep_cost(h->table, rows, cost);
+ get_sort_and_sweep_cost(table, rows, cost);
cost->multiply(n_full_steps);
}
else
@@ -3992,11 +3968,11 @@ bool DsMrr_impl::get_disk_sweep_mrr_cost
cost->zero();
*buffer_size= max(*buffer_size,
(size_t)(1.2*rows_in_last_step) * elem_size +
- h->ref_length + h->table->key_info[keynr].key_length);
+ h->ref_length + table->key_info[keynr].key_length);
}
COST_VECT last_step_cost;
- get_sort_and_sweep_cost(h->table, rows_in_last_step, &last_step_cost);
+ get_sort_and_sweep_cost(table, rows_in_last_step, &last_step_cost);
cost->add(&last_step_cost);
if (n_full_steps != 0)
@@ -4246,6 +4222,22 @@ int handler::compare_key(key_range *rang
return cmp;
}
+
+/*
+ Same as compare_key() but doesn't check have in_range_check_pushed_down.
+ This is used by index condition pushdown implementation.
+*/
+
+int handler::compare_key2(key_range *range)
+{
+ int cmp;
+ if (!range)
+ return 0; // no max range
+ cmp= key_cmp(range_key_part, range->key, range->length);
+ if (!cmp)
+ cmp= key_compare_result_on_equal;
+ return cmp;
+}
int handler::index_read_idx_map(uchar * buf, uint index, const uchar * key,
key_part_map keypart_map,
diff -Nrup a/sql/handler.h b/sql/handler.h
--- a/sql/handler.h 2007-12-12 11:14:04 +03:00
+++ b/sql/handler.h 2008-01-11 01:04:52 +03:00
@@ -1205,7 +1205,6 @@ uint calculate_key_len(TABLE *, uint, co
class handler :public Sql_alloc
{
friend class ha_partition;
- friend class DsMrr_impl;
friend int ha_delete_table(THD*,handlerton*,const char*,const char*,
const char*,bool);
@@ -1244,10 +1243,10 @@ public:
ha_statistics stats;
- /* Multi range read implementation-used members: */
- range_seq_t mrr_iter; /* MRR range sequence iterator being traversed */
- RANGE_SEQ_IF mrr_funcs; /* Saved MRR range sequence traversal functions */
- HANDLER_BUFFER *multi_range_buffer; /* Saved MRR buffer info */
+ /* MultiRangeRead-related members: */
+ range_seq_t mrr_iter; /* Interator to traverse the range sequence */
+ RANGE_SEQ_IF mrr_funcs; /* Range sequence traversal functions */
+ HANDLER_BUFFER *multi_range_buffer; /* MRR buffer info */
uint ranges_in_seq; /* Total number of ranges in the traversed sequence */
/* TRUE <=> source MRR ranges and the output are ordered */
bool mrr_is_output_sorted;
@@ -1257,17 +1256,13 @@ 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;
int key_compare_result_on_equal;
bool eq_range;
/*
- TRUE <=> the engine checks that returned records are within the range
+ TRUE <=> the engine guarantees that returned records are within the range
being scanned.
*/
bool in_range_check_pushed_down;
@@ -1281,7 +1276,11 @@ public:
enum {NONE=0, INDEX, RND} inited;
bool locked;
bool implicit_emptied; /* Can be !=0 only if HEAP */
- const COND *pushed_cond;
+ const Item *pushed_cond;
+
+ Item *pushed_idx_cond;
+ uint pushed_idx_cond_keyno; /* The index which the above condition is for */
+
/*
next_insert_id is the next value which should be inserted into the
auto_increment column: in a inserting-multi-row statement (like INSERT
@@ -1308,12 +1307,13 @@ 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),
locked(FALSE), implicit_emptied(0),
- pushed_cond(0), next_insert_id(0), insert_id_for_cur_row(0)
+ pushed_cond(0), pushed_idx_cond(NULL), pushed_idx_cond_keyno(MAX_KEY),
+ next_insert_id(0), insert_id_for_cur_row(0)
{}
virtual ~handler(void)
{
@@ -1412,6 +1412,7 @@ public:
DBUG_ASSERT(inited==NONE);
if (!(result= index_init(idx, sorted)))
inited=INDEX;
+ end_range= NULL;
DBUG_RETURN(result);
}
int ha_index_end()
@@ -1419,6 +1420,7 @@ public:
DBUG_ENTER("ha_index_end");
DBUG_ASSERT(inited==INDEX);
inited=NONE;
+ end_range= NULL;
DBUG_RETURN(index_end());
}
int ha_rnd_init(bool scan)
@@ -1603,6 +1605,7 @@ public:
bool eq_range, bool sorted);
virtual int read_range_next();
int compare_key(key_range *range);
+ int compare_key2(key_range *range);
virtual int ft_init() { return HA_ERR_WRONG_COMMAND; }
void ft_end() { ft_handler=NULL; }
virtual FT_INFO *ft_init_ext(uint flags, uint inx,String *key)
@@ -2171,7 +2174,6 @@ public:
return HA_ERR_WRONG_COMMAND;
}
- virtual void add_explain_extra_info(uint keyno, String *extra) {}
private:
/*
Row-level primitives for storage engines. These should be
@@ -2224,34 +2226,43 @@ 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 */
+ TABLE *table; /* Always equal to h->table */
+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 */
- range_check_toggle_func_t range_check_toggle_func;
-
-
+
+ bool use_default_impl; /* TRUE <=> shortcut all calls to default MRR impl */
+public:
+ void init(handler *h_arg, TABLE *table_arg)
+ {
+ h= h_arg;
+ table= table_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/sql/opt_range.cc b/sql/opt_range.cc
--- a/sql/opt_range.cc 2007-12-13 15:56:19 +03:00
+++ b/sql/opt_range.cc 2008-01-11 01:04:52 +03:00
@@ -7443,7 +7443,7 @@ ha_rows check_quick_select(PARAM *param,
param->is_ror_scan= FALSE;
*mrr_flags= param->force_default_mrr? HA_MRR_USE_DEFAULT_IMPL: 0;
- *mrr_flags= HA_MRR_NO_ASSOCIATION;
+ *mrr_flags|= HA_MRR_NO_ASSOCIATION;
bool pk_is_clustered= file->primary_key_is_clustered();
if (index_only &&
diff -Nrup a/sql/set_var.cc b/sql/set_var.cc
--- a/sql/set_var.cc 2007-12-18 12:30:43 +03:00
+++ b/sql/set_var.cc 2008-01-11 01:04:53 +03:00
@@ -3583,8 +3583,6 @@ ulong fix_sql_mode(ulong sql_mode)
}
-//psergey-todo: think if we can join this with thd_sql_mode one
-
bool
sys_var_thd_optimizer_switch::
symbolic_mode_representation(THD *thd, ulonglong val, LEX_STRING *rep)
diff -Nrup a/sql/sql_select.cc b/sql/sql_select.cc
--- a/sql/sql_select.cc 2007-12-20 18:00:13 +03:00
+++ b/sql/sql_select.cc 2008-01-11 01:04:53 +03:00
@@ -3213,19 +3213,6 @@ bool convert_subq_to_sj(JOIN *parent_joi
if (subq_pred->left_expr->cols() == 1)
{
- /*
- psergey-insideout-todo:
- Figure out if we can just collect a list of items or will need
- to wrap them into item-refs instead, like this:
-
- (and if we do wrap, we will have to use a permanent place to store
- pointers. (is that one of ref-pointer-array's functions?))
-
- new Item_direct_view_ref(&subq_lex->context,
- subq_lex->ref_pointer_array[0],
- (char *)"<no matter>",
- (char *)"<list ref>");
- */
nested_join->sj_outer_expr_list.push_back(subq_pred->left_expr);
Item *item_eq= new Item_func_eq(subq_pred->left_expr,
@@ -12254,8 +12241,7 @@ TABLE *create_duplicate_weedout_tmp_tabl
table->copy_blobs= 1;
table->in_use= thd;
table->quick_keys.init();
- table->covering_keys.init(); //psergey-todo: check if we need to set a bit there
- //table->used_keys.init();
+ table->covering_keys.init();
table->keys_in_use_for_query.init();
table->s= share;
@@ -15423,12 +15409,12 @@ test_if_skip_sort_order(JOIN_TAB *tab,OR
*/
if (table->covering_keys.is_set(ref_key))
usable_keys.intersect(table->covering_keys);
+ if (tab->pre_idx_push_select_cond)
+ tab->select_cond= tab->select->cond= tab->pre_idx_push_select_cond;
if ((new_ref_key= test_if_subkey(order, table, ref_key, ref_key_parts,
&usable_keys)) < MAX_KEY)
{
/* Found key that can be used to retrieve data in sorted order */
- if (tab->pre_idx_push_select_cond)
- tab->select_cond= tab->select->cond= tab->pre_idx_push_select_cond;
if (tab->ref.key >= 0)
{
/*
@@ -18654,7 +18640,10 @@ void select_describe(JOIN *join, bool ne
else if (tab->select && tab->select->quick)
keyno = tab->select->quick->index;
- tab->table->file->add_explain_extra_info(keyno, &extra);
+ if (keyno != MAX_KEY && keyno == table->file->pushed_idx_cond_keyno &&
+ table->file->pushed_idx_cond)
+ extra.append(STRING_WITH_LEN("; Using index condition"));
+
if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT ||
quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE)
diff -Nrup a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
--- a/storage/innobase/handler/ha_innodb.cc 2007-12-13 15:47:18 +03:00
+++ b/storage/innobase/handler/ha_innodb.cc 2008-01-11 01:04:53 +03:00
@@ -976,12 +976,10 @@ ha_innobase::ha_innobase(handlerton *hto
value here because it doesn't matter if we return the
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)
+ num_write_row(0)
{
- ds_mrr.h= this;
+// ds_mrr.init(this, table, (DsMrr_impl::range_check_toggle_func_t)
+// &ha_innobase::toggle_range_check);
}
/*************************************************************************
@@ -3127,9 +3125,12 @@ build_template(
prebuilt->templ_contains_blob = FALSE;
- if (file->active_index == file->cond_keyno &&
- file->active_index != MAX_KEY &&
- file->active_index != 0 /* file->primary_key psergey-todo:!*/)
+ /*
+ Setup index condition pushdown (note: we don't need to check if
+ this is a scan on primary key as that is checked in idx_cond_push)
+ */
+ if (file->active_index == file->pushed_idx_cond_keyno &&
+ file->active_index != MAX_KEY)
do_idx_cond_push= need_second_pass= TRUE;
/*
@@ -3263,7 +3264,7 @@ skip_field:
prebuilt->idx_cond_func= NULL;
prebuilt->n_index_fields= n_requested_fields;
}
- file->in_range_read= FALSE;
+ // file->in_range_read= FALSE;
if (index != clust_index && prebuilt->need_to_access_clustered) {
/* Change rec_field_no's to correspond to the clustered index
@@ -3991,7 +3992,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);
}
@@ -4606,6 +4608,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
@@ -6289,10 +6295,10 @@ ha_innobase::extra(
reset_template(prebuilt);
/* Reset index condition pushdown state */
- cond_keyno= MAX_KEY;
- in_range_read= FALSE;
+ pushed_idx_cond= FALSE;
+ pushed_idx_cond_keyno= MAX_KEY;
+ //in_range_read= FALSE;
prebuilt->idx_cond_func= NULL;
- cond_keyno= MAX_KEY;
break;
case HA_EXTRA_NO_KEYREAD:
prebuilt->read_just_key = 0;
@@ -6337,11 +6343,10 @@ int ha_innobase::reset()
}
reset_template(prebuilt);
/* Reset index condition pushdown state */
- cond_keyno= MAX_KEY;
- in_range_read= FALSE;
+ pushed_idx_cond_keyno= MAX_KEY;
+ pushed_idx_cond= NULL;
+ //in_range_read= FALSE;
prebuilt->idx_cond_func= NULL;
-
- cond_keyno= MAX_KEY;
return 0;
}
@@ -8206,6 +8211,8 @@ ha_rows ha_innobase::multi_range_read_in
uint *flags,
COST_VECT *cost)
{
+ /* See comments in ha_myisam::multi_range_read_info_const */
+ ds_mrr.init(this, table);
return ds_mrr.dsmrr_info_const(keyno, seq, seq_init_param, n_ranges, bufsz,
flags, cost);
}
@@ -8213,6 +8220,7 @@ ha_rows ha_innobase::multi_range_read_in
int ha_innobase::multi_range_read_info(uint keyno, uint n_ranges, uint keys,
uint *bufsz, uint *flags, COST_VECT *cost)
{
+ ds_mrr.init(this, table);
return ds_mrr.dsmrr_info(keyno, n_ranges, keys, bufsz, flags, cost);
}
@@ -8229,12 +8237,12 @@ C_MODE_START
static my_bool index_cond_func_innodb(void *arg)
{
ha_innobase *h= (ha_innobase*)arg;
- if (h->in_range_read)
+ if (h->end_range) //was: h->in_range_read
{
- if (h->compare_key(h->end_range) > 0)
+ if (h->compare_key2(h->end_range) > 0)
return 2; /* caller should return HA_ERR_END_OF_FILE already */
}
- return (my_bool)h->idx_cond->val_int();
+ return (my_bool)h->pushed_idx_cond->val_int();
}
C_MODE_END
@@ -8244,33 +8252,26 @@ Item *ha_innobase::idx_cond_push(uint ke
{
if (keyno_arg != primary_key)
{
- cond_keyno= keyno_arg;
- idx_cond= idx_cond_arg;
- return NULL; /* Table handler will check the entire condition */
+ pushed_idx_cond_keyno= keyno_arg;
+ pushed_idx_cond= idx_cond_arg;
in_range_check_pushed_down= TRUE;
+ return NULL; /* Table handler will check the entire condition */
}
return idx_cond_arg; /* Table handler will not make any checks */
}
-void ha_innobase::add_explain_extra_info(uint keyno, String *extra)
-{
- if (cond_keyno != MAX_KEY && idx_cond && keyno==cond_keyno)
- extra->append(STRING_WITH_LEN("; Using index condition"));
-}
-
-
int ha_innobase::read_range_first(const key_range *start_key,
const key_range *end_key,
bool eq_range_arg,
bool sorted /* ignored */)
{
int res;
- if (!eq_range_arg)
- in_range_read= TRUE;
+ //if (!eq_range_arg)
+ //in_range_read= TRUE;
res= handler::read_range_first(start_key, end_key, eq_range_arg, sorted);
- if (res)
- in_range_read= FALSE;
+ //if (res)
+ // in_range_read= FALSE;
return res;
}
@@ -8278,8 +8279,8 @@ int ha_innobase::read_range_first(const
int ha_innobase::read_range_next()
{
int res= handler::read_range_next();
- if (res)
- in_range_read= FALSE;
+ //if (res)
+ // in_range_read= FALSE;
return res;
}
diff -Nrup a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h
--- a/storage/innobase/handler/ha_innodb.h 2007-12-13 15:47:18 +03:00
+++ b/storage/innobase/handler/ha_innodb.h 2008-01-11 01:04:53 +03:00
@@ -228,24 +228,6 @@ public:
uint *bufsz, uint *flags, COST_VECT *cost);
DsMrr_impl ds_mrr;
- void add_explain_extra_info(uint keyno, String *extra);
-
- /* Index Condition Pushdown implementation */
- Item *idx_cond; /* The pushed condition. Valid iff cond_keyno != MAX_KEY */
- uint cond_keyno; /* The index which the above condition is for */
-
- /*
- TRUE <=> We're reading a range that is not equivalent to
- "keypart1=const1 AND ... keypartK=constK"
- if we're reading such range we should check if we've ran out of range
- before checking the index condition
- */
- bool in_range_read;
- void toggle_range_check(bool on)
- {
- in_range_read= on;
- }
-
int read_range_first(const key_range *start_key, const key_range *end_key,
bool eq_range_arg, bool sorted);
int read_range_next();
diff -Nrup a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
--- a/storage/myisam/ha_myisam.cc 2007-12-13 15:56:22 +03:00
+++ b/storage/myisam/ha_myisam.cc 2008-01-11 01:04:53 +03:00
@@ -532,12 +532,8 @@ ha_myisam::ha_myisam(handlerton *hton, T
HA_CAN_INSERT_DELAYED | HA_CAN_BIT_FIELD | HA_CAN_RTREEKEYS |
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)
-{
- ds_mrr.h= this;
-}
+ can_enable_indexes(1)
+{}
handler *ha_myisam::clone(MEM_ROOT *mem_root)
{
@@ -1450,12 +1446,13 @@ C_MODE_START
my_bool index_cond_func_myisam(void *arg)
{
ha_myisam *h= (ha_myisam*)arg;
- if (h->in_range_read)
+ /*if (h->in_range_read)*/
+ if (h->end_range)
{
- if (h->compare_key(h->end_range) > 0)
+ if (h->compare_key2(h->end_range) > 0)
return 2; /* caller should return HA_ERR_END_OF_FILE already */
}
- return (my_bool)h->idx_cond->val_int();
+ return (my_bool)h->pushed_idx_cond->val_int();
}
C_MODE_END
@@ -1464,8 +1461,8 @@ C_MODE_END
int ha_myisam::index_init(uint idx, bool sorted)
{
active_index=idx;
- in_range_read= FALSE;
- if (cond_keyno == idx)
+ //in_range_read= FALSE;
+ if (pushed_idx_cond_keyno == idx)
mi_set_index_cond_func(file, index_cond_func_myisam, this);
return 0;
}
@@ -1474,8 +1471,10 @@ int ha_myisam::index_init(uint idx, bool
int ha_myisam::index_end()
{
active_index=MAX_KEY;
+ //pushed_idx_cond_keyno= MAX_KEY;
mi_set_index_cond_func(file, NULL, 0);
in_range_check_pushed_down= FALSE;
+ ds_mrr.dsmrr_close();
return 0;
}
@@ -1570,13 +1569,13 @@ int ha_myisam::read_range_first(const ke
bool sorted /* ignored */)
{
int res;
- if (!eq_range_arg)
- in_range_read= TRUE;
+ //if (!eq_range_arg)
+ // in_range_read= TRUE;
res= handler::read_range_first(start_key, end_key, eq_range_arg, sorted);
- if (res)
- in_range_read= FALSE;
+ //if (res)
+ // in_range_read= FALSE;
return res;
}
@@ -1584,8 +1583,8 @@ int ha_myisam::read_range_first(const ke
int ha_myisam::read_range_next()
{
int res= handler::read_range_next();
- if (res)
- in_range_read= FALSE;
+ //if (res)
+ // in_range_read= FALSE;
return res;
}
@@ -1618,6 +1617,7 @@ int ha_myisam::rnd_pos(uchar *buf, uchar
return error;
}
+
void ha_myisam::position(const uchar *record)
{
my_off_t row_position= mi_position(file);
@@ -1701,7 +1701,8 @@ int ha_myisam::extra(enum ha_extra_funct
int ha_myisam::reset(void)
{
- cond_keyno= MAX_KEY;
+ pushed_idx_cond= NULL;
+ pushed_idx_cond_keyno= MAX_KEY;
mi_set_index_cond_func(file, NULL, 0);
return mi_reset(file);
}
@@ -1984,6 +1985,12 @@ ha_rows ha_myisam::multi_range_read_info
uint n_ranges, uint *bufsz,
uint *flags, COST_VECT *cost)
{
+ /*
+ This call is here because there is no location where this->table would
+ already be known.
+ TODO: consider moving it into some per-query initialization call.
+ */
+ ds_mrr.init(this, table);
return ds_mrr.dsmrr_info_const(keyno, seq, seq_init_param, n_ranges, bufsz,
flags, cost);
}
@@ -1991,6 +1998,7 @@ ha_rows ha_myisam::multi_range_read_info
int ha_myisam::multi_range_read_info(uint keyno, uint n_ranges, uint keys,
uint *bufsz, uint *flags, COST_VECT *cost)
{
+ ds_mrr.init(this, table);
return ds_mrr.dsmrr_info(keyno, n_ranges, keys, bufsz, flags, cost);
}
@@ -2002,18 +2010,12 @@ int ha_myisam::multi_range_read_info(uin
Item *ha_myisam::idx_cond_push(uint keyno_arg, Item* idx_cond_arg)
{
- cond_keyno= keyno_arg;
- idx_cond= idx_cond_arg;
+ pushed_idx_cond_keyno= keyno_arg;
+ pushed_idx_cond= idx_cond_arg;
in_range_check_pushed_down= TRUE;
- if (active_index == cond_keyno)
+ if (active_index == pushed_idx_cond_keyno)
mi_set_index_cond_func(file, index_cond_func_myisam, this);
return NULL;
-}
-
-void ha_myisam::add_explain_extra_info(uint keyno, String *extra)
-{
- if (cond_keyno != MAX_KEY && idx_cond && keyno==cond_keyno)
- extra->append(STRING_WITH_LEN("; Using index condition"));
}
diff -Nrup a/storage/myisam/ha_myisam.h b/storage/myisam/ha_myisam.h
--- a/storage/myisam/ha_myisam.h 2007-11-15 23:03:43 +03:00
+++ b/storage/myisam/ha_myisam.h 2008-01-11 01:04:54 +03:00
@@ -164,18 +164,9 @@ public:
/* Index condition pushdown implementation */
Item *idx_cond_push(uint keyno, Item* idx_cond);
-
- void add_explain_extra_info(uint keyno, String *extra);
private:
- uint cond_keyno;
- Item *idx_cond;
DsMrr_impl ds_mrr;
key_map keys_with_parts;
- bool in_range_read;
- void toggle_range_check(bool on)
- {
- in_range_read= on;
- }
friend my_bool index_cond_func_myisam(void *arg);
};
diff -Nrup a/storage/myisam/mi_key.c b/storage/myisam/mi_key.c
--- a/storage/myisam/mi_key.c 2007-08-26 15:31:22 +04:00
+++ b/storage/myisam/mi_key.c 2008-01-11 01:04:54 +03:00
@@ -238,36 +238,6 @@ uint _mi_pack_key(register MI_INFO *info
uint char_length;
uchar *pos;
CHARSET_INFO *cs=keyseg->charset;
- /* psergey: we probably don't need all this as we will be cloning
- handlers instead*/
-#if 0
- if (!type)
- {
- /*
- Decode the ROWID value back to to file pointer. The if-check below is
- needed to distinguish between the cases of
- a) when this function is called with k_length=USE_WHOLE_KEY (the
- packed tuple doesn't have rowid), and
- b) when this function is called with tuple+rowid
-
- The right check ought to be "k_length == length" but sergefp has
- discovered that rowid key segment length may be inequal to
- ha_myisam->ref_length, which forces us to use the below ugly check:
- */
- if (k_length > 0 && k_length < MI_MAX_KEY_LENGTH)
- {
- my_off_t rowid;
- pos=old;
- rowid= my_get_ptr(pos, k_length);
- _mi_dpointer(info, key, rowid);
- pos+=length;
- key+= keyseg->length;
- k_length= 0;
- keyseg++;
- }
- break;
- }
-#endif
keypart_map>>= 1;
if (keyseg->null_bit)
{
diff -Nrup a/storage/myisam/mi_rkey.c b/storage/myisam/mi_rkey.c
--- a/storage/myisam/mi_rkey.c 2007-08-26 15:31:22 +04:00
+++ b/storage/myisam/mi_rkey.c 2008-01-11 01:04:54 +03:00
@@ -30,7 +30,6 @@ int mi_rkey(MI_INFO *info, uchar *buf, i
HA_KEYSEG *last_used_keyseg;
uint pack_key_length, use_key_length, nextflag;
uint myisam_search_flag;
- my_bool key_tuple_has_rowid= FALSE;
int res= 0;
DBUG_ENTER("mi_rkey");
DBUG_PRINT("enter", ("base: 0x%lx buf: 0x%lx inx: %d search_flag: %d",
@@ -62,13 +61,6 @@ int mi_rkey(MI_INFO *info, uchar *buf, i
key_buff=info->lastkey+info->s->base.max_key_length;
pack_key_length=_mi_pack_key(info,(uint) inx, key_buff, (uchar*) key,
keypart_map, &last_used_keyseg);
- /* psergey-merge: this is not needed:
- if (last_used_keyseg > (info->s->keyinfo[inx].seg +
- info->s->keyinfo[inx].keysegs))
- {
- key_tuple_has_rowid= TRUE;
- last_used_keyseg--;
- } */
/* Save packed_key_length for use by the MERGE engine. */
info->pack_key_length= pack_key_length;
info->last_used_keyseg= (uint16) (last_used_keyseg -
@@ -102,11 +94,6 @@ int mi_rkey(MI_INFO *info, uchar *buf, i
case HA_KEY_ALG_BTREE:
default:
myisam_search_flag= myisam_read_vec[search_flag];
- if (key_tuple_has_rowid)
- {
- /* Fiddle with flags so ha_key_cmp compares the rowid, too */
- myisam_search_flag &= ~(SEARCH_FIND | SEARCH_NO_FIND);
- }
if (!_mi_search(info, keyinfo, key_buff, use_key_length,
myisam_search_flag, info->s->state.key_root[inx]))
{
| Thread |
|---|
| • bk commit into 6.0 tree (sergefp:1.2774) BUG#30622 | Sergey Petrunia | 10 Jan |