Commit da5edf50 authored by Sergey Petrunya's avatar Sergey Petrunya

MWL#67: MRR backport

- Make index condition pushdown be controlled by an @@optimizer_switch flag,
  not by @@engine_condition_pushdown
- Make MRR buffer size be controlled by @@mrr_buffer_size, not 
  by @@read_rnd_buffer_size
- Move parts of code to separate files
- Code cleanup
- Add --sorted_result to some SELECTs in tests.
parent 19f6f52a
......@@ -138,11 +138,13 @@ extern void my_handler_error_unregister(void);
*/
typedef enum icp_result {
ICP_NO_MATCH,
ICP_MATCH,
ICP_OUT_OF_RANGE
ICP_ERROR=-1,
ICP_NO_MATCH=0,
ICP_MATCH=1,
ICP_OUT_OF_RANGE=2
} ICP_RESULT;
#ifdef __cplusplus
}
#endif
......
......@@ -45,7 +45,7 @@ libmysqlsources = errmsg.c get_password.c libmysql.c client.c pack.c \
noinst_HEADERS = embedded_priv.h emb_qcache.h
sqlsources = ds_mrr.cc derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
ha_ndbcluster.cc ha_ndbcluster_cond.cc \
ha_ndbcluster_binlog.cc ha_partition.cc \
handler.cc sql_handler.cc \
......@@ -76,7 +76,8 @@ sqlsources = ds_mrr.cc derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
rpl_filter.cc sql_partition.cc sql_builtin.cc sql_plugin.cc \
sql_tablespace.cc \
rpl_injector.cc my_user.c partition_info.cc \
sql_servers.cc event_parse_data.cc opt_table_elimination.cc
sql_servers.cc event_parse_data.cc opt_table_elimination.cc \
multi_range_read.cc opt_index_cond_pushdown.cc
libmysqld_int_a_SOURCES= $(libmysqld_sources)
nodist_libmysqld_int_a_SOURCES= $(libmysqlsources) $(sqlsources)
......
......@@ -1332,7 +1332,7 @@ explain select fld1 from t2 where fld1=250501 or fld1=250502 or fld1 >= 250505 a
# Search with a key with LIKE constant
# If the like starts with a certain letter key will be used.
#
--sorted_result
select fld1,fld3 from t2 where companynr = 37 and fld3 like 'f%';
select fld3 from t2 where fld3 like "L%" and fld3 = "ok";
select fld3 from t2 where (fld3 like "C%" and fld3 = "Chantilly");
......
......@@ -65,8 +65,8 @@ insert into t1 (a) values ('air'),
('tn_fakira'),('vw_silvia'),('vw_starshi'),('vw_geo'),('vw_b0x1');
select * from t1 where a like 'we_%';
a b
we_toshko NULL
we_ivo NULL
we_iliyan NULL
we_ivo NULL
we_martin NULL
we_toshko NULL
drop table t1;
......@@ -1421,19 +1421,19 @@ drop table t1;
#
select @@optimizer_switch;
@@optimizer_switch
index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on
index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on
set optimizer_switch='index_merge=off,index_merge_union=off';
select @@optimizer_switch;
@@optimizer_switch
index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on
index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on
set optimizer_switch='index_merge_union=on';
select @@optimizer_switch;
@@optimizer_switch
index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on
index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on
set optimizer_switch='default,index_merge_sort_union=off';
select @@optimizer_switch;
@@optimizer_switch
index_merge=on,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on
index_merge=on,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_condition_pushdown=on
set optimizer_switch=4;
ERROR 42000: Variable 'optimizer_switch' can't be set to the value of '4'
set optimizer_switch=NULL;
......@@ -1460,21 +1460,21 @@ set optimizer_switch=default;
set optimizer_switch='index_merge=off,index_merge_union=off,default';
select @@optimizer_switch;
@@optimizer_switch
index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on
index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on
set optimizer_switch=default;
select @@global.optimizer_switch;
@@global.optimizer_switch
index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on
index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on
set @@global.optimizer_switch=default;
select @@global.optimizer_switch;
@@global.optimizer_switch
index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on
index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on
#
# Check index_merge's @@optimizer_switch flags
#
select @@optimizer_switch;
@@optimizer_switch
index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on
index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on
create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1 (a int, b int, c int, filler char(100),
......@@ -1584,5 +1584,5 @@ id select_type table type possible_keys key key_len ref rows Extra
set optimizer_switch=default;
show variables like 'optimizer_switch';
Variable_name Value
optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on
optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on
drop table t0, t1;
......@@ -292,10 +292,10 @@ NULL 9 0
NULL 9 0
drop table t1, t2;
set storage_engine= @save_storage_engine;
set @read_rnd_buffer_size_save= @@read_rnd_buffer_size;
set read_rnd_buffer_size=64;
set @mrr_buffer_size_save= @@mrr_buffer_size;
set mrr_buffer_size=64;
Warnings:
Warning 1292 Truncated incorrect read_rnd_buffer_size value: '64'
Warning 1292 Truncated incorrect mrr_buffer_size value: '64'
create table t1(a int);
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t2(a char(8), b char(8), c char(8), filler char(100), key(a,b,c) ) engine=InnoDB;
......@@ -318,10 +318,10 @@ 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;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range d d 5 NULL 53 Using index condition; Using MRR
1 SIMPLE t2 range d d 5 NULL # Using index condition; Using MRR
drop table t2;
drop table t1;
set @@read_rnd_buffer_size= @read_rnd_buffer_size_save;
set @@mrr_buffer_size= @mrr_buffer_size_save;
create table t1 (f1 int not null, f2 int not null,f3 int not null, f4 char(1), primary key (f1,f2), key ix(f3))Engine=InnoDB;
select * from t1 where (f3>=5 and f3<=10) or (f3>=1 and f3<=4);
f1 f2 f3 f4
......
drop table if exists t1, t2, t3;
set @read_rnd_buffer_size_save= @@read_rnd_buffer_size;
set read_rnd_buffer_size=79;
set @mrr_buffer_size_save= @@mrr_buffer_size;
set mrr_buffer_size=79;
Warnings:
Warning 1292 Truncated incorrect read_rnd_buffer_size value: '79'
Warning 1292 Truncated incorrect mrr_buffer_size value: '79'
create table t1(a int);
show create table t1;
Table Create Table
......@@ -293,7 +293,7 @@ NULL 7 0
NULL 9 0
NULL 9 0
drop table t1, t2;
set @@read_rnd_buffer_size= @read_rnd_buffer_size_save;
set @@mrr_buffer_size= @mrr_buffer_size_save;
CREATE TABLE t1 (
ID int(10) unsigned NOT NULL AUTO_INCREMENT,
col1 int(10) unsigned DEFAULT NULL,
......@@ -388,3 +388,29 @@ explain select * from t1 where a < 20 order by a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 20 Using index condition
drop table t0, t1;
#
# Part of MWL#67: DS-MRR backport: add an @@optimizer_switch flag for
# index_condition pushdown:
# - engine_condition_pushdown does not affect ICP
select @@optimizer_switch;
@@optimizer_switch
index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,table_elimination=on
create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1 (a int, b int, key(a));
insert into t1 select A.a + 10 *(B.a + 10*C.a), A.a + 10 *(B.a + 10*C.a) from t0 A, t0 B, t0 C;
A query that will use ICP:
explain select * from t1 where a < 20;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 20 Using index condition; Using MRR
set @save_optimizer_switch=@@optimizer_switch;
set optimizer_switch='index_condition_pushdown=off';
explain select * from t1 where a < 20;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 20 Using where; Using MRR
set optimizer_switch='index_condition_pushdown=on';
explain select * from t1 where a < 20;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 20 Using index condition; Using MRR
set optimizer_switch=@save_optimizer_switch;
drop table t0, t1;
......@@ -44,6 +44,7 @@ insert into t1 (a) values ('air'),
('we_martin'),('vw_grado'),('vw_vasko'),('tn_vili'),('tn_kalina'),
('tn_fakira'),('vw_silvia'),('vw_starshi'),('vw_geo'),('vw_b0x1');
--sorted_result
select * from t1 where a like 'we_%';
drop table t1;
......
......@@ -12,8 +12,8 @@ set storage_engine=InnoDB;
set storage_engine= @save_storage_engine;
# Try big rowid sizes
set @read_rnd_buffer_size_save= @@read_rnd_buffer_size;
set read_rnd_buffer_size=64;
set @mrr_buffer_size_save= @@mrr_buffer_size;
set mrr_buffer_size=64;
# By default InnoDB will fill values only for key parts used by the query,
# which will cause DS-MRR to supply an invalid tuple on scan restoration.
......@@ -38,11 +38,12 @@ drop table t2;
create table t2 (a char(100), b char(100), c char(100), d int,
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;
--replace_column 9 #
explain select * from t2 force index (d) where d < 10;
drop table t2;
drop table t1;
set @@read_rnd_buffer_size= @read_rnd_buffer_size_save;
set @@mrr_buffer_size= @mrr_buffer_size_save;
#
# BUG#33033 "MySQL/InnoDB crashes with simple select range query"
......
......@@ -6,12 +6,12 @@
drop table if exists t1, t2, t3;
--enable_warnings
set @read_rnd_buffer_size_save= @@read_rnd_buffer_size;
set read_rnd_buffer_size=79;
set @mrr_buffer_size_save= @@mrr_buffer_size;
set mrr_buffer_size=79;
-- source include/mrr_tests.inc
set @@read_rnd_buffer_size= @read_rnd_buffer_size_save;
set @@mrr_buffer_size= @mrr_buffer_size_save;
#
# BUG#30622: Incorrect query results for MRR + filesort
......@@ -96,3 +96,31 @@ insert into t1 select A.a + 10 *(B.a + 10*C.a), A.a + 10 *(B.a + 10*C.a) from t0
explain select * from t1 where a < 20 order by a;
drop table t0, t1;
-- echo #
-- echo # Part of MWL#67: DS-MRR backport: add an @@optimizer_switch flag for
-- echo # index_condition pushdown:
-- echo # - engine_condition_pushdown does not affect ICP
# Check that optimizer_switch is present
select @@optimizer_switch;
# Check if it affects ICP
create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1 (a int, b int, key(a));
insert into t1 select A.a + 10 *(B.a + 10*C.a), A.a + 10 *(B.a + 10*C.a) from t0 A, t0 B, t0 C;
-- echo A query that will use ICP:
explain select * from t1 where a < 20;
set @save_optimizer_switch=@@optimizer_switch;
set optimizer_switch='index_condition_pushdown=off';
explain select * from t1 where a < 20;
set optimizer_switch='index_condition_pushdown=on';
explain select * from t1 where a < 20;
set optimizer_switch=@save_optimizer_switch;
drop table t0, t1;
......@@ -47,7 +47,7 @@ mysqld_LDADD = libndb.la \
$(LDADD) $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ \
$(yassl_libs) $(openssl_libs) @MYSQLD_EXTRA_LIBS@
noinst_HEADERS = ds_mrr.h item.h item_func.h item_sum.h item_cmpfunc.h \
noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
item_strfunc.h item_timefunc.h \
item_xmlfunc.h \
item_create.h item_subselect.h item_row.h \
......@@ -77,9 +77,10 @@ noinst_HEADERS = ds_mrr.h item.h item_func.h item_sum.h item_cmpfunc.h \
sql_plugin.h authors.h event_parse_data.h \
event_data_objects.h event_scheduler.h \
sql_partition.h partition_info.h partition_element.h \
contributors.h sql_servers.h
contributors.h sql_servers.h \
multi_range_read.h
mysqld_SOURCES = ds_mrr.cc sql_lex.cc sql_handler.cc sql_partition.cc \
mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
item.cc item_sum.cc item_buff.cc item_func.cc \
item_cmpfunc.cc item_strfunc.cc item_timefunc.cc \
thr_malloc.cc item_create.cc item_subselect.cc \
......@@ -122,7 +123,9 @@ mysqld_SOURCES = ds_mrr.cc sql_lex.cc sql_handler.cc sql_partition.cc \
sql_plugin.cc sql_binlog.cc \
sql_builtin.cc sql_tablespace.cc partition_info.cc \
sql_servers.cc event_parse_data.cc \
opt_table_elimination.cc
opt_table_elimination.cc \
multi_range_read.cc \
opt_index_cond_pushdown.cc
nodist_mysqld_SOURCES = mini_client_errors.c pack.c client.c my_time.c my_user.c
......
......@@ -2314,7 +2314,7 @@ private:
friend class DsMrr_impl;
};
#include "ds_mrr.h"
#include "multi_range_read.h"
/* Some extern variables used with handlers */
......
This diff is collapsed.
/*
This file contains declarations for
- Disk-Sweep MultiRangeRead (DS-MRR) implementation
- Index Condition Pushdown helper functions
*/
/**
......
......@@ -540,12 +540,13 @@ protected:
#define OPTIMIZER_SWITCH_INDEX_MERGE_UNION 2
#define OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION 4
#define OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT 8
#define OPTIMIZER_SWITCH_INDEX_COND_PUSHDOWN 16
#ifdef DBUG_OFF
# define OPTIMIZER_SWITCH_LAST 16
#else
# define OPTIMIZER_SWITCH_TABLE_ELIMINATION 16
# define OPTIMIZER_SWITCH_LAST 32
#else
# define OPTIMIZER_SWITCH_TABLE_ELIMINATION 32
# define OPTIMIZER_SWITCH_LAST 64
#endif
#ifdef DBUG_OFF
......@@ -553,12 +554,14 @@ protected:
# define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \
OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \
OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION | \
OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT)
OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT | \
OPTIMIZER_SWITCH_INDEX_COND_PUSHDOWN)
#else
# define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \
OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \
OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION | \
OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT | \
OPTIMIZER_SWITCH_INDEX_COND_PUSHDOWN | \
OPTIMIZER_SWITCH_TABLE_ELIMINATION)
#endif
......
......@@ -300,6 +300,7 @@ static const char *optimizer_switch_names[]=
{
"index_merge","index_merge_union","index_merge_sort_union",
"index_merge_intersection",
"index_condition_pushdown",
#ifndef DBUG_OFF
"table_elimination",
#endif
......@@ -313,6 +314,7 @@ static const unsigned int optimizer_switch_names_len[]=
sizeof("index_merge_union") - 1,
sizeof("index_merge_sort_union") - 1,
sizeof("index_merge_intersection") - 1,
sizeof("index_condition_pushdown") - 1,
#ifndef DBUG_OFF
sizeof("table_elimination") - 1,
#endif
......@@ -391,7 +393,8 @@ static const char *sql_mode_str= "OFF";
/* Text representation for OPTIMIZER_SWITCH_DEFAULT */
static const char *optimizer_switch_str="index_merge=on,index_merge_union=on,"
"index_merge_sort_union=on,"
"index_merge_intersection=on"
"index_merge_intersection=on,"
"index_condition_pushdown=on"
#ifndef DBUG_OFF
",table_elimination=on";
#else
......@@ -5767,7 +5770,7 @@ enum options_mysqld
OPT_MAX_SEEKS_FOR_KEY, OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS,
OPT_MAX_LENGTH_FOR_SORT_DATA,
OPT_MAX_WRITE_LOCK_COUNT, OPT_BULK_INSERT_BUFFER_SIZE,
OPT_MAX_ERROR_COUNT, OPT_MULTI_RANGE_COUNT, OPT_MYISAM_DATA_POINTER_SIZE,
OPT_MAX_ERROR_COUNT, OPT_MRR_BUFFER_SIZE, OPT_MYISAM_DATA_POINTER_SIZE,
OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE,
......@@ -6963,6 +6966,12 @@ The minimum value for this variable is 4096.",
(uchar**) &global_system_variables.min_examined_row_limit,
(uchar**) &max_system_variables.min_examined_row_limit, 0, GET_ULONG,
REQUIRED_ARG, 0, 0, (longlong) ULONG_MAX, 0, 1L, 0},
{"mrr_buffer_size", OPT_MRR_BUFFER_SIZE,
"Size of buffer to use when using MRR with range access",
(uchar**) &global_system_variables.mrr_buff_size,
(uchar**) &max_system_variables.mrr_buff_size, 0,
GET_ULONG, REQUIRED_ARG, 256*1024L, IO_SIZE*2+MALLOC_OVERHEAD,
INT_MAX32, MALLOC_OVERHEAD, 1 /* Small to be able to do tests */ , 0},
{"myisam_block_size", OPT_MYISAM_BLOCK_SIZE,
"Block size to be used for MyISAM index pages.",
(uchar**) &opt_myisam_block_size,
......@@ -7042,7 +7051,8 @@ The minimum value for this variable is 4096.",
0, GET_ULONG, OPT_ARG, MAX_TABLES+1, 0, MAX_TABLES+2, 0, 1, 0},
{"optimizer_switch", OPT_OPTIMIZER_SWITCH,
"optimizer_switch=option=val[,option=val...], where option={index_merge, "
"index_merge_union, index_merge_sort_union, index_merge_intersection"
"index_merge_union, index_merge_sort_union, index_merge_intersection, "
"index_condition_pushdown"
#ifndef DBUG_OFF
", table_elimination"
#endif
......@@ -7126,7 +7136,7 @@ The minimum value for this variable is 4096.",
(uchar**) &global_system_variables.read_rnd_buff_size,
(uchar**) &max_system_variables.read_rnd_buff_size, 0,
GET_ULONG, REQUIRED_ARG, 256*1024L, IO_SIZE*2+MALLOC_OVERHEAD,
INT_MAX32, MALLOC_OVERHEAD, 1 /* Small overhead to be able to test MRR, was: IO_SIZE*/ , 0},
INT_MAX32, MALLOC_OVERHEAD, IO_SIZE, 0},
{"record_buffer", OPT_RECORD_BUFFER,
"Alias for read_buffer_size",
(uchar**) &global_system_variables.read_buff_size,
......
This diff is collapsed.
This diff is collapsed.
......@@ -317,7 +317,7 @@ protected:
public:
uint mrr_flags; /* Flags to be used with MRR interface */
protected:
uint mrr_buf_size; /* copy from thd->variables.read_rnd_buff_size */
uint mrr_buf_size; /* copy from thd->variables.mrr_buff_size */
HANDLER_BUFFER *mrr_buf_desc; /* the handler buffer */
/* Info about index we're scanning */
......
This diff is collapsed.
......@@ -526,6 +526,8 @@ static sys_var_bool_ptr sys_userstat(&vars, "userstat",
static sys_var_thd_ulong sys_read_rnd_buff_size(&vars, "read_rnd_buffer_size",
&SV::read_rnd_buff_size);
static sys_var_thd_ulong sys_mrr_buff_size(&vars, "mrr_buffer_size",
&SV::mrr_buff_size);
static sys_var_thd_ulong sys_div_precincrement(&vars, "div_precision_increment",
&SV::div_precincrement);
static sys_var_long_ptr sys_rpl_recovery_rank(&vars, "rpl_recovery_rank",
......
......@@ -339,6 +339,7 @@ struct system_variables
ulong query_cache_type;
ulong read_buff_size;
ulong read_rnd_buff_size;
ulong mrr_buff_size;
ulong div_precincrement;
ulong sortbuff_size;
ulong thread_handling;
......
......@@ -2022,16 +2022,15 @@ int ha_maria::delete_row(const uchar * buf)
C_MODE_START
my_bool index_cond_func_maria(void *arg)
ICP_RESULT index_cond_func_maria(void *arg)
{
ha_maria *h= (ha_maria*)arg;
/*if (h->in_range_read)*/
if (h->end_range)
{
if (h->compare_key2(h->end_range) > 0)
return 2; /* caller should return HA_ERR_END_OF_FILE already */
return ICP_OUT_OF_RANGE; /* caller should return HA_ERR_END_OF_FILE already */
}
return (my_bool)h->pushed_idx_cond->val_int();
return h->pushed_idx_cond->val_int() ? ICP_MATCH : ICP_NO_MATCH;
}
C_MODE_END
......
......@@ -29,7 +29,7 @@
#define HA_RECOVER_QUICK 8 /* Don't check rows in data file */
C_MODE_START
my_bool index_cond_func_maria(void *arg);
ICP_RESULT index_cond_func_maria(void *arg);
C_MODE_END
extern ulong maria_sort_buffer_size;
......@@ -187,5 +187,5 @@ public:
Item *idx_cond_push(uint keyno, Item* idx_cond);
private:
DsMrr_impl ds_mrr;
friend my_bool index_cond_func_maria(void *arg);
friend ICP_RESULT index_cond_func_maria(void *arg);
};
......@@ -669,10 +669,10 @@ int _ma_read_key_record(MARIA_HA *info, uchar *buf, MARIA_RECORD_POS filepos)
will look for column values there)
RETURN
-1 Error
0 Index condition is not satisfied, continue scanning
1 Index condition is satisfied
2 Index condition is not satisfied, end the scan.
ICP_ERROR Error
ICP_NO_MATCH Index condition is not satisfied, continue scanning
ICP_MATCH Index condition is satisfied
ICP_OUT_OF_RANGE Index condition is not satisfied, end the scan.
*/
int ma_check_index_cond(register MARIA_HA *info, uint keynr, uchar *record)
......
......@@ -477,8 +477,7 @@ typedef struct st_maria_block_scan
MARIA_RECORD_POS row_base_page;
} MARIA_BLOCK_SCAN;
/*psergey-todo: do really need to have copies of this all over the place?*/
typedef my_bool (*index_cond_func_t)(void *param);
typedef ICP_RESULT (*index_cond_func_t)(void *param);
struct st_maria_handler
{
......
......@@ -504,10 +504,10 @@ int _mi_read_key_record(MI_INFO *info, my_off_t filepos, uchar *buf)
will look for column values there)
RETURN
-1 Error
0 Index condition is not satisfied, continue scanning
1 Index condition is satisfied
2 Index condition is not satisfied, end the scan.
ICP_ERROR Error
ICP_NO_MATCH Index condition is not satisfied, continue scanning
ICP_MATCH Index condition is satisfied
ICP_OUT_OF_RANGE Index condition is not satisfied, end the scan.
*/
int mi_check_index_cond(register MI_INFO *info, uint keynr, uchar *record)
......@@ -516,7 +516,7 @@ int mi_check_index_cond(register MI_INFO *info, uint keynr, uchar *record)
{
mi_print_error(info->s, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
return -1;
return ICP_ERROR;
}
return info->index_cond_func(info->index_cond_func_arg);
}
......
......@@ -29,7 +29,7 @@ int mi_rkey(MI_INFO *info, uchar *buf, int inx, const uchar *key,
MI_KEYDEF *keyinfo;
HA_KEYSEG *last_used_keyseg;
uint pack_key_length, use_key_length, nextflag;
int res= 0;
ICP_RESULT res= ICP_NO_MATCH;
DBUG_ENTER("mi_rkey");
DBUG_PRINT("enter", ("base: 0x%lx buf: 0x%lx inx: %d search_flag: %d",
(long) info, (long) buf, inx, search_flag));
......@@ -118,7 +118,7 @@ int mi_rkey(MI_INFO *info, uchar *buf, int inx, const uchar *key,
(search_flag != HA_READ_KEY_EXACT ||
last_used_keyseg != keyinfo->seg + keyinfo->keysegs)) ||
(info->index_cond_func &&
!(res= mi_check_index_cond(info, inx, buf))))
(res= mi_check_index_cond(info, inx, buf)) == ICP_NO_MATCH))
{
uint not_used[2];
/*
......@@ -146,7 +146,7 @@ int mi_rkey(MI_INFO *info, uchar *buf, int inx, const uchar *key,
break;
}
}
if (res == 2)
if (res == ICP_OUT_OF_RANGE)
{
info->lastpos= HA_OFFSET_ERROR;
if (share->concurrent_insert)
......
......@@ -28,7 +28,7 @@ int mi_rnext(MI_INFO *info, uchar *buf, int inx)
{
int error,changed;
uint flag;
int res= 0;
ICP_RESULT res= 0;
DBUG_ENTER("mi_rnext");
if ((inx = _mi_check_index(info,inx)) < 0)
......@@ -87,7 +87,7 @@ int mi_rnext(MI_INFO *info, uchar *buf, int inx)
while ((info->s->concurrent_insert &&
info->lastpos >= info->state->data_file_length) ||
(info->index_cond_func &&
!(res= mi_check_index_cond(info, inx, buf))))
(res= mi_check_index_cond(info, inx, buf)) == ICP_NO_MATCH))
{
/*
Skip rows that are either inserted by other threads since
......@@ -100,7 +100,7 @@ int mi_rnext(MI_INFO *info, uchar *buf, int inx)
info->s->state.key_root[inx])))
break;
}
if (!error && res == 2)
if (!error && res == ICP_OUT_OF_RANGE)
{
if (info->s->concurrent_insert)
rw_unlock(&info->s->key_root_lock[inx]);
......
......@@ -75,9 +75,13 @@ int mi_rnext_same(MI_INFO *info, uchar *buf)
info->lastpos= HA_OFFSET_ERROR;
break;
}
/* Skip rows that are inserted by other threads since we got a lock */
/*
Skip
- rows that are inserted by other threads since we got a lock
- rows that don't match index condition */
if (info->lastpos < info->state->data_file_length &&
(!info->index_cond_func || mi_check_index_cond(info, inx, buf)))
(!info->index_cond_func ||
mi_check_index_cond(info, inx, buf) != ICP_NO_MATCH))
break;
}
}
......
......@@ -114,7 +114,7 @@ static pthread_mutex_t commit_cond_m;
static bool innodb_inited = 0;
C_MODE_START
static uint index_cond_func_innodb(void *arg);
static int index_cond_func_innodb(void *arg);
C_MODE_END
......@@ -10765,24 +10765,12 @@ ha_rows ha_innobase::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
{
/* See comments in ha_myisam::multi_range_read_info_const */
ds_mrr.init(this, table);
//psergey-mrr-fix:
if (prebuilt->select_lock_type != LOCK_NONE)
*flags |= HA_MRR_USE_DEFAULT_IMPL;
uint orig_flags= *flags;
ha_rows res= ds_mrr.dsmrr_info_const(keyno, seq, seq_init_param, n_ranges,
bufsz, flags, cost);
bool disable_ds_mrr= true;
disable_ds_mrr= false;
// DBUG_EXECUTE_IF("optimizer_innodb_ds_mrr", disable_ds_mrr= false;);
if (!disable_ds_mrr)
return res;
/* Disable DS-MRR: enable MS-MRR only after critical bugs are fixed */
*bufsz= 0;
*flags = orig_flags | HA_MRR_USE_DEFAULT_IMPL;
return res;
}
......@@ -10791,17 +10779,7 @@ ha_rows ha_innobase::multi_range_read_info(uint keyno, uint n_ranges,
uint *flags, COST_VECT *cost)
{
ds_mrr.init(this, table);
uint orig_flags= *flags;
ha_rows res= ds_mrr.dsmrr_info(keyno, n_ranges, keys, bufsz, flags, cost);
bool disable_ds_mrr= false;
// DBUG_EXECUTE_IF("optimizer_innodb_ds_mrr", disable_ds_mrr= false;);
if (!disable_ds_mrr)
return res;
/* Disable DS-MRR: enable MS-MRR only after critical bugs are fixed */
*bufsz= 0;
*flags = orig_flags | HA_MRR_USE_DEFAULT_IMPL;
return res;
}
......@@ -10818,15 +10796,15 @@ C_MODE_START
See note on ICP_RESULT for return values description.
*/
static uint index_cond_func_innodb(void *arg)
static int index_cond_func_innodb(void *arg)
{
ha_innobase *h= (ha_innobase*)arg;
if (h->end_range)
{
if (h->compare_key2(h->end_range) > 0)
return 2; /* caller should return HA_ERR_END_OF_FILE already */
return ICP_OUT_OF_RANGE; /* caller should return HA_ERR_END_OF_FILE already */
}
return test(h->pushed_idx_cond->val_int());
return h->pushed_idx_cond->val_int()? ICP_MATCH : ICP_NO_MATCH;
}
C_MODE_END
......@@ -10834,8 +10812,7 @@ C_MODE_END
Item *ha_innobase::idx_cond_push(uint keyno_arg, Item* idx_cond_arg)
{
// V :psergey-mrrr-merge: V
if (keyno_arg != primary_key && (prebuilt->select_lock_type == LOCK_NONE))
if ((keyno_arg != primary_key) && (prebuilt->select_lock_type == LOCK_NONE))
{
pushed_idx_cond_keyno= keyno_arg;
pushed_idx_cond= idx_cond_arg;
......
......@@ -564,7 +564,7 @@ struct mysql_row_templ_struct {
#define ROW_PREBUILT_ALLOCATED 78540783
#define ROW_PREBUILT_FREED 26423527
typedef uint (*index_cond_func_t)(void *param);
typedef int (*index_cond_func_t)(void *param);
/* A struct for (sometimes lazily) prebuilt structures in an Innobase table
handle used within MySQL; these are used to save CPU time. */
......
......@@ -3116,10 +3116,14 @@ row_sel_pop_cached_row_for_mysql(
/* Copy NULL bit of the current field from cached_rec
to buf */
if (templ->mysql_null_bit_mask) {
buf[templ->mysql_null_byte_offset]
/*buf[templ->mysql_null_byte_offset]
^= (buf[templ->mysql_null_byte_offset]
^ cached_rec[templ->mysql_null_byte_offset])
& (byte)templ->mysql_null_bit_mask;
& (byte)templ->mysql_null_bit_mask;*/
byte *null_byte= buf + templ->mysql_null_byte_offset;
(*null_byte)&= ~templ->mysql_null_bit_mask;
(*null_byte)|= cached_rec[templ->mysql_null_byte_offset] &
templ->mysql_null_bit_mask;
}
}
}
......@@ -3354,10 +3358,8 @@ row_search_for_mysql(
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_;
/*psergey-mrr:*/
ibool some_fields_in_buffer;
ibool get_clust_rec = 0;
/*:psergey-mrr*/
rec_offs_init(offsets_);
......@@ -4210,11 +4212,8 @@ no_gap_lock:
information via the clustered index record. */
ut_ad(index != clust_index);
/*psergey-mrr:*/
get_clust_rec = TRUE;
goto idx_cond_check;
/**goto requires_clust_rec;**/
/*:psergey-mrr*/
}
}
......@@ -4260,22 +4259,20 @@ no_gap_lock:
idx_cond_check:
if (prebuilt->idx_cond_func)
{
int res;
ut_ad(prebuilt->template_type != ROW_MYSQL_DUMMY_TEMPLATE);
offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
row_sel_store_mysql_rec(buf, prebuilt, rec,
offsets, 0, prebuilt->n_index_fields);
res= prebuilt->idx_cond_func(prebuilt->idx_cond_func_arg);
if (res == 0)
goto next_rec;
if (res == 2)
{
err = DB_RECORD_NOT_FOUND;
goto idx_cond_failed;
}
}
if (prebuilt->idx_cond_func) {
int res;
ut_ad(prebuilt->template_type != ROW_MYSQL_DUMMY_TEMPLATE);
offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
row_sel_store_mysql_rec(buf, prebuilt, rec,
offsets, 0, prebuilt->n_index_fields);
res= prebuilt->idx_cond_func(prebuilt->idx_cond_func_arg);
if (res == 0)
goto next_rec;
if (res == 2) {
err = DB_RECORD_NOT_FOUND;
goto idx_cond_failed;
}
}
/* Get the clustered index record if needed, if we did not do the
search using the clustered index. */
......
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