Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
3b29cad0
Commit
3b29cad0
authored
May 13, 2004
by
sergefp@mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Manual merge
parents
654bf99b
a46d7542
Changes
28
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
28 changed files
with
3721 additions
and
511 deletions
+3721
-511
include/my_base.h
include/my_base.h
+6
-0
include/my_bitmap.h
include/my_bitmap.h
+2
-0
include/my_sys.h
include/my_sys.h
+1
-0
innobase/include/row0mysql.h
innobase/include/row0mysql.h
+4
-0
innobase/row/row0sel.c
innobase/row/row0sel.c
+28
-3
mysql-test/r/index_merge_ror.result
mysql-test/r/index_merge_ror.result
+168
-0
mysql-test/r/index_merge_ror_cpk.result
mysql-test/r/index_merge_ror_cpk.result
+93
-0
mysql-test/r/rowid_order_bdb.result
mysql-test/r/rowid_order_bdb.result
+186
-0
mysql-test/r/rowid_order_innodb.result
mysql-test/r/rowid_order_innodb.result
+186
-0
mysql-test/t/index_merge_ror.test
mysql-test/t/index_merge_ror.test
+215
-0
mysql-test/t/index_merge_ror_cpk.test
mysql-test/t/index_merge_ror_cpk.test
+81
-0
mysql-test/t/rowid_order_bdb.test
mysql-test/t/rowid_order_bdb.test
+108
-0
mysql-test/t/rowid_order_innodb.test
mysql-test/t/rowid_order_innodb.test
+108
-0
mysys/my_bit.c
mysys/my_bit.c
+5
-0
mysys/my_bitmap.c
mysys/my_bitmap.c
+56
-0
sql/ha_berkeley.cc
sql/ha_berkeley.cc
+25
-0
sql/ha_berkeley.h
sql/ha_berkeley.h
+1
-0
sql/ha_heap.h
sql/ha_heap.h
+6
-1
sql/ha_innodb.cc
sql/ha_innodb.cc
+57
-0
sql/ha_innodb.h
sql/ha_innodb.h
+1
-0
sql/handler.h
sql/handler.h
+5
-0
sql/opt_range.cc
sql/opt_range.cc
+2188
-377
sql/opt_range.h
sql/opt_range.h
+147
-14
sql/sql_delete.cc
sql/sql_delete.cc
+5
-5
sql/sql_select.cc
sql/sql_select.cc
+28
-48
sql/sql_select.h
sql/sql_select.h
+1
-1
sql/sql_test.cc
sql/sql_test.cc
+2
-31
sql/sql_update.cc
sql/sql_update.cc
+8
-31
No files found.
include/my_base.h
View file @
3b29cad0
...
...
@@ -147,6 +147,12 @@ enum ha_extra_function {
*/
HA_EXTRA_CHANGE_KEY_TO_UNIQUE
,
HA_EXTRA_CHANGE_KEY_TO_DUP
/*
When using HA_EXTRA_KEYREAD, overwrite only key member fields and keep
other fields intact. When this is off (by default) InnoDB will use memcpy
to overwrite entire row.
*/
HA_EXTRA_KEYREAD_PRESERVE_FIELDS
};
/* The following is parameter to ha_panic() */
...
...
include/my_bitmap.h
View file @
3b29cad0
...
...
@@ -46,6 +46,8 @@ extern my_bool bitmap_is_set(const MY_BITMAP *map, uint bitmap_bit);
extern
my_bool
bitmap_is_set_all
(
const
MY_BITMAP
*
map
);
extern
my_bool
bitmap_is_subset
(
const
MY_BITMAP
*
map1
,
const
MY_BITMAP
*
map2
);
extern
uint
bitmap_set_next
(
MY_BITMAP
*
map
);
extern
uint
bitmap_get_first
(
const
MY_BITMAP
*
map
);
extern
uint
bitmap_bits_set
(
const
MY_BITMAP
*
map
);
extern
void
bitmap_clear_all
(
MY_BITMAP
*
map
);
extern
void
bitmap_clear_bit
(
MY_BITMAP
*
map
,
uint
bitmap_bit
);
extern
void
bitmap_free
(
MY_BITMAP
*
map
);
...
...
include/my_sys.h
View file @
3b29cad0
...
...
@@ -748,6 +748,7 @@ extern byte *my_compress_alloc(const byte *packet, ulong *len, ulong *complen);
extern
ha_checksum
my_checksum
(
ha_checksum
crc
,
const
byte
*
mem
,
uint
count
);
extern
uint
my_bit_log2
(
ulong
value
);
extern
uint
my_count_bits
(
ulonglong
v
);
extern
uint
my_count_bits_ushort
(
ushort
v
);
extern
void
my_sleep
(
ulong
m_seconds
);
extern
ulong
crc32
(
ulong
crc
,
const
uchar
*
buf
,
uint
len
);
extern
uint
my_set_max_open_files
(
uint
files
);
...
...
innobase/include/row0mysql.h
View file @
3b29cad0
...
...
@@ -554,6 +554,10 @@ struct row_prebuilt_struct {
allocated mem buf start, because
there is a 4 byte magic number at the
start and at the end */
ibool
keep_other_fields_on_keyread
;
/* when using fetch
cache with HA_EXTRA_KEYREAD, don't
overwrite other fields in mysql row
row buffer.*/
ulint
fetch_cache_first
;
/* position of the first not yet
fetched row in fetch_cache */
ulint
n_fetch_cached
;
/* number of not yet fetched rows
...
...
innobase/row/row0sel.c
View file @
3b29cad0
...
...
@@ -2579,10 +2579,35 @@ row_sel_pop_cached_row_for_mysql(
row */
row_prebuilt_t
*
prebuilt
)
/* in: prebuilt struct */
{
ulint
i
;
mysql_row_templ_t
*
templ
;
byte
*
cached_rec
;
ut_ad
(
prebuilt
->
n_fetch_cached
>
0
);
if
(
prebuilt
->
keep_other_fields_on_keyread
)
{
/* Copy cache record field by field, don't touch fields that
are not covered by current key */
cached_rec
=
prebuilt
->
fetch_cache
[
prebuilt
->
fetch_cache_first
];
for
(
i
=
0
;
i
<
prebuilt
->
n_template
;
i
++
)
{
templ
=
prebuilt
->
mysql_template
+
i
;
ut_memcpy
(
buf
+
templ
->
mysql_col_offset
,
cached_rec
+
templ
->
mysql_col_offset
,
templ
->
mysql_col_len
);
if
(
templ
->
mysql_null_bit_mask
)
buf
[
templ
->
mysql_null_byte_offset
]
&=
cached_rec
[
templ
->
mysql_null_byte_offset
];
}
}
else
{
ut_memcpy
(
buf
,
prebuilt
->
fetch_cache
[
prebuilt
->
fetch_cache_first
],
prebuilt
->
mysql_row_len
);
}
prebuilt
->
n_fetch_cached
--
;
prebuilt
->
fetch_cache_first
++
;
...
...
mysql-test/r/index_merge_ror.result
0 → 100644
View file @
3b29cad0
This diff is collapsed.
Click to expand it.
mysql-test/r/index_merge_ror_cpk.result
0 → 100644
View file @
3b29cad0
drop table if exists t1;
create table t1
(
pk1 int not null,
pk2 int not null,
key1 int not null,
key2 int not null,
pktail1ok int not null,
pktail2ok int not null,
pktail3bad int not null,
pktail4bad int not null,
pktail5bad int not null,
pk2copy int not null,
badkey int not null,
filler1 char (200),
filler2 char (200),
key (key1),
key (key2),
/* keys with tails from CPK members */
key (pktail1ok, pk1),
key (pktail2ok, pk1, pk2),
key (pktail3bad, pk2, pk1),
key (pktail4bad, pk1, pk2copy),
key (pktail5bad, pk1, pk2, pk2copy),
primary key (pk1, pk2)
) engine=innodb;
explain select * from t1 where pk1 = 1 and pk2 < 80 and key1=0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref PRIMARY,key1 PRIMARY 4 const 1 Using where
select * from t1 where pk1 = 1 and pk2 < 80 and key1=0;
pk1 pk2 key1 key2 pktail1ok pktail2ok pktail3bad pktail4bad pktail5bad pk2copy badkey filler1 filler2
1 10 0 0 0 0 0 0 0 10 0 filler-data-10 filler2
1 11 0 0 0 0 0 0 0 11 0 filler-data-11 filler2
1 12 0 0 0 0 0 0 0 12 0 filler-data-12 filler2
1 13 0 0 0 0 0 0 0 13 0 filler-data-13 filler2
1 14 0 0 0 0 0 0 0 14 0 filler-data-14 filler2
1 15 0 0 0 0 0 0 0 15 0 filler-data-15 filler2
1 16 0 0 0 0 0 0 0 16 0 filler-data-16 filler2
1 17 0 0 0 0 0 0 0 17 0 filler-data-17 filler2
1 18 0 0 0 0 0 0 0 18 0 filler-data-18 filler2
1 19 0 0 0 0 0 0 0 19 0 filler-data-19 filler2
explain select pk1,pk2 from t1 where key1 = 10 and key2=10 and 2*pk1+1 < 2*96+1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index_merge key1,key2 intr(key1,key2) 4,4 NULL 1 Using where; Using index
select pk1,pk2 from t1 where key1 = 10 and key2=10 and 2*pk1+1 < 2*96+1;
pk1 pk2
95 50
95 51
95 52
95 53
95 54
95 55
95 56
95 57
95 58
95 59
explain select * from t1 where badkey=1 and key1=10;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref key1 key1 4 const 101 Using where
explain select * from t1 where pk1 < 7500 and key1 = 10;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index_merge PRIMARY,key1 intr(key1:PRIMARY) 4:4 NULL 38 Using where
explain select * from t1 where pktail1ok=1 and key1=10;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index_merge key1,pktail1ok intr(key1,pktail1ok) 4,4 NULL 1 Using where
explain select * from t1 where pktail2ok=1 and key1=10;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index_merge key1,pktail2ok intr(key1,pktail2ok) 4,4 NULL 1 Using where
explain select * from t1 where pktail3bad=1 and key1=10;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref key1,pktail3bad pktail3bad 4 const 98 Using where
explain select * from t1 where pktail4bad=1 and key1=10;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref key1,pktail4bad pktail4bad 4 const 99 Using where
explain select * from t1 where pktail5bad=1 and key1=10;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref key1,pktail5bad pktail5bad 4 const 99 Using where
explain select pk1,pk2,key1,key2 from t1 where key1 = 10 and key2=10 limit 10;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index_merge key1,key2 intr(key1,key2) 4,4 NULL 1 Using where; Using index
select pk1,pk2,key1,key2 from t1 where key1 = 10 and key2=10 limit 10;
pk1 pk2 key1 key2
95 50 10 10
95 51 10 10
95 52 10 10
95 53 10 10
95 54 10 10
95 55 10 10
95 56 10 10
95 57 10 10
95 58 10 10
95 59 10 10
drop table t1;
mysql-test/r/rowid_order_bdb.result
0 → 100644
View file @
3b29cad0
drop table if exists t1, t2, t3,t4;
create table t1 (
pk1 int not NULL,
key1 int(11),
key2 int(11),
PRIMARY KEY (pk1),
KEY key1 (key1),
KEY key2 (key2)
) engine=bdb;
insert into t1 values (-5, 1, 1),
(-100, 1, 1),
(3, 1, 1),
(0, 1, 1),
(10, 1, 1);
explain select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index_merge key1,key2 key1,key2 5,5 NULL 5 Using where
select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
pk1 key1 key2
-100 1 1
-5 1 1
0 1 1
3 1 1
10 1 1
drop table t1;
create table t1 (
pk1 int unsigned not NULL,
key1 int(11),
key2 int(11),
PRIMARY KEY (pk1),
KEY key1 (key1),
KEY key2 (key2)
) engine=bdb;
insert into t1 values (0, 1, 1),
(0xFFFFFFFF, 1, 1),
(0xFFFFFFFE, 1, 1),
(1, 1, 1),
(2, 1, 1);
select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
pk1 key1 key2
0 1 1
1 1 1
2 1 1
4294967294 1 1
4294967295 1 1
drop table t1;
create table t1 (
pk1 char(4) not NULL,
key1 int(11),
key2 int(11),
PRIMARY KEY (pk1),
KEY key1 (key1),
KEY key2 (key2)
) engine=bdb collate latin2_general_ci;
insert into t1 values ('a1', 1, 1),
('b2', 1, 1),
('A3', 1, 1),
('B4', 1, 1);
select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
pk1 key1 key2
a1 1 1
A3 1 1
b2 1 1
B4 1 1
drop table t1;
create table t1 (
pk1 int not NULL,
pk2 char(4) not NULL collate latin1_german1_ci,
pk3 char(4) not NULL collate latin1_bin,
key1 int(11),
key2 int(11),
PRIMARY KEY (pk1,pk2,pk3),
KEY key1 (key1),
KEY key2 (key2)
) engine=bdb;
insert into t1 values
(1, 'u', 'u', 1, 1),
(1, 'u', char(0xEC), 1, 1),
(1, 'u', 'x', 1, 1);
insert ignore into t1 select pk1, char(0xEC), pk3, key1, key2 from t1;
insert ignore into t1 select pk1, 'x', pk3, key1, key2 from t1 where pk2='u';
insert ignore into t1 select 2, pk2, pk3, key1, key2 from t1;
select * from t1;
pk1 pk2 pk3 key1 key2
1 u 1 1
1 x 1 1
1 1 1
1 u u 1 1
1 u x 1 1
1 u 1 1
1 x u 1 1
1 x x 1 1
1 x 1 1
2 u 1 1
2 x 1 1
2 1 1
2 u u 1 1
2 u x 1 1
2 u 1 1
2 x u 1 1
2 x x 1 1
2 x 1 1
select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
pk1 pk2 pk3 key1 key2
1 u 1 1
1 x 1 1
1 1 1
1 u u 1 1
1 u x 1 1
1 u 1 1
1 x u 1 1
1 x x 1 1
1 x 1 1
2 u 1 1
2 x 1 1
2 1 1
2 u u 1 1
2 u x 1 1
2 u 1 1
2 x u 1 1
2 x x 1 1
2 x 1 1
alter table t1 drop primary key;
select * from t1;
pk1 pk2 pk3 key1 key2
1 u 1 1
1 x 1 1
1 1 1
1 u u 1 1
1 u x 1 1
1 u 1 1
1 x u 1 1
1 x x 1 1
1 x 1 1
2 u 1 1
2 x 1 1
2 1 1
2 u u 1 1
2 u x 1 1
2 u 1 1
2 x u 1 1
2 x x 1 1
2 x 1 1
select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
pk1 pk2 pk3 key1 key2
1 u 1 1
1 x 1 1
1 1 1
1 u u 1 1
1 u x 1 1
1 u 1 1
1 x u 1 1
1 x x 1 1
1 x 1 1
2 u 1 1
2 x 1 1
2 1 1
2 u u 1 1
2 u x 1 1
2 u 1 1
2 x u 1 1
2 x x 1 1
2 x 1 1
drop table t1;
create table t1 (
pk1 varchar(8) NOT NULL default '',
pk2 varchar(4) NOT NULL default '',
key1 int(11),
key2 int(11),
primary key(pk1, pk2),
KEY key1 (key1),
KEY key2 (key2)
) engine=bdb;
insert into t1 values ('','empt',2,2),
('a','a--a',2,2),
('bb','b--b',2,2),
('ccc','c--c',2,2),
('dddd','d--d',2,2);
select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
pk1 pk2 key1 key2
empt 2 2
a a--a 2 2
bb b--b 2 2
ccc c--c 2 2
dddd d--d 2 2
drop table t1;
mysql-test/r/rowid_order_innodb.result
0 → 100644
View file @
3b29cad0
drop table if exists t1, t2, t3,t4;
create table t1 (
pk1 int not NULL,
key1 int(11),
key2 int(11),
PRIMARY KEY (pk1),
KEY key1 (key1),
KEY key2 (key2)
) engine=innodb;
insert into t1 values (-5, 1, 1),
(-100, 1, 1),
(3, 1, 1),
(0, 1, 1),
(10, 1, 1);
explain select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index_merge key1,key2 key1,key2 5,5 NULL 4 Using where
select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
pk1 key1 key2
-100 1 1
-5 1 1
0 1 1
3 1 1
10 1 1
drop table t1;
create table t1 (
pk1 int unsigned not NULL,
key1 int(11),
key2 int(11),
PRIMARY KEY (pk1),
KEY key1 (key1),
KEY key2 (key2)
) engine=innodb;
insert into t1 values (0, 1, 1),
(0xFFFFFFFF, 1, 1),
(0xFFFFFFFE, 1, 1),
(1, 1, 1),
(2, 1, 1);
select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
pk1 key1 key2
0 1 1
1 1 1
2 1 1
4294967294 1 1
4294967295 1 1
drop table t1;
create table t1 (
pk1 char(4) not NULL,
key1 int(11),
key2 int(11),
PRIMARY KEY (pk1),
KEY key1 (key1),
KEY key2 (key2)
) engine=innodb collate latin2_general_ci;
insert into t1 values ('a1', 1, 1),
('b2', 1, 1),
('A3', 1, 1),
('B4', 1, 1);
select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
pk1 key1 key2
a1 1 1
A3 1 1
b2 1 1
B4 1 1
drop table t1;
create table t1 (
pk1 int not NULL,
pk2 char(4) not NULL collate latin1_german1_ci,
pk3 char(4) not NULL collate latin1_bin,
key1 int(11),
key2 int(11),
PRIMARY KEY (pk1,pk2,pk3),
KEY key1 (key1),
KEY key2 (key2)
) engine=innodb;
insert into t1 values
(1, 'u', 'u', 1, 1),
(1, 'u', char(0xEC), 1, 1),
(1, 'u', 'x', 1, 1);
insert ignore into t1 select pk1, char(0xEC), pk3, key1, key2 from t1;
insert ignore into t1 select pk1, 'x', pk3, key1, key2 from t1 where pk2='u';
insert ignore into t1 select 2, pk2, pk3, key1, key2 from t1;
select * from t1;
pk1 pk2 pk3 key1 key2
1 u 1 1
1 x 1 1
1 1 1
1 u u 1 1
1 u x 1 1
1 u 1 1
1 x u 1 1
1 x x 1 1
1 x 1 1
2 u 1 1
2 x 1 1
2 1 1
2 u u 1 1
2 u x 1 1
2 u 1 1
2 x u 1 1
2 x x 1 1
2 x 1 1
select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
pk1 pk2 pk3 key1 key2
1 u 1 1
1 x 1 1
1 1 1
1 u u 1 1
1 u x 1 1
1 u 1 1
1 x u 1 1
1 x x 1 1
1 x 1 1
2 u 1 1
2 x 1 1
2 1 1
2 u u 1 1
2 u x 1 1
2 u 1 1
2 x u 1 1
2 x x 1 1
2 x 1 1
alter table t1 drop primary key;
select * from t1;
pk1 pk2 pk3 key1 key2
1 u 1 1
1 x 1 1
1 1 1
1 u u 1 1
1 u x 1 1
1 u 1 1
1 x u 1 1
1 x x 1 1
1 x 1 1
2 u 1 1
2 x 1 1
2 1 1
2 u u 1 1
2 u x 1 1
2 u 1 1
2 x u 1 1
2 x x 1 1
2 x 1 1
select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
pk1 pk2 pk3 key1 key2
1 u 1 1
1 x 1 1
1 1 1
1 u u 1 1
1 u x 1 1
1 u 1 1
1 x u 1 1
1 x x 1 1
1 x 1 1
2 u 1 1
2 x 1 1
2 1 1
2 u u 1 1
2 u x 1 1
2 u 1 1
2 x u 1 1
2 x x 1 1
2 x 1 1
drop table t1;
create table t1 (
pk1 varchar(8) NOT NULL default '',
pk2 varchar(4) NOT NULL default '',
key1 int(11),
key2 int(11),
primary key(pk1, pk2),
KEY key1 (key1),
KEY key2 (key2)
) engine=innodb;
insert into t1 values ('','empt',2,2),
('a','a--a',2,2),
('bb','b--b',2,2),
('ccc','c--c',2,2),
('dddd','d--d',2,2);
select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
pk1 pk2 key1 key2
empt 2 2
a a--a 2 2
bb b--b 2 2
ccc c--c 2 2
dddd d--d 2 2
drop table t1;
mysql-test/t/index_merge_ror.test
0 → 100644
View file @
3b29cad0
#
# ROR-index_merge tests.
#
--
disable_warnings
drop
table
if
exists
t1
,
t0
;
--
enable_warnings
--
disable_query_log
create
table
t1
(
/* Field names reflect value(rowid) distribution, st=STairs, swt= SaWTooth */
st_a
int
not
null
,
swt1a
int
not
null
,
swt2a
int
not
null
,
st_b
int
not
null
,
swt1b
int
not
null
,
swt2b
int
not
null
,
/* fields/keys for row retrieval tests */
key1
int
,
key2
int
,
key3
int
,
key4
int
,
/* make rows much bigger then keys */
filler1
char
(
200
),
filler2
char
(
200
),
filler3
char
(
200
),
filler4
char
(
200
),
filler5
char
(
200
),
filler6
char
(
200
),
/* order of keys is important */
key
sta_swt12a
(
st_a
,
swt1a
,
swt2a
),
key
sta_swt1a
(
st_a
,
swt1a
),
key
sta_swt2a
(
st_a
,
swt2a
),
key
sta_swt21a
(
st_a
,
swt2a
,
swt1a
),
key
st_a
(
st_a
),
key
stb_swt1a_2b
(
st_b
,
swt1b
,
swt2a
),
key
stb_swt1b
(
st_b
,
swt1b
),
key
st_b
(
st_b
),
key
(
key1
),
key
(
key2
),
key
(
key3
),
key
(
key4
)
)
;
# Fill table
create
table
t0
as
select
*
from
t1
;
let
$cnt
=
1000
;
while
(
$cnt
)
{
eval
insert
into
t0
values
(
1
,
2
,
3
,
1
,
2
,
3
,
0
,
0
,
0
,
0
,
'data1'
,
'data2'
,
'data3'
,
'data4'
,
'data5'
,
'data6'
);
dec
$cnt
;
}
alter
table
t1
disable
keys
;
let
$
1
=
4
;
while
(
$
1
)
{
let
$
2
=
4
;
while
(
$
2
)
{
let
$
3
=
4
;
while
(
$
3
)
{
eval
insert
into
t1
select
$
1
,
$
2
,
$
3
,
$
1
,
$
2
,
$
3
,
key1
,
key2
,
key3
,
key4
,
filler1
,
filler2
,
filler3
,
filler4
,
filler5
,
filler6
from
t0
;
dec
$
3
;
}
dec
$
2
;
}
dec
$
1
;
}
# Row retrieval tests
# -1 is used for values 'out of any range we are using'
# insert enough rows for index intersection to be used for (key1,key2)
insert
into
t1
(
key1
,
key2
,
key3
,
key4
,
filler1
)
values
(
100
,
100
,
100
,
100
,
'key1-key2-key3-key4'
);
let
$cnt
=
400
;
while
(
$cnt
)
{
eval
insert
into
t1
(
key1
,
key2
,
key3
,
key4
,
filler1
)
values
(
100
,
-
1
,
100
,
-
1
,
'key1-key3'
);
dec
$cnt
;
}
let
$cnt
=
400
;
while
(
$cnt
)
{
eval
insert
into
t1
(
key1
,
key2
,
key3
,
key4
,
filler1
)
values
(
-
1
,
100
,
-
1
,
100
,
'key2-key4'
);
dec
$cnt
;
}
alter
table
t1
enable
keys
;
--
enable_query_log
select
count
(
*
)
from
t1
;
# One row results tests for cases where a single row matches all conditions
explain
select
key1
,
key2
from
t1
where
key1
=
100
and
key2
=
100
;
select
key1
,
key2
from
t1
where
key1
=
100
and
key2
=
100
;
explain
select
key1
,
key2
,
key3
,
key4
,
filler1
from
t1
where
key1
=
100
and
key2
=
100
or
key3
=
100
and
key4
=
100
;
select
key1
,
key2
,
key3
,
key4
,
filler1
from
t1
where
key1
=
100
and
key2
=
100
or
key3
=
100
and
key4
=
100
;
# Several-rows results
insert
into
t1
(
key1
,
key2
,
key3
,
key4
,
filler1
)
values
(
100
,
100
,
-
1
,
-
1
,
'key1-key2'
);
insert
into
t1
(
key1
,
key2
,
key3
,
key4
,
filler1
)
values
(
-
1
,
-
1
,
100
,
100
,
'key4-key3'
);
# ROR-intersection, not covering
explain
select
key1
,
key2
,
filler1
from
t1
where
key1
=
100
and
key2
=
100
;
select
key1
,
key2
,
filler1
from
t1
where
key1
=
100
and
key2
=
100
;
# ROR-intersection, covering
explain
select
key1
,
key2
from
t1
where
key1
=
100
and
key2
=
100
;
select
key1
,
key2
from
t1
where
key1
=
100
and
key2
=
100
;
# ROR-union of ROR-intersections
explain
select
key1
,
key2
,
key3
,
key4
from
t1
where
key1
=
100
and
key2
=
100
or
key3
=
100
and
key4
=
100
;
select
key1
,
key2
,
key3
,
key4
from
t1
where
key1
=
100
and
key2
=
100
or
key3
=
100
and
key4
=
100
;
explain
select
key1
,
key2
,
key3
,
key4
,
filler1
from
t1
where
key1
=
100
and
key2
=
100
or
key3
=
100
and
key4
=
100
;
select
key1
,
key2
,
key3
,
key4
,
filler1
from
t1
where
key1
=
100
and
key2
=
100
or
key3
=
100
and
key4
=
100
;
# 3-way ROR-intersection
explain
select
key1
,
key2
,
key3
from
t1
where
key1
=
100
and
key2
=
100
and
key3
=
100
;
select
key1
,
key2
,
key3
from
t1
where
key1
=
100
and
key2
=
100
and
key3
=
100
;
# ROR-union(ROR-intersection, ROR-range)
insert
into
t1
(
key1
,
key2
,
key3
,
key4
,
filler1
)
values
(
101
,
101
,
101
,
101
,
'key1234-101'
);
explain
select
key1
,
key2
,
key3
,
key4
,
filler1
from
t1
where
key1
=
100
and
key2
=
100
or
key3
=
101
;
select
key1
,
key2
,
key3
,
key4
,
filler1
from
t1
where
key1
=
100
and
key2
=
100
or
key3
=
101
;
# Run some ROR updates/deletes
select
key1
,
key2
,
filler1
from
t1
where
key1
=
100
and
key2
=
100
;
update
t1
set
filler1
=
'to be deleted'
where
key1
=
100
and
key2
=
100
;
update
t1
set
key1
=
200
,
key2
=
200
where
key1
=
100
and
key2
=
100
;
delete
from
t1
where
key1
=
200
and
key2
=
200
;
select
key1
,
key2
,
filler1
from
t1
where
key2
=
100
and
key2
=
200
;
# ROR-union(ROR-intersection) with one of ROR-intersection giving empty
# results
explain
select
key1
,
key2
,
key3
,
key4
,
filler1
from
t1
where
key1
=
100
and
key2
=
100
or
key3
=
100
and
key4
=
100
;
select
key1
,
key2
,
key3
,
key4
,
filler1
from
t1
where
key1
=
100
and
key2
=
100
or
key3
=
100
and
key4
=
100
;
delete
from
t1
where
key3
=
100
and
key4
=
100
;
# ROR-union with all ROR-intersections giving empty results
explain
select
key1
,
key2
,
key3
,
key4
,
filler1
from
t1
where
key1
=
100
and
key2
=
100
or
key3
=
100
and
key4
=
100
;
select
key1
,
key2
,
key3
,
key4
,
filler1
from
t1
where
key1
=
100
and
key2
=
100
or
key3
=
100
and
key4
=
100
;
# ROR-intersection with empty result
explain
select
key1
,
key2
from
t1
where
key1
=
100
and
key2
=
100
;
select
key1
,
key2
from
t1
where
key1
=
100
and
key2
=
100
;
# ROR-union tests with various cases.
# All scans returning duplicate rows:
insert
into
t1
(
key1
,
key2
,
key3
,
key4
,
filler1
)
values
(
100
,
100
,
200
,
200
,
'key1-key2-key3-key4-1'
);
insert
into
t1
(
key1
,
key2
,
key3
,
key4
,
filler1
)
values
(
100
,
100
,
200
,
200
,
'key1-key2-key3-key4-2'
);
insert
into
t1
(
key1
,
key2
,
key3
,
key4
,
filler1
)
values
(
100
,
100
,
200
,
200
,
'key1-key2-key3-key4-3'
);
explain
select
key1
,
key2
,
key3
,
key4
,
filler1
from
t1
where
key3
=
200
or
(
key1
=
100
and
key2
=
100
)
or
key4
=
200
;
select
key1
,
key2
,
key3
,
key4
,
filler1
from
t1
where
key3
=
200
or
(
key1
=
100
and
key2
=
100
)
or
key4
=
200
;
insert
into
t1
(
key1
,
key2
,
key3
,
key4
,
filler1
)
values
(
-
1
,
-
1
,
-
1
,
200
,
'key4'
);
explain
select
key1
,
key2
,
key3
,
key4
,
filler1
from
t1
where
key3
=
200
or
(
key1
=
100
and
key2
=
100
)
or
key4
=
200
;
select
key1
,
key2
,
key3
,
key4
,
filler1
from
t1
where
key3
=
200
or
(
key1
=
100
and
key2
=
100
)
or
key4
=
200
;
insert
into
t1
(
key1
,
key2
,
key3
,
key4
,
filler1
)
values
(
-
1
,
-
1
,
200
,
-
1
,
'key3'
);
explain
select
key1
,
key2
,
key3
,
key4
,
filler1
from
t1
where
key3
=
200
or
(
key1
=
100
and
key2
=
100
)
or
key4
=
200
;
select
key1
,
key2
,
key3
,
key4
,
filler1
from
t1
where
key3
=
200
or
(
key1
=
100
and
key2
=
100
)
or
key4
=
200
;
##
## Optimizer tests
##
# Check that the shortest key is used for ROR-intersection, covering and non-covering.
explain
select
*
from
t1
where
st_a
=
1
and
st_b
=
1
;
explain
select
st_a
,
st_b
from
t1
where
st_a
=
1
and
st_b
=
1
;
# Check if "ingore index" syntax works
explain
select
st_a
from
t1
ignore
index
(
st_a
)
where
st_a
=
1
and
st_b
=
1
;
# Do many tests
# Check that keys that don't improve selectivity are skipped.
#
explain
select
*
from
t1
where
st_a
=
1
and
swt1a
=
1
and
swt2a
=
1
;
explain
select
*
from
t1
where
st_b
=
1
and
swt1b
=
1
and
swt2b
=
1
;
explain
select
*
from
t1
where
st_a
=
1
and
swt1a
=
1
and
swt2a
=
1
and
st_b
=
1
and
swt1b
=
1
and
swt2b
=
1
;
explain
select
*
from
t1
ignore
index
(
sta_swt21a
,
stb_swt1a_2b
)
where
st_a
=
1
and
swt1a
=
1
and
swt2a
=
1
and
st_b
=
1
and
swt1b
=
1
and
swt2b
=
1
;
explain
select
*
from
t1
ignore
index
(
sta_swt21a
,
sta_swt12a
,
stb_swt1a_2b
)
where
st_a
=
1
and
swt1a
=
1
and
swt2a
=
1
and
st_b
=
1
and
swt1b
=
1
and
swt2b
=
1
;
explain
select
*
from
t1
ignore
index
(
sta_swt21a
,
sta_swt12a
,
stb_swt1a_2b
,
stb_swt1b
)
where
st_a
=
1
and
swt1a
=
1
and
swt2a
=
1
and
st_b
=
1
and
swt1b
=
1
and
swt2b
=
1
;
explain
select
*
from
t1
where
st_a
=
1
and
swt1a
=
1
and
swt2a
=
1
and
st_b
=
1
and
swt1b
=
1
;
explain
select
*
from
t1
where
st_a
=
1
and
swt1a
=
1
and
st_b
=
1
and
swt1b
=
1
and
swt1b
=
1
;
explain
select
st_a
from
t1
where
st_a
=
1
and
swt1a
=
1
and
st_b
=
1
and
swt1b
=
1
and
swt1b
=
1
;
explain
select
st_a
from
t1
where
st_a
=
1
and
swt1a
=
1
and
st_b
=
1
and
swt1b
=
1
and
swt1b
=
1
;
drop
table
t0
,
t1
;
mysql-test/t/index_merge_ror_cpk.test
0 → 100644
View file @
3b29cad0
#
# Clustered PK ROR-index_merge tests
#
--
source
include
/
have_innodb
.
inc
--
disable_warnings
drop
table
if
exists
t1
;
--
enable_warnings
create
table
t1
(
pk1
int
not
null
,
pk2
int
not
null
,
key1
int
not
null
,
key2
int
not
null
,
pktail1ok
int
not
null
,
pktail2ok
int
not
null
,
pktail3bad
int
not
null
,
pktail4bad
int
not
null
,
pktail5bad
int
not
null
,
pk2copy
int
not
null
,
badkey
int
not
null
,
filler1
char
(
200
),
filler2
char
(
200
),
key
(
key1
),
key
(
key2
),
/* keys with tails from CPK members */
key
(
pktail1ok
,
pk1
),
key
(
pktail2ok
,
pk1
,
pk2
),
key
(
pktail3bad
,
pk2
,
pk1
),
key
(
pktail4bad
,
pk1
,
pk2copy
),
key
(
pktail5bad
,
pk1
,
pk2
,
pk2copy
),
primary
key
(
pk1
,
pk2
)
)
engine
=
innodb
;
--
disable_query_log
set
autocommit
=
0
;
let
$
1
=
10000
;
while
(
$
1
)
{
eval
insert
into
t1
values
(
$
1
div
10
,
$
1
mod
100
,
$
1
/
100
,
$
1
/
100
,
$
1
/
100
,
$
1
/
100
,
$
1
/
100
,
$
1
/
100
,
$
1
/
100
,
$
1
mod
100
,
$
1
/
1000
,
'filler-data-$1'
,
'filler2'
);
dec
$
1
;
}
set
autocommit
=
1
;
--
enable_query_log
# Verify that range scan on CPK is ROR
# (use index_intersection because it is impossible to check that for index union)
explain
select
*
from
t1
where
pk1
=
1
and
pk2
<
80
and
key1
=
0
;
# CPK scan + 1 ROR range scan is a special case
select
*
from
t1
where
pk1
=
1
and
pk2
<
80
and
key1
=
0
;
# Verify that CPK fields are considered to be covered by index scans
explain
select
pk1
,
pk2
from
t1
where
key1
=
10
and
key2
=
10
and
2
*
pk1
+
1
<
2
*
96
+
1
;
select
pk1
,
pk2
from
t1
where
key1
=
10
and
key2
=
10
and
2
*
pk1
+
1
<
2
*
96
+
1
;
# Verify that CPK is always used for index intersection scans
# (this is because it is used as a filter, not for retrieval)
explain
select
*
from
t1
where
badkey
=
1
and
key1
=
10
;
explain
select
*
from
t1
where
pk1
<
7500
and
key1
=
10
;
# Verify that keys with 'tails' of PK members are ok.
explain
select
*
from
t1
where
pktail1ok
=
1
and
key1
=
10
;
explain
select
*
from
t1
where
pktail2ok
=
1
and
key1
=
10
;
explain
select
*
from
t1
where
pktail3bad
=
1
and
key1
=
10
;
explain
select
*
from
t1
where
pktail4bad
=
1
and
key1
=
10
;
explain
select
*
from
t1
where
pktail5bad
=
1
and
key1
=
10
;
# Test for problem with innodb key values prefetch buffer:
explain
select
pk1
,
pk2
,
key1
,
key2
from
t1
where
key1
=
10
and
key2
=
10
limit
10
;
select
pk1
,
pk2
,
key1
,
key2
from
t1
where
key1
=
10
and
key2
=
10
limit
10
;
drop
table
t1
;
mysql-test/t/rowid_order_bdb.test
0 → 100644
View file @
3b29cad0
#
# Test for rowid ordering (and comparison) functions.
# do index_merge select for tables with PK of various types.
#
--
disable_warnings
drop
table
if
exists
t1
,
t2
,
t3
,
t4
;
--
enable_warnings
--
source
include
/
have_bdb
.
inc
# Signed number as rowid
create
table
t1
(
pk1
int
not
NULL
,
key1
int
(
11
),
key2
int
(
11
),
PRIMARY
KEY
(
pk1
),
KEY
key1
(
key1
),
KEY
key2
(
key2
)
)
engine
=
bdb
;
insert
into
t1
values
(
-
5
,
1
,
1
),
(
-
100
,
1
,
1
),
(
3
,
1
,
1
),
(
0
,
1
,
1
),
(
10
,
1
,
1
);
explain
select
*
from
t1
force
index
(
key1
,
key2
)
where
key1
<
3
or
key2
<
3
;
select
*
from
t1
force
index
(
key1
,
key2
)
where
key1
<
3
or
key2
<
3
;
drop
table
t1
;
# Unsigned numbers as rowids
create
table
t1
(
pk1
int
unsigned
not
NULL
,
key1
int
(
11
),
key2
int
(
11
),
PRIMARY
KEY
(
pk1
),
KEY
key1
(
key1
),
KEY
key2
(
key2
)
)
engine
=
bdb
;
insert
into
t1
values
(
0
,
1
,
1
),
(
0xFFFFFFFF
,
1
,
1
),
(
0xFFFFFFFE
,
1
,
1
),
(
1
,
1
,
1
),
(
2
,
1
,
1
);
select
*
from
t1
force
index
(
key1
,
key2
)
where
key1
<
3
or
key2
<
3
;
drop
table
t1
;
# Case-insensitive char(N)
create
table
t1
(
pk1
char
(
4
)
not
NULL
,
key1
int
(
11
),
key2
int
(
11
),
PRIMARY
KEY
(
pk1
),
KEY
key1
(
key1
),
KEY
key2
(
key2
)
)
engine
=
bdb
collate
latin2_general_ci
;
insert
into
t1
values
(
'a1'
,
1
,
1
),
(
'b2'
,
1
,
1
),
(
'A3'
,
1
,
1
),
(
'B4'
,
1
,
1
);
select
*
from
t1
force
index
(
key1
,
key2
)
where
key1
<
3
or
key2
<
3
;
drop
table
t1
;
# Multi-part PK
create
table
t1
(
pk1
int
not
NULL
,
pk2
char
(
4
)
not
NULL
collate
latin1_german1_ci
,
pk3
char
(
4
)
not
NULL
collate
latin1_bin
,
key1
int
(
11
),
key2
int
(
11
),
PRIMARY
KEY
(
pk1
,
pk2
,
pk3
),
KEY
key1
(
key1
),
KEY
key2
(
key2
)
)
engine
=
bdb
;
insert
into
t1
values
(
1
,
'u'
,
'u'
,
1
,
1
),
(
1
,
'u'
,
char
(
0xEC
),
1
,
1
),
(
1
,
'u'
,
'x'
,
1
,
1
);
insert
ignore
into
t1
select
pk1
,
char
(
0xEC
),
pk3
,
key1
,
key2
from
t1
;
insert
ignore
into
t1
select
pk1
,
'x'
,
pk3
,
key1
,
key2
from
t1
where
pk2
=
'u'
;
insert
ignore
into
t1
select
2
,
pk2
,
pk3
,
key1
,
key2
from
t1
;
select
*
from
t1
;
select
*
from
t1
force
index
(
key1
,
key2
)
where
key1
<
3
or
key2
<
3
;
# Hidden PK
alter
table
t1
drop
primary
key
;
select
*
from
t1
;
select
*
from
t1
force
index
(
key1
,
key2
)
where
key1
<
3
or
key2
<
3
;
drop
table
t1
;
# Variable-length PK
# this is also test for Bug#2688
create
table
t1
(
pk1
varchar
(
8
)
NOT
NULL
default
''
,
pk2
varchar
(
4
)
NOT
NULL
default
''
,
key1
int
(
11
),
key2
int
(
11
),
primary
key
(
pk1
,
pk2
),
KEY
key1
(
key1
),
KEY
key2
(
key2
)
)
engine
=
bdb
;
insert
into
t1
values
(
''
,
'empt'
,
2
,
2
),
(
'a'
,
'a--a'
,
2
,
2
),
(
'bb'
,
'b--b'
,
2
,
2
),
(
'ccc'
,
'c--c'
,
2
,
2
),
(
'dddd'
,
'd--d'
,
2
,
2
);
select
*
from
t1
force
index
(
key1
,
key2
)
where
key1
<
3
or
key2
<
3
;
drop
table
t1
;
mysql-test/t/rowid_order_innodb.test
0 → 100644
View file @
3b29cad0
#
# Test for rowid ordering (and comparison) functions.
# do index_merge select for tables with PK of various types.
#
--
disable_warnings
drop
table
if
exists
t1
,
t2
,
t3
,
t4
;
--
enable_warnings
--
source
include
/
have_innodb
.
inc
# Signed number as rowid
create
table
t1
(
pk1
int
not
NULL
,
key1
int
(
11
),
key2
int
(
11
),
PRIMARY
KEY
(
pk1
),
KEY
key1
(
key1
),
KEY
key2
(
key2
)
)
engine
=
innodb
;
insert
into
t1
values
(
-
5
,
1
,
1
),
(
-
100
,
1
,
1
),
(
3
,
1
,
1
),
(
0
,
1
,
1
),
(
10
,
1
,
1
);
explain
select
*
from
t1
force
index
(
key1
,
key2
)
where
key1
<
3
or
key2
<
3
;
select
*
from
t1
force
index
(
key1
,
key2
)
where
key1
<
3
or
key2
<
3
;
drop
table
t1
;
# Unsigned numbers as rowids
create
table
t1
(
pk1
int
unsigned
not
NULL
,
key1
int
(
11
),
key2
int
(
11
),
PRIMARY
KEY
(
pk1
),
KEY
key1
(
key1
),
KEY
key2
(
key2
)
)
engine
=
innodb
;
insert
into
t1
values
(
0
,
1
,
1
),
(
0xFFFFFFFF
,
1
,
1
),
(
0xFFFFFFFE
,
1
,
1
),
(
1
,
1
,
1
),
(
2
,
1
,
1
);
select
*
from
t1
force
index
(
key1
,
key2
)
where
key1
<
3
or
key2
<
3
;
drop
table
t1
;
# Case-insensitive char(N)
create
table
t1
(
pk1
char
(
4
)
not
NULL
,
key1
int
(
11
),
key2
int
(
11
),
PRIMARY
KEY
(
pk1
),
KEY
key1
(
key1
),
KEY
key2
(
key2
)
)
engine
=
innodb
collate
latin2_general_ci
;
insert
into
t1
values
(
'a1'
,
1
,
1
),
(
'b2'
,
1
,
1
),
(
'A3'
,
1
,
1
),
(
'B4'
,
1
,
1
);
select
*
from
t1
force
index
(
key1
,
key2
)
where
key1
<
3
or
key2
<
3
;
drop
table
t1
;
# Multi-part PK
create
table
t1
(
pk1
int
not
NULL
,
pk2
char
(
4
)
not
NULL
collate
latin1_german1_ci
,
pk3
char
(
4
)
not
NULL
collate
latin1_bin
,
key1
int
(
11
),
key2
int
(
11
),
PRIMARY
KEY
(
pk1
,
pk2
,
pk3
),
KEY
key1
(
key1
),
KEY
key2
(
key2
)
)
engine
=
innodb
;
insert
into
t1
values
(
1
,
'u'
,
'u'
,
1
,
1
),
(
1
,
'u'
,
char
(
0xEC
),
1
,
1
),
(
1
,
'u'
,
'x'
,
1
,
1
);
insert
ignore
into
t1
select
pk1
,
char
(
0xEC
),
pk3
,
key1
,
key2
from
t1
;
insert
ignore
into
t1
select
pk1
,
'x'
,
pk3
,
key1
,
key2
from
t1
where
pk2
=
'u'
;
insert
ignore
into
t1
select
2
,
pk2
,
pk3
,
key1
,
key2
from
t1
;
select
*
from
t1
;
select
*
from
t1
force
index
(
key1
,
key2
)
where
key1
<
3
or
key2
<
3
;
# Hidden PK
alter
table
t1
drop
primary
key
;
select
*
from
t1
;
select
*
from
t1
force
index
(
key1
,
key2
)
where
key1
<
3
or
key2
<
3
;
drop
table
t1
;
# Variable-length PK
# this is also test for Bug#2688
create
table
t1
(
pk1
varchar
(
8
)
NOT
NULL
default
''
,
pk2
varchar
(
4
)
NOT
NULL
default
''
,
key1
int
(
11
),
key2
int
(
11
),
primary
key
(
pk1
,
pk2
),
KEY
key1
(
key1
),
KEY
key2
(
key2
)
)
engine
=
innodb
;
insert
into
t1
values
(
''
,
'empt'
,
2
,
2
),
(
'a'
,
'a--a'
,
2
,
2
),
(
'bb'
,
'b--b'
,
2
,
2
),
(
'ccc'
,
'c--c'
,
2
,
2
),
(
'dddd'
,
'd--d'
,
2
,
2
);
select
*
from
t1
force
index
(
key1
,
key2
)
where
key1
<
3
or
key2
<
3
;
drop
table
t1
;
mysys/my_bit.c
View file @
3b29cad0
...
...
@@ -71,3 +71,8 @@ uint my_count_bits(ulonglong v)
#endif
}
uint
my_count_bits_ushort
(
ushort
v
)
{
return
nbits
[
v
];
}
mysys/my_bitmap.c
View file @
3b29cad0
...
...
@@ -330,3 +330,59 @@ void bitmap_union(MY_BITMAP *map, const MY_BITMAP *map2)
bitmap_unlock
(
map
);
}
/*
Get number of set bits in the bitmap
*/
uint
bitmap_bits_set
(
const
MY_BITMAP
*
map
)
{
uchar
*
m
=
map
->
bitmap
,
*
end
=
map
->
bitmap
+
map
->
bitmap_size
;
uint
res
=
0
;
DBUG_ASSERT
(
map
->
bitmap
);
bitmap_lock
((
MY_BITMAP
*
)
map
);
while
(
m
<
end
)
{
res
+=
my_count_bits_ushort
(
*
m
++
);
}
bitmap_unlock
((
MY_BITMAP
*
)
map
);
return
res
;
}
/*
Return number of first zero bit or MY_BIT_NONE if all bits are set.
*/
uint
bitmap_get_first
(
const
MY_BITMAP
*
map
)
{
uchar
*
bitmap
=
map
->
bitmap
;
uint
bit_found
=
MY_BIT_NONE
;
uint
bitmap_size
=
map
->
bitmap_size
*
8
;
uint
i
;
DBUG_ASSERT
(
map
->
bitmap
);
bitmap_lock
((
MY_BITMAP
*
)
map
);
for
(
i
=
0
;
i
<
bitmap_size
;
i
++
,
bitmap
++
)
{
if
(
*
bitmap
!=
0xff
)
{
/* Found slot with free bit */
uint
b
;
for
(
b
=
0
;
;
b
++
)
{
if
(
!
(
*
bitmap
&
(
1
<<
b
)))
{
bit_found
=
(
i
*
8
)
+
b
;
break
;
}
}
break
;
/* Found bit */
}
}
bitmap_unlock
((
MY_BITMAP
*
)
map
);
return
bit_found
;
}
sql/ha_berkeley.cc
View file @
3b29cad0
...
...
@@ -2499,4 +2499,29 @@ ha_rows ha_berkeley::estimate_number_of_rows()
return
share
->
rows
+
HA_BERKELEY_EXTRA_ROWS
;
}
int
ha_berkeley
::
cmp_ref
(
const
byte
*
ref1
,
const
byte
*
ref2
)
{
if
(
hidden_primary_key
)
return
memcmp
(
ref1
,
ref2
,
BDB_HIDDEN_PRIMARY_KEY_LENGTH
);
int
result
;
Field
*
field
;
KEY
*
key_info
=
table
->
key_info
+
table
->
primary_key
;
KEY_PART_INFO
*
key_part
=
key_info
->
key_part
;
KEY_PART_INFO
*
end
=
key_part
+
key_info
->
key_parts
;
for
(;
key_part
!=
end
;
key_part
++
)
{
field
=
key_part
->
field
;
result
=
field
->
pack_cmp
((
const
char
*
)
ref1
,
(
const
char
*
)
ref2
,
key_part
->
length
);
if
(
result
)
return
result
;
ref1
+=
field
->
packed_col_length
((
const
char
*
)
ref1
,
key_part
->
length
);
ref2
+=
field
->
packed_col_length
((
const
char
*
)
ref2
,
key_part
->
length
);
}
return
0
;
}
#endif
/* HAVE_BERKELEY_DB */
sql/ha_berkeley.h
View file @
3b29cad0
...
...
@@ -169,6 +169,7 @@ class ha_berkeley: public handler
void
print_error
(
int
error
,
myf
errflag
);
uint8
table_cache_type
()
{
return
HA_CACHE_TBL_TRANSACT
;
}
bool
primary_key_is_clustered
()
{
return
true
;
}
int
cmp_ref
(
const
byte
*
ref1
,
const
byte
*
ref2
);
};
extern
bool
berkeley_shared_data
;
...
...
sql/ha_heap.h
View file @
3b29cad0
...
...
@@ -95,5 +95,10 @@ class ha_heap: public handler
THR_LOCK_DATA
**
store_lock
(
THD
*
thd
,
THR_LOCK_DATA
**
to
,
enum
thr_lock_type
lock_type
);
int
cmp_ref
(
const
byte
*
ref1
,
const
byte
*
ref2
)
{
HEAP_PTR
ptr1
=*
(
HEAP_PTR
*
)
ref1
;
HEAP_PTR
ptr2
=*
(
HEAP_PTR
*
)
ref2
;
return
ptr1
<
ptr2
?
-
1
:
(
ptr1
>
ptr2
?
1
:
0
);
}
};
sql/ha_innodb.cc
View file @
3b29cad0
...
...
@@ -709,6 +709,8 @@ ha_innobase::init_table_handle_for_HANDLER(void)
prebuilt
->
read_just_key
=
FALSE
;
prebuilt
->
used_in_HANDLER
=
TRUE
;
prebuilt
->
keep_other_fields_on_keyread
=
FALSE
;
}
/*************************************************************************
...
...
@@ -4515,9 +4517,11 @@ ha_innobase::extra(
if
(
prebuilt
->
blob_heap
)
{
row_mysql_prebuilt_free_blob_heap
(
prebuilt
);
}
prebuilt
->
keep_other_fields_on_keyread
=
0
;
prebuilt
->
read_just_key
=
0
;
break
;
case
HA_EXTRA_RESET_STATE
:
prebuilt
->
keep_other_fields_on_keyread
=
0
;
prebuilt
->
read_just_key
=
0
;
break
;
case
HA_EXTRA_NO_KEYREAD
:
...
...
@@ -4536,6 +4540,9 @@ ha_innobase::extra(
case
HA_EXTRA_KEYREAD
:
prebuilt
->
read_just_key
=
1
;
break
;
case
HA_EXTRA_KEYREAD_PRESERVE_FIELDS
:
prebuilt
->
keep_other_fields_on_keyread
=
1
;
break
;
default:
/* Do nothing */
;
}
...
...
@@ -4594,6 +4601,7 @@ ha_innobase::start_stmt(
prebuilt
->
sql_stat_start
=
TRUE
;
prebuilt
->
hint_need_to_fetch_extra_cols
=
0
;
prebuilt
->
read_just_key
=
0
;
prebuilt
->
keep_other_fields_on_keyread
=
FALSE
;
if
(
!
prebuilt
->
mysql_has_locked
)
{
/* This handle is for a temporary table created inside
...
...
@@ -4672,6 +4680,7 @@ ha_innobase::external_lock(
prebuilt
->
hint_need_to_fetch_extra_cols
=
0
;
prebuilt
->
read_just_key
=
0
;
prebuilt
->
keep_other_fields_on_keyread
=
FALSE
;
if
(
lock_type
==
F_WRLCK
)
{
...
...
@@ -5074,4 +5083,52 @@ ha_innobase::get_auto_increment()
return
(
nr
);
}
int
ha_innobase
::
cmp_ref
(
const
mysql_byte
*
ref1
,
const
mysql_byte
*
ref2
)
{
row_prebuilt_t
*
prebuilt
=
(
row_prebuilt_t
*
)
innobase_prebuilt
;
enum_field_types
mysql_type
;
Field
*
field
;
int
result
;
if
(
prebuilt
->
clust_index_was_generated
)
return
memcmp
(
ref1
,
ref2
,
DATA_ROW_ID_LEN
);
/* Do type-aware comparison of Primary Key members. PK members
are always NOT NULL, so no checks for NULL are performed */
KEY_PART_INFO
*
key_part
=
table
->
key_info
[
table
->
primary_key
].
key_part
;
KEY_PART_INFO
*
key_part_end
=
key_part
+
table
->
key_info
[
table
->
primary_key
].
key_parts
;
for
(;
key_part
!=
key_part_end
;
++
key_part
)
{
field
=
key_part
->
field
;
mysql_type
=
field
->
type
();
if
(
mysql_type
==
FIELD_TYPE_TINY_BLOB
||
mysql_type
==
FIELD_TYPE_MEDIUM_BLOB
||
mysql_type
==
FIELD_TYPE_BLOB
||
mysql_type
==
FIELD_TYPE_LONG_BLOB
)
{
ut_a
(
!
ref1
[
1
]);
ut_a
(
!
ref2
[
1
]);
byte
len1
=
*
ref1
;
byte
len2
=
*
ref2
;
ref1
+=
2
;
ref2
+=
2
;
result
=
((
Field_blob
*
)
field
)
->
cmp
((
const
char
*
)
ref1
,
len1
,
(
const
char
*
)
ref2
,
len2
);
}
else
{
result
=
field
->
cmp
((
const
char
*
)
ref1
,
(
const
char
*
)
ref2
);
}
if
(
result
)
return
result
;
ref1
+=
key_part
->
length
;
ref2
+=
key_part
->
length
;
}
return
0
;
}
#endif
/* HAVE_INNOBASE_DB */
sql/ha_innodb.h
View file @
3b29cad0
...
...
@@ -188,6 +188,7 @@ class ha_innobase: public handler
longlong
get_auto_increment
();
uint8
table_cache_type
()
{
return
HA_CACHE_TBL_ASKTRANSACT
;
}
bool
primary_key_is_clustered
()
{
return
true
;
}
int
cmp_ref
(
const
byte
*
ref1
,
const
byte
*
ref2
);
};
extern
uint
innobase_init_flags
,
innobase_lock_type
;
...
...
sql/handler.h
View file @
3b29cad0
...
...
@@ -389,6 +389,11 @@ public:
false otherwise
*/
virtual
bool
primary_key_is_clustered
()
{
return
false
;
}
virtual
int
cmp_ref
(
const
byte
*
ref1
,
const
byte
*
ref2
)
{
return
memcmp
(
ref1
,
ref2
,
ref_length
);
}
};
/* Some extern variables used with handlers */
...
...
sql/opt_range.cc
View file @
3b29cad0
This diff is collapsed.
Click to expand it.
sql/opt_range.h
View file @
3b29cad0
...
...
@@ -79,10 +79,12 @@ public:
TABLE
*
head
;
/*
the only index this quick select uses, or MAX_KEY for
QUICK_INDEX_MERGE_SELECT
index this quick select uses, or MAX_KEY for quick selects
that use several indexes
*/
uint
index
;
/* applicable iff index!= MAX_KEY */
uint
max_used_key_length
,
used_key_parts
;
QUICK_SELECT_I
();
...
...
@@ -106,13 +108,50 @@ public:
QS_TYPE_RANGE
=
0
,
QS_TYPE_INDEX_MERGE
=
1
,
QS_TYPE_RANGE_DESC
=
2
,
QS_TYPE_FULLTEXT
=
3
QS_TYPE_FULLTEXT
=
3
,
QS_TYPE_ROR_INTERSECT
=
4
,
QS_TYPE_ROR_UNION
=
5
,
};
/* Get type of this quick select - one of the QS_* values */
/* Get type of this quick select - one of the QS_
TYPE_
* values */
virtual
int
get_type
()
=
0
;
/*
Initialize this quick select as a child of a index union or intersection
scan. This call replaces init() call.
*/
virtual
int
init_ror_child_scan
(
bool
reuse_handler
)
{
DBUG_ASSERT
(
0
);
return
1
;
}
virtual
void
cleanup_ror_child_scan
()
{
DBUG_ASSERT
(
0
);
}
virtual
void
save_last_pos
(){};
/*
Fill key_names with list of keys this quick select used;
fill used_lenghth with correponding used lengths.
This is used by select_describe.
*/
virtual
void
fill_keys_and_lengths
(
String
*
key_names
,
String
*
used_lengths
)
=
0
;
virtual
bool
check_if_keys_used
(
List
<
Item
>
*
fields
);
/*
rowid of last row retrieved by this quick select. This is used only
when doing ROR-index_merge selects
*/
byte
*
last_rowid
;
byte
*
record
;
#ifndef DBUG_OFF
/*
Print quick select information to DBUG_FILE. Caller is responsible
for locking DBUG_FILE before this call and unlocking it afterwards.
*/
virtual
void
dbug_dump
(
int
indent
,
bool
verbose
)
=
0
;
#endif
};
struct
st_qsel_param
;
class
SEL_ARG
;
...
...
@@ -122,11 +161,11 @@ protected:
bool
next
,
dont_free
;
public:
int
error
;
protected:
handler
*
file
;
byte
*
record
;
bool
free_file
;
/* if true, this quick select "owns" file and will free it */
protected:
friend
void
print_quick_sel_range
(
QUICK_RANGE_SELECT
*
quick
,
const
key_map
*
needed_reg
);
friend
QUICK_RANGE_SELECT
*
get_quick_select_for_ref
(
THD
*
thd
,
TABLE
*
table
,
struct
st_table_ref
*
ref
);
...
...
@@ -140,17 +179,19 @@ protected:
MEM_ROOT
*
alloc
);
friend
class
QUICK_SELECT_DESC
;
friend
class
QUICK_INDEX_MERGE_SELECT
;
friend
class
QUICK_ROR_INTERSECT_SELECT
;
DYNAMIC_ARRAY
ranges
;
/* ordered array of range ptrs */
QUICK_RANGE
**
cur_range
;
/* current element in ranges */
QUICK_RANGE
*
range
;
MEM_ROOT
alloc
;
KEY_PART
*
key_parts
;
int
cmp_next
(
QUICK_RANGE
*
range
);
int
cmp_prev
(
QUICK_RANGE
*
range
);
bool
row_in_ranges
();
public:
MEM_ROOT
alloc
;
QUICK_RANGE_SELECT
(
THD
*
thd
,
TABLE
*
table
,
uint
index_arg
,
bool
no_alloc
=
0
,
MEM_ROOT
*
parent_alloc
=
NULL
);
~
QUICK_RANGE_SELECT
();
...
...
@@ -166,7 +207,16 @@ public:
int
get_next
();
bool
reverse_sorted
()
{
return
0
;
}
bool
unique_key_range
();
int
init_ror_child_scan
(
bool
reuse_handler
);
void
save_last_pos
()
{
file
->
position
(
record
);
};
int
get_type
()
{
return
QS_TYPE_RANGE
;
}
void
fill_keys_and_lengths
(
String
*
key_names
,
String
*
used_lengths
);
#ifndef DBUG_OFF
virtual
void
dbug_dump
(
int
indent
,
bool
verbose
);
#endif
};
...
...
@@ -241,6 +291,11 @@ public:
bool
reverse_sorted
()
{
return
false
;
}
bool
unique_key_range
()
{
return
false
;
}
int
get_type
()
{
return
QS_TYPE_INDEX_MERGE
;
}
void
fill_keys_and_lengths
(
String
*
key_names
,
String
*
used_lengths
);
bool
check_if_keys_used
(
List
<
Item
>
*
fields
);
#ifndef DBUG_OFF
virtual
void
dbug_dump
(
int
indent
,
bool
verbose
);
#endif
bool
push_quick_back
(
QUICK_RANGE_SELECT
*
quick_sel_range
);
...
...
@@ -251,9 +306,6 @@ public:
List_iterator_fast
<
QUICK_RANGE_SELECT
>
cur_quick_it
;
QUICK_RANGE_SELECT
*
cur_quick_select
;
/* last element in quick_selects list */
QUICK_RANGE_SELECT
*
last_quick_select
;
/* quick select that uses clustered primary key (NULL if none) */
QUICK_RANGE_SELECT
*
pk_quick_select
;
...
...
@@ -271,6 +323,87 @@ public:
READ_RECORD
read_record
;
};
/*
Rowid-Ordered Retrieval (ROR) index intersection quick select.
This quick select produces an intersection of records returned by several
QUICK_RANGE_SELECTs that return data ordered by rowid.
*/
class
QUICK_ROR_INTERSECT_SELECT
:
public
QUICK_SELECT_I
{
public:
QUICK_ROR_INTERSECT_SELECT
(
THD
*
thd
,
TABLE
*
table
,
bool
retrieve_full_rows
,
MEM_ROOT
*
parent_alloc
);
~
QUICK_ROR_INTERSECT_SELECT
();
int
init
();
int
reset
(
void
);
int
get_next
();
bool
reverse_sorted
()
{
return
false
;
}
bool
unique_key_range
()
{
return
false
;
}
int
get_type
()
{
return
QS_TYPE_ROR_INTERSECT
;
}
void
fill_keys_and_lengths
(
String
*
key_names
,
String
*
used_lengths
);
bool
check_if_keys_used
(
List
<
Item
>
*
fields
);
#ifndef DBUG_OFF
virtual
void
dbug_dump
(
int
indent
,
bool
verbose
);
#endif
int
init_ror_child_scan
(
bool
reuse_handler
);
bool
push_quick_back
(
QUICK_RANGE_SELECT
*
quick_sel_range
);
/* range quick selects this intersection consists of */
List
<
QUICK_RANGE_SELECT
>
quick_selects
;
QUICK_RANGE_SELECT
*
cpk_quick
;
MEM_ROOT
alloc
;
THD
*
thd
;
bool
reset_called
;
bool
need_to_fetch_row
;
};
/*
Rowid-Ordered Retrieval index union select.
*/
class
QUICK_ROR_UNION_SELECT
:
public
QUICK_SELECT_I
{
public:
QUICK_ROR_UNION_SELECT
(
THD
*
thd
,
TABLE
*
table
);
~
QUICK_ROR_UNION_SELECT
();
int
init
();
int
reset
(
void
);
int
get_next
();
bool
reverse_sorted
()
{
return
false
;
}
bool
unique_key_range
()
{
return
false
;
}
int
get_type
()
{
return
QS_TYPE_ROR_UNION
;
}
void
fill_keys_and_lengths
(
String
*
key_names
,
String
*
used_lengths
);
bool
check_if_keys_used
(
List
<
Item
>
*
fields
);
#ifndef DBUG_OFF
virtual
void
dbug_dump
(
int
indent
,
bool
verbose
);
#endif
bool
push_quick_back
(
QUICK_SELECT_I
*
quick_sel_range
);
/* range quick selects this index_merge read consists of */
List
<
QUICK_SELECT_I
>
quick_selects
;
QUEUE
queue
;
MEM_ROOT
alloc
;
THD
*
thd
;
byte
*
cur_rowid
;
byte
*
prev_rowid
;
uint
rowid_length
;
bool
reset_called
;
bool
have_prev_rowid
;
private:
static
int
queue_cmp
(
void
*
arg
,
byte
*
val1
,
byte
*
val2
);
};
class
QUICK_SELECT_DESC
:
public
QUICK_RANGE_SELECT
{
public:
...
...
sql/sql_delete.cc
View file @
3b29cad0
...
...
@@ -260,10 +260,10 @@ cleanup:
#define MEM_STRIP_BUF_SIZE current_thd->variables.sortbuff_size
extern
"C"
int
refpos
cmp2
(
void
*
arg
,
const
void
*
a
,
const
void
*
b
)
extern
"C"
int
refpos
_order_cmp
(
void
*
arg
,
const
void
*
a
,
const
void
*
b
)
{
/* arg is a pointer to file->ref_length */
return
memcmp
(
a
,
b
,
*
(
int
*
)
arg
);
handler
*
file
=
(
handler
*
)
arg
;
return
file
->
cmp_ref
((
const
byte
*
)
a
,
(
const
byte
*
)
b
);
}
multi_delete
::
multi_delete
(
THD
*
thd_arg
,
TABLE_LIST
*
dt
,
...
...
@@ -327,8 +327,8 @@ multi_delete::initialize_tables(JOIN *join)
for
(
walk
=
walk
->
next
;
walk
;
walk
=
walk
->
next
)
{
TABLE
*
table
=
walk
->
table
;
*
tempfiles_ptr
++=
new
Unique
(
refpos
cmp2
,
(
void
*
)
&
table
->
file
->
ref_length
,
*
tempfiles_ptr
++=
new
Unique
(
refpos
_order_cmp
,
(
void
*
)
table
->
file
,
table
->
file
->
ref_length
,
MEM_STRIP_BUF_SIZE
);
}
...
...
sql/sql_select.cc
View file @
3b29cad0
...
...
@@ -8025,8 +8025,16 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
}
else
if
(
select
&&
select
->
quick
)
// Range found by opt_range
{
/* assume results are not ordered when index merge is used */
if
(
select
->
quick
->
get_type
()
==
QUICK_SELECT_I
::
QS_TYPE_INDEX_MERGE
)
int
quick_type
=
select
->
quick
->
get_type
();
/*
assume results are not ordered when index merge is used
TODO: sergeyp: Results of all index merge selects actually are ordered
by clustered PK values.
*/
if
(
quick_type
==
QUICK_SELECT_I
::
QS_TYPE_INDEX_MERGE
||
quick_type
==
QUICK_SELECT_I
::
QS_TYPE_ROR_UNION
||
quick_type
==
QUICK_SELECT_I
::
QS_TYPE_ROR_INTERSECT
)
DBUG_RETURN
(
0
);
ref_key
=
select
->
quick
->
index
;
ref_key_parts
=
select
->
quick
->
used_key_parts
;
...
...
@@ -8087,9 +8095,11 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
*/
if
(
!
select
->
quick
->
reverse_sorted
())
{
int
quick_type
=
select
->
quick
->
get_type
();
if
(
table
->
file
->
index_flags
(
ref_key
)
&
HA_NOT_READ_PREFIX_LAST
||
(
select
->
quick
->
get_type
()
==
QUICK_SELECT_I
::
QS_TYPE_INDEX_MERGE
))
quick_type
==
QUICK_SELECT_I
::
QS_TYPE_INDEX_MERGE
||
quick_type
==
QUICK_SELECT_I
::
QS_TYPE_ROR_INTERSECT
||
quick_type
==
QUICK_SELECT_I
::
QS_TYPE_ROR_UNION
)
DBUG_RETURN
(
0
);
// Use filesort
// ORDER BY range_key DESC
...
...
@@ -10067,6 +10077,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
select_result
*
result
=
join
->
result
;
Item
*
item_null
=
new
Item_null
();
CHARSET_INFO
*
cs
=
&
my_charset_latin1
;
int
quick_type
=
-
1
;
DBUG_ENTER
(
"select_describe"
);
DBUG_PRINT
(
"info"
,
(
"Select 0x%lx, type %s, message %s"
,
(
ulong
)
join
->
select_lex
,
join
->
select_lex
->
type
,
...
...
@@ -10112,8 +10123,10 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
cs
));
if
(
tab
->
type
==
JT_ALL
&&
tab
->
select
&&
tab
->
select
->
quick
)
{
if
(
tab
->
select
->
quick
->
get_type
()
==
QUICK_SELECT_I
::
QS_TYPE_INDEX_MERGE
)
quick_type
=
tab
->
select
->
quick
->
get_type
();
if
((
quick_type
==
QUICK_SELECT_I
::
QS_TYPE_INDEX_MERGE
)
||
(
quick_type
==
QUICK_SELECT_I
::
QS_TYPE_ROR_INTERSECT
)
||
(
quick_type
==
QUICK_SELECT_I
::
QS_TYPE_ROR_UNION
))
tab
->
type
=
JT_INDEX_MERGE
;
else
tab
->
type
=
JT_RANGE
;
...
...
@@ -10134,6 +10147,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
strlen
(
join_type_str
[
tab
->
type
]),
cs
));
uint
j
;
/* Build "possible_keys" value and add it to item_list */
if
(
!
tab
->
keys
.
is_clear_all
())
{
for
(
j
=
0
;
j
<
table
->
keys
;
j
++
)
...
...
@@ -10150,6 +10164,8 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
item_list
.
push_back
(
new
Item_string
(
tmp1
.
ptr
(),
tmp1
.
length
(),
cs
));
else
item_list
.
push_back
(
item_null
);
/* Build key,key_len, and ref values and add them to item_list */
if
(
tab
->
ref
.
key_parts
)
{
KEY
*
key_info
=
table
->
key_info
+
tab
->
ref
.
key
;
...
...
@@ -10184,48 +10200,9 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
}
else
if
(
tab
->
select
&&
tab
->
select
->
quick
)
{
if
(
tab
->
select
->
quick
->
get_type
()
==
QUICK_SELECT_I
::
QS_TYPE_INDEX_MERGE
)
{
QUICK_INDEX_MERGE_SELECT
*
quick_imerge
=
(
QUICK_INDEX_MERGE_SELECT
*
)
tab
->
select
->
quick
;
QUICK_RANGE_SELECT
*
quick
;
List_iterator_fast
<
QUICK_RANGE_SELECT
>
it
(
quick_imerge
->
quick_selects
);
while
((
quick
=
it
++
))
{
KEY
*
key_info
=
table
->
key_info
+
quick
->
index
;
register
uint
length
;
if
(
tmp3
.
length
())
tmp3
.
append
(
','
);
tmp3
.
append
(
key_info
->
name
);
if
(
tmp2
.
length
())
tmp2
.
append
(
','
);
length
=
longlong2str
(
quick
->
max_used_key_length
,
keylen_str_buf
,
10
)
-
keylen_str_buf
;
tmp2
.
append
(
keylen_str_buf
,
length
);
}
}
else
{
KEY
*
key_info
=
table
->
key_info
+
tab
->
select
->
quick
->
index
;
register
uint
length
;
tmp3
.
append
(
key_info
->
name
);
length
=
longlong2str
(
tab
->
select
->
quick
->
max_used_key_length
,
keylen_str_buf
,
10
)
-
keylen_str_buf
;
tmp2
.
append
(
keylen_str_buf
,
length
);
}
item_list
.
push_back
(
new
Item_string
(
tmp3
.
ptr
(),
tmp3
.
length
(),
cs
));
tab
->
select
->
quick
->
fill_keys_and_lengths
(
&
tmp2
,
&
tmp3
);
item_list
.
push_back
(
new
Item_string
(
tmp2
.
ptr
(),
tmp2
.
length
(),
cs
));
item_list
.
push_back
(
new
Item_string
(
tmp3
.
ptr
(),
tmp3
.
length
(),
cs
));
item_list
.
push_back
(
item_null
);
}
else
...
...
@@ -10240,6 +10217,9 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
my_bool
key_read
=
table
->
key_read
;
if
(
tab
->
type
==
JT_NEXT
&&
table
->
used_keys
.
is_set
(
tab
->
index
))
key_read
=
1
;
if
(
quick_type
==
QUICK_SELECT_I
::
QS_TYPE_ROR_INTERSECT
&&
!
((
QUICK_ROR_INTERSECT_SELECT
*
)
tab
->
select
->
quick
)
->
need_to_fetch_row
)
key_read
=
1
;
if
(
tab
->
info
)
item_list
.
push_back
(
new
Item_string
(
tab
->
info
,
strlen
(
tab
->
info
),
cs
));
...
...
sql/sql_select.h
View file @
3b29cad0
...
...
@@ -334,7 +334,7 @@ uint find_shortest_key(TABLE *table, const key_map *usable_keys);
int
opt_sum_query
(
TABLE_LIST
*
tables
,
List
<
Item
>
&
all_fields
,
COND
*
conds
);
/* from sql_delete.cc, used by opt_range.cc */
extern
"C"
int
refpos
cmp2
(
void
*
arg
,
const
void
*
a
,
const
void
*
b
);
extern
"C"
int
refpos
_order_cmp
(
void
*
arg
,
const
void
*
a
,
const
void
*
b
);
/* class to copying an field/item to a key struct */
...
...
sql/sql_test.cc
View file @
3b29cad0
...
...
@@ -182,37 +182,8 @@ TEST_join(JOIN *join)
tab
->
select
->
quick_keys
.
print
(
buf
));
else
if
(
tab
->
select
->
quick
)
{
int
quick_type
=
tab
->
select
->
quick
->
get_type
();
if
((
quick_type
==
QUICK_SELECT_I
::
QS_TYPE_RANGE
)
||
(
quick_type
==
QUICK_SELECT_I
::
QS_TYPE_RANGE_DESC
))
{
fprintf
(
DBUG_FILE
,
" quick select used on key %s, length: %d
\n
"
,
form
->
key_info
[
tab
->
select
->
quick
->
index
].
name
,
tab
->
select
->
quick
->
max_used_key_length
);
}
else
if
(
quick_type
==
QUICK_SELECT_I
::
QS_TYPE_INDEX_MERGE
)
{
QUICK_INDEX_MERGE_SELECT
*
quick_imerge
=
(
QUICK_INDEX_MERGE_SELECT
*
)
tab
->
select
->
quick
;
QUICK_RANGE_SELECT
*
quick
;
fprintf
(
DBUG_FILE
,
" index_merge quick select used
\n
"
);
List_iterator_fast
<
QUICK_RANGE_SELECT
>
it
(
quick_imerge
->
quick_selects
);
while
((
quick
=
it
++
))
{
fprintf
(
DBUG_FILE
,
" range quick select: key %s, length: %d
\n
"
,
form
->
key_info
[
quick
->
index
].
name
,
quick
->
max_used_key_length
);
}
}
else
{
fprintf
(
DBUG_FILE
,
" quick select of unknown nature used
\n
"
);
}
fprintf
(
DBUG_FILE
,
" quick select used:
\n
"
);
tab
->
select
->
quick
->
dbug_dump
(
18
,
false
);
}
else
VOID
(
fputs
(
" select used
\n
"
,
DBUG_FILE
));
...
...
sql/sql_update.cc
View file @
3b29cad0
...
...
@@ -175,18 +175,11 @@ int mysql_update(THD *thd,
}
init_ftfuncs
(
thd
,
&
thd
->
lex
->
select_lex
,
1
);
/* Check if we are modifying a key that we are used to search with */
if
(
select
&&
select
->
quick
)
{
if
(
select
->
quick
->
get_type
()
!=
QUICK_SELECT_I
::
QS_TYPE_INDEX_MERGE
)
{
used_index
=
select
->
quick
->
index
;
used_key_is_modified
=
(
!
select
->
quick
->
unique_key_range
()
&&
check_if_key_used
(
table
,
used_index
,
fields
));
}
else
{
used_key_is_modified
=
true
;
}
select
->
quick
->
check_if_keys_used
(
&
fields
));
}
else
if
((
used_index
=
table
->
file
->
key_used_on_scan
)
<
MAX_KEY
)
used_key_is_modified
=
check_if_key_used
(
table
,
used_index
,
fields
);
...
...
@@ -305,6 +298,9 @@ int mysql_update(THD *thd,
if
(
handle_duplicates
==
DUP_IGNORE
)
table
->
file
->
extra
(
HA_EXTRA_IGNORE_DUP_KEY
);
if
(
select
&&
select
->
quick
&&
select
->
quick
->
reset
())
goto
err
;
init_read_record
(
&
info
,
thd
,
table
,
select
,
0
,
1
);
updated
=
found
=
0
;
...
...
@@ -792,26 +788,7 @@ static bool safe_update_on_fly(JOIN_TAB *join_tab, List<Item> *fields)
case
JT_ALL
:
/* If range search on index */
if
(
join_tab
->
quick
)
{
if
(
join_tab
->
quick
->
get_type
()
!=
QUICK_SELECT_I
::
QS_TYPE_INDEX_MERGE
)
{
return
!
check_if_key_used
(
table
,
join_tab
->
quick
->
index
,
*
fields
);
}
else
{
QUICK_INDEX_MERGE_SELECT
*
qsel_imerge
=
(
QUICK_INDEX_MERGE_SELECT
*
)(
join_tab
->
quick
);
List_iterator_fast
<
QUICK_RANGE_SELECT
>
it
(
qsel_imerge
->
quick_selects
);
QUICK_RANGE_SELECT
*
quick
;
while
((
quick
=
it
++
))
{
if
(
check_if_key_used
(
table
,
quick
->
index
,
*
fields
))
return
0
;
}
return
1
;
}
}
return
!
join_tab
->
quick
->
check_if_keys_used
(
fields
);
/* If scanning in clustered key */
if
((
table
->
file
->
table_flags
()
&
HA_PRIMARY_KEY_IN_READ_INDEX
)
&&
table
->
primary_key
<
MAX_KEY
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment