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
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
738728bd
Commit
738728bd
authored
Nov 13, 2003
by
unknown
Browse files
Options
Browse Files
Download
Plain Diff
merging in index_merge (in progress, not yet working)
BitKeeper/etc/logging_ok: auto-union
parents
4696bb41
6e464cc0
Changes
12
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
1232 additions
and
152 deletions
+1232
-152
BitKeeper/etc/logging_ok
BitKeeper/etc/logging_ok
+1
-0
sql/opt_ft.cc
sql/opt_ft.cc
+1
-1
sql/opt_ft.h
sql/opt_ft.h
+4
-5
sql/opt_range.cc
sql/opt_range.cc
+887
-98
sql/opt_range.h
sql/opt_range.h
+175
-17
sql/sql_class.cc
sql/sql_class.cc
+2
-2
sql/sql_list.h
sql/sql_list.h
+7
-0
sql/sql_select.cc
sql/sql_select.cc
+86
-18
sql/sql_select.h
sql/sql_select.h
+3
-2
sql/sql_test.cc
sql/sql_test.cc
+31
-1
sql/sql_union.cc
sql/sql_union.cc
+3
-2
sql/sql_update.cc
sql/sql_update.cc
+32
-6
No files found.
BitKeeper/etc/logging_ok
View file @
738728bd
...
...
@@ -102,6 +102,7 @@ peter@mysql.com
peterg@mysql.com
pgulutzan@linux.local
pmartin@build.mysql2.com
psergey@psergey.(none)
ram@gw.mysql.r18.ru
ram@gw.udmsearch.izhnet.ru
ram@mysql.r18.ru
...
...
sql/opt_ft.cc
View file @
738728bd
...
...
@@ -26,7 +26,7 @@
** Create a FT or QUICK RANGE based on a key
****************************************************************************/
QUICK_SELECT
*
get_ft_or_quick_select_for_ref
(
THD
*
thd
,
TABLE
*
table
,
QUICK_
RANGE_
SELECT
*
get_ft_or_quick_select_for_ref
(
THD
*
thd
,
TABLE
*
table
,
JOIN_TAB
*
tab
)
{
if
(
tab
->
type
==
JT_FT
)
...
...
sql/opt_ft.h
View file @
738728bd
...
...
@@ -24,18 +24,17 @@
#pragma interface
/* gcc class implementation */
#endif
class
FT_SELECT
:
public
QUICK_SELECT
{
class
FT_SELECT
:
public
QUICK_
RANGE_
SELECT
{
public:
TABLE_REF
*
ref
;
FT_SELECT
(
THD
*
thd
,
TABLE
*
table
,
TABLE_REF
*
tref
)
:
QUICK_SELECT
(
thd
,
table
,
tref
->
key
,
1
),
ref
(
tref
)
{
init
();
}
int
init
()
{
return
error
=
file
->
ft_init
();
}
QUICK_RANGE_SELECT
(
thd
,
table
,
tref
->
key
,
1
),
ref
(
tref
)
{
init
();
}
int
get_next
()
{
return
error
=
file
->
ft_read
(
record
);
}
int
get_type
()
{
return
QS_TYPE_FULLTEXT
;
}
};
QUICK_SELECT
*
get_ft_or_quick_select_for_ref
(
THD
*
thd
,
TABLE
*
table
,
QUICK_
RANGE_
SELECT
*
get_ft_or_quick_select_for_ref
(
THD
*
thd
,
TABLE
*
table
,
JOIN_TAB
*
tab
);
#endif
sql/opt_range.cc
View file @
738728bd
This diff is collapsed.
Click to expand it.
sql/opt_range.h
View file @
738728bd
...
...
@@ -65,41 +65,199 @@ class QUICK_RANGE :public Sql_alloc {
}
};
class
INDEX_MERGE
;
class
QUICK_SELECT
{
/*
Quick select interface.
This class is parent for all QUICK_*_SELECT and FT_SELECT classes.
*/
class
QUICK_SELECT_I
{
public:
ha_rows
records
;
/* estimate of # of records to be retrieved */
double
read_time
;
/* time to perform this retrieval */
TABLE
*
head
;
/*
the only index this quick select uses, or MAX_KEY for
QUICK_INDEX_MERGE_SELECT
*/
uint
index
;
uint
max_used_key_length
,
used_key_parts
;
QUICK_SELECT_I
();
virtual
~
QUICK_SELECT_I
(){};
virtual
int
init
()
=
0
;
virtual
void
reset
(
void
)
=
0
;
virtual
int
get_next
()
=
0
;
/* get next record to retrieve */
virtual
bool
reverse_sorted
()
=
0
;
virtual
bool
unique_key_range
()
{
return
false
;
}
enum
{
QS_TYPE_RANGE
=
0
,
QS_TYPE_INDEX_MERGE
=
1
,
QS_TYPE_RANGE_DESC
=
2
,
QS_TYPE_FULLTEXT
=
3
};
/* Get type of this quick select - one of the QS_* values */
virtual
int
get_type
()
=
0
;
};
struct
st_qsel_param
;
class
SEL_ARG
;
class
QUICK_RANGE_SELECT
:
public
QUICK_SELECT_I
{
protected:
bool
next
,
dont_free
;
public:
int
error
;
uint
index
,
max_used_key_length
,
used_key_parts
;
TABLE
*
head
;
handler
*
file
;
byte
*
record
;
protected:
friend
void
print_quick_sel_range
(
QUICK_RANGE_SELECT
*
quick
,
key_map
needed_reg
);
friend
QUICK_RANGE_SELECT
*
get_quick_select_for_ref
(
TABLE
*
table
,
struct
st_table_ref
*
ref
);
friend
bool
get_quick_keys
(
struct
st_qsel_param
*
param
,
QUICK_RANGE_SELECT
*
quick
,
KEY_PART
*
key
,
SEL_ARG
*
key_tree
,
char
*
min_key
,
uint
min_key_flag
,
char
*
max_key
,
uint
max_key_flag
);
friend
QUICK_RANGE_SELECT
*
get_quick_select
(
struct
st_qsel_param
*
,
uint
idx
,
SEL_ARG
*
key_tree
,
MEM_ROOT
*
alloc
);
friend
class
QUICK_SELECT_DESC
;
List
<
QUICK_RANGE
>
ranges
;
List_iterator
<
QUICK_RANGE
>
it
;
QUICK_RANGE
*
range
;
MEM_ROOT
alloc
;
KEY_PART
*
key_parts
;
ha_rows
records
;
double
read_time
;
QUICK_SELECT
(
THD
*
thd
,
TABLE
*
table
,
uint
index_arg
,
bool
no_alloc
=
0
);
virtual
~
QUICK_SELECT
();
void
reset
(
void
)
{
next
=
0
;
it
.
rewind
();
}
int
init
()
{
return
error
=
file
->
index_init
(
index
);
}
virtual
int
get_next
();
virtual
bool
reverse_sorted
()
{
return
0
;
}
QUICK_SELECT
(
THD
*
thd
,
TABLE
*
table
,
uint
index_arg
,
bool
no_alloc
=
0
);
//!!todo: add thd to my ctor below
int
cmp_next
(
QUICK_RANGE
*
range
);
public:
QUICK_RANGE_SELECT
(
TABLE
*
table
,
uint
index_arg
,
bool
no_alloc
=
0
,
MEM_ROOT
*
parent_alloc
=
NULL
);
~
QUICK_RANGE_SELECT
();
void
reset
(
void
)
{
next
=
0
;
it
.
rewind
();
}
int
init
();
int
get_next
();
bool
reverse_sorted
()
{
return
0
;
}
bool
unique_key_range
();
int
get_type
()
{
return
QS_TYPE_RANGE
;
}
};
/*
Helper class for keeping track of rows that have been passed to output
in index_merge access method.
NOTES
Current implementation uses a temporary table to store ROWIDs of rows that
have been passed to output. In the future it might be changed to use more
efficient mechanisms, like Unique class.
*/
class
INDEX_MERGE
{
public:
INDEX_MERGE
(
THD
*
thd_arg
);
~
INDEX_MERGE
();
int
init
(
TABLE
*
table
);
int
check_record_in
();
int
start_last_quick_select
();
int
error
;
private:
/* The only field in temporary table */
class
Item_rowid
:
public
Item_str_func
{
TABLE
*
head
;
/* source table */
public:
Item_rowid
(
TABLE
*
table
)
:
head
(
table
)
{
max_length
=
table
->
file
->
ref_length
;
collation
.
set
(
&
my_charset_bin
);
};
const
char
*
func_name
()
const
{
return
"rowid"
;
}
bool
const_item
()
const
{
return
0
;
}
String
*
val_str
(
String
*
);
void
fix_length_and_dec
()
{}
};
/* Check if record has been processed and save it if it wasn't */
inline
int
put_record
();
/* Check if record has been processed without saving it */
inline
int
check_record
();
/* If true, check_record_in does't store ROWIDs it is passed. */
bool
dont_save
;
THD
*
thd
;
TABLE
*
head
;
/* source table */
TABLE
*
temp_table
;
/* temp. table used for values storage */
TMP_TABLE_PARAM
tmp_table_param
;
/* temp. table creation parameters */
Item_rowid
*
rowid_item
;
/* the only field in temp. table */
List
<
Item
>
fields
;
/* temp. table fields list
(the only element is rowid_item) */
ORDER
order
;
/* key for temp. table (rowid_item) */
};
class
QUICK_SELECT_DESC
:
public
QUICK_SELECT
/*
Index merge quick select.
It is implemented as a container for several QUICK_RANGE_SELECTs.
*/
class
QUICK_INDEX_MERGE_SELECT
:
public
QUICK_SELECT_I
{
public:
QUICK_INDEX_MERGE_SELECT
(
THD
*
thd
,
TABLE
*
table
);
~
QUICK_INDEX_MERGE_SELECT
();
int
init
();
void
reset
(
void
);
int
get_next
();
bool
reverse_sorted
()
{
return
false
;
}
bool
unique_key_range
()
{
return
false
;
}
int
get_type
()
{
return
QS_TYPE_INDEX_MERGE
;
}
bool
push_quick_back
(
QUICK_RANGE_SELECT
*
quick_sel_range
);
/* range quick selects this index_merge read consists of */
List
<
QUICK_RANGE_SELECT
>
quick_selects
;
/* quick select which is currently used for rows retrieval */
List_iterator_fast
<
QUICK_RANGE_SELECT
>
cur_quick_it
;
QUICK_RANGE_SELECT
*
cur_quick_select
;
/*
Last element in quick_selects list.
INDEX_MERGE::start_last_quick_select is called before retrieving
rows for it.
*/
QUICK_RANGE_SELECT
*
last_quick_select
;
/*
Used to keep track of what records have been already passed to output
when doing index_merge access (NULL means no index_merge)
*/
INDEX_MERGE
index_merge
;
MEM_ROOT
alloc
;
};
class
QUICK_SELECT_DESC
:
public
QUICK_RANGE_SELECT
{
public:
QUICK_SELECT_DESC
(
QUICK_SELECT
*
q
,
uint
used_key_parts
);
QUICK_SELECT_DESC
(
QUICK_
RANGE_
SELECT
*
q
,
uint
used_key_parts
);
int
get_next
();
bool
reverse_sorted
()
{
return
1
;
}
int
get_type
()
{
return
QS_TYPE_RANGE_DESC
;
}
private:
int
cmp_prev
(
QUICK_RANGE
*
range
);
bool
range_reads_after_key
(
QUICK_RANGE
*
range
);
...
...
@@ -114,7 +272,7 @@ class QUICK_SELECT_DESC: public QUICK_SELECT
class
SQL_SELECT
:
public
Sql_alloc
{
public:
QUICK_SELECT
*
quick
;
// If quick-select used
QUICK_SELECT
_I
*
quick
;
// If quick-select used
COND
*
cond
;
// where condition
TABLE
*
head
;
IO_CACHE
file
;
// Positions to used records
...
...
@@ -134,7 +292,7 @@ class SQL_SELECT :public Sql_alloc {
ha_rows
limit
,
bool
force_quick_range
=
0
);
};
QUICK_SELECT
*
get_quick_select_for_ref
(
THD
*
thd
,
TABLE
*
table
,
QUICK_
RANGE_
SELECT
*
get_quick_select_for_ref
(
THD
*
thd
,
TABLE
*
table
,
struct
st_table_ref
*
ref
);
#endif
sql/sql_class.cc
View file @
738728bd
...
...
@@ -562,8 +562,8 @@ int THD::send_explain_fields(select_result *result)
item
->
maybe_null
=
1
;
field_list
.
push_back
(
item
=
new
Item_empty_string
(
"key"
,
NAME_LEN
));
item
->
maybe_null
=
1
;
field_list
.
push_back
(
item
=
new
Item_
return_int
(
"key_len"
,
3
,
MYSQL_TYPE_LONGLONG
));
field_list
.
push_back
(
item
=
new
Item_
empty_string
(
"key_len"
,
NAME_LEN
*
MAX_KEY
));
item
->
maybe_null
=
1
;
field_list
.
push_back
(
item
=
new
Item_empty_string
(
"ref"
,
NAME_LEN
*
MAX_REF_PARTS
));
...
...
sql/sql_list.h
View file @
738728bd
...
...
@@ -135,6 +135,12 @@ class base_list :public Sql_alloc
last
=
&
first
;
return
tmp
->
info
;
}
inline
void
concat
(
base_list
*
list
)
{
*
last
=
list
->
first
;
last
=
list
->
last
;
elements
+=
list
->
elements
;
}
inline
list_node
*
last_node
()
{
return
*
last
;
}
inline
list_node
*
first_node
()
{
return
first
;}
inline
void
*
head
()
{
return
first
->
info
;
}
...
...
@@ -255,6 +261,7 @@ template <class T> class List :public base_list
}
empty
();
}
inline
void
concat
(
List
<
T
>
*
list
)
{
base_list
::
concat
(
list
);
}
};
...
...
sql/sql_select.cc
View file @
738728bd
...
...
@@ -32,7 +32,8 @@
const
char
*
join_type_str
[]
=
{
"UNKNOWN"
,
"system"
,
"const"
,
"eq_ref"
,
"ref"
,
"MAYBE_REF"
,
"ALL"
,
"range"
,
"index"
,
"fulltext"
,
"ref_or_null"
,
"unique_subquery"
,
"index_subquery"
"ref_or_null"
,
"unique_subquery"
,
"index_subquery"
,
"index_merge"
//!!todo: psergey: check if constant values are same
};
static
void
optimize_keyuse
(
JOIN
*
join
,
DYNAMIC_ARRAY
*
keyuse_array
);
...
...
@@ -114,7 +115,6 @@ static int join_read_next_same_or_null(READ_RECORD *info);
static
COND
*
make_cond_for_table
(
COND
*
cond
,
table_map
table
,
table_map
used_table
);
static
Item
*
part_of_refkey
(
TABLE
*
form
,
Field
*
field
);
static
uint
find_shortest_key
(
TABLE
*
table
,
key_map
usable_keys
);
static
bool
test_if_skip_sort_order
(
JOIN_TAB
*
tab
,
ORDER
*
order
,
ha_rows
select_limit
,
bool
no_changes
);
static
int
create_sort_index
(
THD
*
thd
,
JOIN
*
join
,
ORDER
*
order
,
...
...
@@ -3340,7 +3340,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
with key reading */
if
(
tab
->
needed_reg
==
0
&&
tab
->
type
!=
JT_EQ_REF
&&
tab
->
type
!=
JT_FT
&&
(
tab
->
type
!=
JT_REF
||
(
uint
)
tab
->
ref
.
key
==
tab
->
quick
->
index
))
(
uint
)
tab
->
ref
.
key
==
tab
->
quick
->
index
))
{
sel
->
quick
=
tab
->
quick
;
// Use value from get_quick_...
sel
->
quick_keys
=
0
;
...
...
@@ -6589,7 +6589,7 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
return
reverse
;
}
static
uint
find_shortest_key
(
TABLE
*
table
,
key_map
usable_keys
)
uint
find_shortest_key
(
TABLE
*
table
,
key_map
usable_keys
)
{
uint
min_length
=
(
uint
)
~
0
;
uint
best
=
MAX_KEY
;
...
...
@@ -6719,6 +6719,9 @@ 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
)
DBUG_RETURN
(
0
);
ref_key
=
select
->
quick
->
index
;
ref_key_parts
=
select
->
quick
->
used_key_parts
;
}
...
...
@@ -6753,6 +6756,10 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
}
else
{
/*
We have verified above that select->quick is not
index_merge quick select.
*/
select
->
quick
->
index
=
new_ref_key
;
select
->
quick
->
init
();
}
...
...
@@ -6774,10 +6781,13 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
*/
if
(
!
select
->
quick
->
reverse_sorted
())
{
if
(
table
->
file
->
index_flags
(
ref_key
)
&
HA_NOT_READ_PREFIX_LAST
)
if
(
table
->
file
->
index_flags
(
ref_key
)
&
HA_NOT_READ_PREFIX_LAST
||
(
select
->
quick
->
get_type
()
==
QUICK_SELECT_I
::
QS_TYPE_INDEX_MERGE
))
DBUG_RETURN
(
0
);
// Use filesort
// ORDER BY range_key DESC
QUICK_SELECT_DESC
*
tmp
=
new
QUICK_SELECT_DESC
(
select
->
quick
,
// ORDER BY range_key DESC
QUICK_SELECT_DESC
*
tmp
=
new
QUICK_SELECT_DESC
((
QUICK_RANGE_SELECT
*
)(
select
->
quick
),
used_key_parts
);
if
(
!
tmp
||
tmp
->
error
)
{
...
...
@@ -6912,8 +6922,11 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
{
select
->
quick
=
tab
->
quick
;
tab
->
quick
=
0
;
/* We can only use 'Only index' if quick key is same as ref_key */
if
(
table
->
key_read
&&
(
uint
)
tab
->
ref
.
key
!=
select
->
quick
->
index
)
/*
We can only use 'Only index' if quick key is same as ref_key
and in index_merge 'Only index' cannot be used
*/
if
(
table
->
key_read
&&
((
uint
)
tab
->
ref
.
key
!=
select
->
quick
->
index
))
{
table
->
key_read
=
0
;
table
->
file
->
extra
(
HA_EXTRA_NO_KEYREAD
);
...
...
@@ -8717,12 +8730,15 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
JOIN_TAB
*
tab
=
join
->
join_tab
+
i
;
TABLE
*
table
=
tab
->
table
;
char
buff
[
512
],
*
buff_ptr
=
buff
;
char
buff1
[
512
],
buff2
[
512
];
char
buff1
[
512
],
buff2
[
512
],
buff3
[
512
];
char
keylen_str_buf
[
64
];
char
derived_name
[
64
];
String
tmp1
(
buff1
,
sizeof
(
buff1
),
cs
);
String
tmp2
(
buff2
,
sizeof
(
buff2
),
cs
);
String
tmp3
(
buff3
,
sizeof
(
buff3
),
cs
);
tmp1
.
length
(
0
);
tmp2
.
length
(
0
);
tmp3
.
length
(
0
);
item_list
.
empty
();
item_list
.
push_back
(
new
Item_int
((
int32
)
...
...
@@ -8731,7 +8747,13 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
strlen
(
join
->
select_lex
->
type
),
cs
));
if
(
tab
->
type
==
JT_ALL
&&
tab
->
select
&&
tab
->
select
->
quick
)
tab
->
type
=
JT_RANGE
;
{
if
(
tab
->
select
->
quick
->
get_type
()
==
QUICK_SELECT_I
::
QS_TYPE_INDEX_MERGE
)
tab
->
type
=
JT_INDEX_MERGE
;
else
tab
->
type
=
JT_RANGE
;
}
if
(
table
->
derived_select_number
)
{
/* Derived table name generation */
...
...
@@ -8765,10 +8787,14 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
if
(
tab
->
ref
.
key_parts
)
{
KEY
*
key_info
=
table
->
key_info
+
tab
->
ref
.
key
;
register
uint
length
;
item_list
.
push_back
(
new
Item_string
(
key_info
->
name
,
strlen
(
key_info
->
name
),
system_charset_info
));
item_list
.
push_back
(
new
Item_int
((
int32
)
tab
->
ref
.
key_length
));
length
=
longlong2str
(
tab
->
ref
.
key_length
,
keylen_str_buf
,
10
)
-
keylen_str_buf
;
item_list
.
push_back
(
new
Item_string
(
keylen_str_buf
,
length
,
system_charset_info
));
for
(
store_key
**
ref
=
tab
->
ref
.
key_copy
;
*
ref
;
ref
++
)
{
if
(
tmp2
.
length
())
...
...
@@ -8780,18 +8806,60 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
else
if
(
tab
->
type
==
JT_NEXT
)
{
KEY
*
key_info
=
table
->
key_info
+
tab
->
index
;
register
uint
length
;
item_list
.
push_back
(
new
Item_string
(
key_info
->
name
,
strlen
(
key_info
->
name
),
cs
));
item_list
.
push_back
(
new
Item_int
((
int32
)
key_info
->
key_length
));
length
=
longlong2str
(
key_info
->
key_length
,
keylen_str_buf
,
10
)
-
keylen_str_buf
;
item_list
.
push_back
(
new
Item_string
(
keylen_str_buf
,
length
,
system_charset_info
));
item_list
.
push_back
(
item_null
);
}
else
if
(
tab
->
select
&&
tab
->
select
->
quick
)
{
KEY
*
key_info
=
table
->
key_info
+
tab
->
select
->
quick
->
index
;
item_list
.
push_back
(
new
Item_string
(
key_info
->
name
,
strlen
(
key_info
->
name
),
cs
));
item_list
.
push_back
(
new
Item_int
((
int32
)
tab
->
select
->
quick
->
max_used_key_length
));
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
));
item_list
.
push_back
(
new
Item_string
(
tmp2
.
ptr
(),
tmp2
.
length
(),
cs
));
item_list
.
push_back
(
item_null
);
}
else
...
...
sql/sql_select.h
View file @
738728bd
...
...
@@ -76,7 +76,7 @@ typedef struct st_join_cache {
enum
join_type
{
JT_UNKNOWN
,
JT_SYSTEM
,
JT_CONST
,
JT_EQ_REF
,
JT_REF
,
JT_MAYBE_REF
,
JT_ALL
,
JT_RANGE
,
JT_NEXT
,
JT_FT
,
JT_REF_OR_NULL
,
JT_UNIQUE_SUBQUERY
,
JT_INDEX_SUBQUERY
};
JT_UNIQUE_SUBQUERY
,
JT_INDEX_SUBQUERY
,
JT_INDEX_MERGE
};
class
JOIN
;
...
...
@@ -85,7 +85,7 @@ typedef struct st_join_table {
KEYUSE
*
keyuse
;
/* pointer to first used key */
SQL_SELECT
*
select
;
COND
*
select_cond
;
QUICK_SELECT
*
quick
;
QUICK_SELECT
_I
*
quick
;
Item
*
on_expr
;
const
char
*
info
;
byte
*
null_ref_key
;
...
...
@@ -307,6 +307,7 @@ void copy_fields(TMP_TABLE_PARAM *param);
void
copy_funcs
(
Item
**
func_ptr
);
bool
create_myisam_from_heap
(
THD
*
thd
,
TABLE
*
table
,
TMP_TABLE_PARAM
*
param
,
int
error
,
bool
ignore_last_dupp_error
);
uint
find_shortest_key
(
TABLE
*
table
,
key_map
usable_keys
);
/* functions from opt_sum.cc */
int
opt_sum_query
(
TABLE_LIST
*
tables
,
List
<
Item
>
&
all_fields
,
COND
*
conds
);
...
...
sql/sql_test.cc
View file @
738728bd
...
...
@@ -178,9 +178,39 @@ TEST_join(JOIN *join)
" quick select checked for each record (keys: %d)
\n
"
,
(
int
)
tab
->
select
->
quick_keys
);
else
if
(
tab
->
select
->
quick
)
fprintf
(
DBUG_FILE
,
" quick select used on key %s, length: %d
\n
"
,
{
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
"
);
}
}
else
VOID
(
fputs
(
" select used
\n
"
,
DBUG_FILE
));
}
...
...
sql/sql_union.cc
View file @
738728bd
...
...
@@ -117,7 +117,8 @@ int st_select_lex_unit::prepare(THD *thd, select_result *sel_result,
{
SELECT_LEX
*
lex_select_save
=
thd
->
lex
->
current_select
;
SELECT_LEX
*
select_cursor
,
*
sl
;
DBUG_ENTER
(
"st_select_lex_unit::prepare"
);
SELECT_LEX
*
sl
;
DBUG_ENTER
(
"st_select_lex_unit::prepare"
);
if
(
prepared
)
DBUG_RETURN
(
0
);
...
...
@@ -187,7 +188,7 @@ int st_select_lex_unit::prepare(THD *thd, select_result *sel_result,
union_result
->
not_describe
=
1
;
union_result
->
tmp_table_param
=
tmp_table_param
;
for
(;
sl
;
sl
=
sl
->
next_select
())
for
(;
sl
;
sl
=
sl
->
next_select
())
//!!todo: psergey: all my changes around this were to shut up the compiler. check they didn't make it here
{
JOIN
*
join
=
new
JOIN
(
thd
,
sl
->
item_list
,
sl
->
options
|
thd
->
options
|
SELECT_NO_UNLOCK
,
...
...
sql/sql_update.cc
View file @
738728bd
...
...
@@ -177,10 +177,18 @@ 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
)
used_key_is_modified
=
(
!
select
->
quick
->
unique_key_range
()
&&
check_if_key_used
(
table
,
(
used_index
=
select
->
quick
->
index
),
fields
));
{
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
;
}
}
else
if
((
used_index
=
table
->
file
->
key_used_on_scan
)
<
MAX_KEY
)
used_key_is_modified
=
check_if_key_used
(
table
,
used_index
,
fields
);
else
...
...
@@ -699,8 +707,26 @@ 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
)
return
!
check_if_key_used
(
table
,
join_tab
->
quick
->
index
,
*
fields
);
{
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
;
}
}
/* 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