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
8ab4a7a1
Commit
8ab4a7a1
authored
Oct 11, 2004
by
timour@mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge with implementation of WL#1724.
parents
09e9651a
a19eee45
Changes
18
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
5096 additions
and
229 deletions
+5096
-229
mysql-test/r/distinct.result
mysql-test/r/distinct.result
+5
-5
mysql-test/r/group_min_max.result
mysql-test/r/group_min_max.result
+1899
-0
mysql-test/t/group_min_max.test
mysql-test/t/group_min_max.test
+579
-0
sql/ha_myisam.cc
sql/ha_myisam.cc
+3
-2
sql/handler.cc
sql/handler.cc
+2
-1
sql/item.cc
sql/item.cc
+39
-0
sql/item.h
sql/item.h
+4
-0
sql/item_sum.cc
sql/item_sum.cc
+1
-0
sql/key.cc
sql/key.cc
+70
-43
sql/mysql_priv.h
sql/mysql_priv.h
+5
-3
sql/opt_range.cc
sql/opt_range.cc
+2214
-105
sql/opt_range.h
sql/opt_range.h
+101
-5
sql/opt_sum.cc
sql/opt_sum.cc
+1
-1
sql/sql_acl.cc
sql/sql_acl.cc
+4
-4
sql/sql_handler.cc
sql/sql_handler.cc
+1
-1
sql/sql_insert.cc
sql/sql_insert.cc
+1
-1
sql/sql_select.cc
sql/sql_select.cc
+165
-57
sql/sql_select.h
sql/sql_select.h
+2
-1
No files found.
mysql-test/r/distinct.result
View file @
8ab4a7a1
...
@@ -200,19 +200,19 @@ select distinct 1 from t1,t3 where t1.a=t3.a;
...
@@ -200,19 +200,19 @@ select distinct 1 from t1,t3 where t1.a=t3.a;
1
1
explain SELECT distinct t1.a from t1;
explain SELECT distinct t1.a from t1;
id select_type table type possible_keys key key_len ref rows Extra
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1
index NULL PRIMARY 4 NULL 4 Using index
1 SIMPLE t1
range NULL PRIMARY 4 NULL 5 Using index for group-by
explain SELECT distinct t1.a from t1 order by a desc;
explain SELECT distinct t1.a from t1 order by a desc;
id select_type table type possible_keys key key_len ref rows Extra
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1
index NULL PRIMARY 4 NULL 4 Using index
1 SIMPLE t1
range NULL PRIMARY 4 NULL 5 Using index for group-by; Using temporary; Using filesort
explain SELECT t1.a from t1 group by a order by a desc;
explain SELECT t1.a from t1 group by a order by a desc;
id select_type table type possible_keys key key_len ref rows Extra
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1
index NULL PRIMARY 4 NULL 4 Using index
1 SIMPLE t1
range NULL PRIMARY 4 NULL 5 Using index for group-by; Using temporary; Using filesort
explain SELECT distinct t1.a from t1 order by a desc limit 1;
explain SELECT distinct t1.a from t1 order by a desc limit 1;
id select_type table type possible_keys key key_len ref rows Extra
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL PRIMARY 4 NULL
4
Using index
1 SIMPLE t1 index NULL PRIMARY 4 NULL
5
Using index
explain SELECT distinct a from t3 order by a desc limit 2;
explain SELECT distinct a from t3 order by a desc limit 2;
id select_type table type possible_keys key key_len ref rows Extra
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t3 index NULL a 5 NULL
204
Using index
1 SIMPLE t3 index NULL a 5 NULL
10
Using index
explain SELECT distinct a,b from t3 order by a+1;
explain SELECT distinct a,b from t3 order by a+1;
id select_type table type possible_keys key key_len ref rows Extra
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t3 ALL NULL NULL NULL NULL 204 Using temporary; Using filesort
1 SIMPLE t3 ALL NULL NULL NULL NULL 204 Using temporary; Using filesort
...
...
mysql-test/r/group_min_max.result
0 → 100644
View file @
8ab4a7a1
This diff is collapsed.
Click to expand it.
mysql-test/t/group_min_max.test
0 → 100644
View file @
8ab4a7a1
This diff is collapsed.
Click to expand it.
sql/ha_myisam.cc
View file @
8ab4a7a1
...
@@ -1538,7 +1538,8 @@ ulonglong ha_myisam::get_auto_increment()
...
@@ -1538,7 +1538,8 @@ ulonglong ha_myisam::get_auto_increment()
mi_flush_bulk_insert
(
file
,
table
->
next_number_index
);
mi_flush_bulk_insert
(
file
,
table
->
next_number_index
);
(
void
)
extra
(
HA_EXTRA_KEYREAD
);
(
void
)
extra
(
HA_EXTRA_KEYREAD
);
key_copy
(
key
,
table
,
table
->
next_number_index
,
key_copy
(
key
,
table
->
record
[
0
],
table
->
key_info
+
table
->
next_number_index
,
table
->
next_number_key_offset
);
table
->
next_number_key_offset
);
error
=
mi_rkey
(
file
,
table
->
record
[
1
],(
int
)
table
->
next_number_index
,
error
=
mi_rkey
(
file
,
table
->
record
[
1
],(
int
)
table
->
next_number_index
,
key
,
table
->
next_number_key_offset
,
HA_READ_PREFIX_LAST
);
key
,
table
->
next_number_key_offset
,
HA_READ_PREFIX_LAST
);
...
...
sql/handler.cc
View file @
8ab4a7a1
...
@@ -1125,7 +1125,8 @@ ulonglong handler::get_auto_increment()
...
@@ -1125,7 +1125,8 @@ ulonglong handler::get_auto_increment()
else
else
{
{
byte
key
[
MAX_KEY_LENGTH
];
byte
key
[
MAX_KEY_LENGTH
];
key_copy
(
key
,
table
,
table
->
next_number_index
,
key_copy
(
key
,
table
->
record
[
0
],
table
->
key_info
+
table
->
next_number_index
,
table
->
next_number_key_offset
);
table
->
next_number_key_offset
);
error
=
index_read
(
table
->
record
[
1
],
key
,
table
->
next_number_key_offset
,
error
=
index_read
(
table
->
record
[
1
],
key
,
table
->
next_number_key_offset
,
HA_READ_PREFIX_LAST
);
HA_READ_PREFIX_LAST
);
...
...
sql/item.cc
View file @
8ab4a7a1
...
@@ -170,6 +170,45 @@ bool Item_ident::remove_dependence_processor(byte * arg)
...
@@ -170,6 +170,45 @@ bool Item_ident::remove_dependence_processor(byte * arg)
}
}
/*
Store the pointer to this item field into a list if not already there.
SYNOPSIS
Item_field::collect_item_field_processor()
arg pointer to a List<Item_field>
DESCRIPTION
The method is used by Item::walk to collect all unique Item_field objects
from a tree of Items into a set of items represented as a list.
IMPLEMENTATION
Item_cond::walk() and Item_func::walk() stop the evaluation of the
processor function for its arguments once the processor returns
true.Therefore in order to force this method being called for all item
arguments in a condition the method must return false.
RETURN
false to force the evaluation of collect_item_field_processor
for the subsequent items.
*/
bool
Item_field
::
collect_item_field_processor
(
byte
*
arg
)
{
DBUG_ENTER
(
"Item_field::collect_item_field_processor"
);
DBUG_PRINT
(
"info"
,
(
"%s"
,
field
->
field_name
?
field
->
field_name
:
"noname"
));
List
<
Item_field
>
*
item_list
=
(
List
<
Item_field
>*
)
arg
;
List_iterator
<
Item_field
>
item_list_it
(
*
item_list
);
Item_field
*
curr_item
;
while
((
curr_item
=
item_list_it
++
))
{
if
(
curr_item
->
eq
(
this
,
1
))
DBUG_RETURN
(
false
);
/* Already in the set. */
}
item_list
->
push_back
(
this
);
DBUG_RETURN
(
false
);
}
bool
Item
::
check_cols
(
uint
c
)
bool
Item
::
check_cols
(
uint
c
)
{
{
if
(
c
!=
1
)
if
(
c
!=
1
)
...
...
sql/item.h
View file @
8ab4a7a1
...
@@ -263,6 +263,7 @@ public:
...
@@ -263,6 +263,7 @@ public:
virtual
bool
remove_dependence_processor
(
byte
*
arg
)
{
return
0
;
}
virtual
bool
remove_dependence_processor
(
byte
*
arg
)
{
return
0
;
}
virtual
bool
remove_fixed
(
byte
*
arg
)
{
fixed
=
0
;
return
0
;
}
virtual
bool
remove_fixed
(
byte
*
arg
)
{
fixed
=
0
;
return
0
;
}
virtual
bool
collect_item_field_processor
(
byte
*
arg
)
{
return
0
;
}
virtual
Item
*
this_item
()
{
return
this
;
}
/* For SPs mostly. */
virtual
Item
*
this_item
()
{
return
this
;
}
/* For SPs mostly. */
virtual
Item
*
this_const_item
()
const
{
return
const_cast
<
Item
*>
(
this
);
}
/* For SPs mostly. */
virtual
Item
*
this_const_item
()
const
{
return
const_cast
<
Item
*>
(
this
);
}
/* For SPs mostly. */
...
@@ -497,6 +498,7 @@ public:
...
@@ -497,6 +498,7 @@ public:
bool
get_time
(
TIME
*
ltime
);
bool
get_time
(
TIME
*
ltime
);
bool
is_null
()
{
return
field
->
is_null
();
}
bool
is_null
()
{
return
field
->
is_null
();
}
Item
*
get_tmp_table_item
(
THD
*
thd
);
Item
*
get_tmp_table_item
(
THD
*
thd
);
bool
collect_item_field_processor
(
byte
*
arg
);
void
cleanup
();
void
cleanup
();
inline
uint32
max_disp_length
()
{
return
field
->
max_length
();
}
inline
uint32
max_disp_length
()
{
return
field
->
max_length
();
}
Item_field
*
filed_for_view_update
()
{
return
this
;
}
Item_field
*
filed_for_view_update
()
{
return
this
;
}
...
@@ -988,6 +990,8 @@ public:
...
@@ -988,6 +990,8 @@ public:
(
*
ref
)
->
save_in_field
(
result_field
,
no_conversions
);
(
*
ref
)
->
save_in_field
(
result_field
,
no_conversions
);
}
}
Item
*
real_item
()
{
return
*
ref
;
}
Item
*
real_item
()
{
return
*
ref
;
}
bool
walk
(
Item_processor
processor
,
byte
*
arg
)
{
return
(
*
ref
)
->
walk
(
processor
,
arg
);
}
void
print
(
String
*
str
);
void
print
(
String
*
str
);
void
cleanup
();
void
cleanup
();
};
};
...
...
sql/item_sum.cc
View file @
8ab4a7a1
...
@@ -182,6 +182,7 @@ bool Item_sum::walk (Item_processor processor, byte *argument)
...
@@ -182,6 +182,7 @@ bool Item_sum::walk (Item_processor processor, byte *argument)
return
(
this
->*
processor
)(
argument
);
return
(
this
->*
processor
)(
argument
);
}
}
String
*
String
*
Item_sum_num
::
val_str
(
String
*
str
)
Item_sum_num
::
val_str
(
String
*
str
)
{
{
...
...
sql/key.cc
View file @
8ab4a7a1
...
@@ -66,94 +66,121 @@ int find_ref_key(TABLE *table,Field *field, uint *key_length)
...
@@ -66,94 +66,121 @@ int find_ref_key(TABLE *table,Field *field, uint *key_length)
}
}
/* Copy a key from record to some buffer */
/*
/* if length == 0 then copy whole key */
Copy part of a record that forms a key or key prefix to a buffer.
SYNOPSIS
key_copy()
to_key buffer that will be used as a key
from_record full record to be copied from
key_info descriptor of the index
key_length specifies length of all keyparts that will be copied
DESCRIPTION
The function takes a complete table record (as e.g. retrieved by
handler::index_read()), and a description of an index on the same table,
and extracts the first key_length bytes of the record which are part of a
key into to_key. If length == 0 then copy all bytes from the record that
form a key.
RETURN
None
*/
void
key_copy
(
byte
*
key
,
TABLE
*
table
,
uint
idx
,
uint
key_length
)
void
key_copy
(
byte
*
to_key
,
byte
*
from_record
,
KEY
*
key_info
,
uint
key_length
)
{
{
uint
length
;
uint
length
;
KEY
*
key_info
=
table
->
key_info
+
idx
;
KEY_PART_INFO
*
key_part
;
KEY_PART_INFO
*
key_part
;
if
(
key_length
==
0
)
if
(
key_length
==
0
)
key_length
=
key_info
->
key_length
;
key_length
=
key_info
->
key_length
;
for
(
key_part
=
key_info
->
key_part
;
for
(
key_part
=
key_info
->
key_part
;
(
int
)
key_length
>
0
;
key_part
++
)
(
int
)
key_length
>
0
;
key_part
++
)
{
{
if
(
key_part
->
null_bit
)
if
(
key_part
->
null_bit
)
{
{
*
key
++=
test
(
table
->
record
[
0
]
[
key_part
->
null_offset
]
&
*
to_key
++=
test
(
from_record
[
key_part
->
null_offset
]
&
key_part
->
null_bit
);
key_part
->
null_bit
);
key_length
--
;
key_length
--
;
}
}
if
(
key_part
->
key_part_flag
&
HA_BLOB_PART
)
if
(
key_part
->
key_part_flag
&
HA_BLOB_PART
)
{
{
char
*
pos
;
char
*
pos
;
ulong
blob_length
=
((
Field_blob
*
)
key_part
->
field
)
->
get_length
();
ulong
blob_length
=
((
Field_blob
*
)
key_part
->
field
)
->
get_length
();
key_length
-=
2
;
key_length
-=
2
;
((
Field_blob
*
)
key_part
->
field
)
->
get_ptr
(
&
pos
);
((
Field_blob
*
)
key_part
->
field
)
->
get_ptr
(
&
pos
);
length
=
min
(
key_length
,
key_part
->
length
);
length
=
min
(
key_length
,
key_part
->
length
);
set_if_smaller
(
blob_length
,
length
);
set_if_smaller
(
blob_length
,
length
);
int2store
(
key
,
(
uint
)
blob_length
);
int2store
(
to_key
,
(
uint
)
blob_length
);
key
+=
2
;
// Skip length info
to_key
+=
2
;
// Skip length info
memcpy
(
key
,
pos
,
blob_length
);
memcpy
(
to_key
,
pos
,
blob_length
);
}
}
else
else
{
{
length
=
min
(
key_length
,
key_part
->
length
);
length
=
min
(
key_length
,
key_part
->
length
);
memcpy
(
key
,
table
->
record
[
0
]
+
key_part
->
offset
,
(
size_t
)
length
);
memcpy
(
to_key
,
from_record
+
key_part
->
offset
,
(
size_t
)
length
);
}
}
key
+=
length
;
to_key
+=
length
;
key_length
-=
length
;
key_length
-=
length
;
}
}
}
/* key_copy */
}
/* restore a key from some buffer to record */
/*
Restore a key from some buffer to record.
SYNOPSIS
key_restore()
to_record record buffer where the key will be restored to
from_key buffer that contains a key
key_info descriptor of the index
key_length specifies length of all keyparts that will be restored
DESCRIPTION
This function converts a key into record format. It can be used in cases
when we want to return a key as a result row.
RETURN
None
*/
void
key_restore
(
TABLE
*
table
,
byte
*
key
,
uint
idx
,
uint
key_length
)
void
key_restore
(
byte
*
to_record
,
byte
*
from_key
,
KEY
*
key_info
,
uint
key_length
)
{
{
uint
length
;
uint
length
;
KEY
*
key_info
=
table
->
key_info
+
idx
;
KEY_PART_INFO
*
key_part
;
KEY_PART_INFO
*
key_part
;
if
(
key_length
==
0
)
if
(
key_length
==
0
)
{
{
if
(
idx
==
(
uint
)
-
1
)
key_length
=
key_info
->
key_length
;
return
;
key_length
=
key_info
->
key_length
;
}
}
for
(
key_part
=
key_info
->
key_part
;
for
(
key_part
=
key_info
->
key_part
;
(
int
)
key_length
>
0
;
key_part
++
)
(
int
)
key_length
>
0
;
key_part
++
)
{
{
if
(
key_part
->
null_bit
)
if
(
key_part
->
null_bit
)
{
{
if
(
*
key
++
)
if
(
*
from_
key
++
)
t
able
->
record
[
0
]
[
key_part
->
null_offset
]
|=
key_part
->
null_bit
;
t
o_record
[
key_part
->
null_offset
]
|=
key_part
->
null_bit
;
else
else
t
able
->
record
[
0
]
[
key_part
->
null_offset
]
&=
~
key_part
->
null_bit
;
t
o_record
[
key_part
->
null_offset
]
&=
~
key_part
->
null_bit
;
key_length
--
;
key_length
--
;
}
}
if
(
key_part
->
key_part_flag
&
HA_BLOB_PART
)
if
(
key_part
->
key_part_flag
&
HA_BLOB_PART
)
{
{
uint
blob_length
=
uint2korr
(
key
);
uint
blob_length
=
uint2korr
(
from_
key
);
key
+=
2
;
from_key
+=
2
;
key_length
-=
2
;
key_length
-=
2
;
((
Field_blob
*
)
key_part
->
field
)
->
set_ptr
((
ulong
)
blob_length
,
((
Field_blob
*
)
key_part
->
field
)
->
set_ptr
((
ulong
)
blob_length
,
(
char
*
)
key
);
(
char
*
)
from_
key
);
length
=
key_part
->
length
;
length
=
key_part
->
length
;
}
}
else
else
{
{
length
=
min
(
key_length
,
key_part
->
length
);
length
=
min
(
key_length
,
key_part
->
length
);
memcpy
(
t
able
->
record
[
0
]
+
key_part
->
offset
,
key
,
(
size_t
)
length
);
memcpy
(
t
o_record
+
key_part
->
offset
,
from_key
,
(
size_t
)
length
);
}
}
key
+=
length
;
from_key
+=
length
;
key_length
-=
length
;
key_length
-=
length
;
}
}
}
/* key_restore */
}
/*
/*
...
...
sql/mysql_priv.h
View file @
8ab4a7a1
...
@@ -763,7 +763,8 @@ bool add_proc_to_list(THD *thd, Item *item);
...
@@ -763,7 +763,8 @@ bool add_proc_to_list(THD *thd, Item *item);
TABLE
*
unlink_open_table
(
THD
*
thd
,
TABLE
*
list
,
TABLE
*
find
);
TABLE
*
unlink_open_table
(
THD
*
thd
,
TABLE
*
list
,
TABLE
*
find
);
SQL_SELECT
*
make_select
(
TABLE
*
head
,
table_map
const_tables
,
SQL_SELECT
*
make_select
(
TABLE
*
head
,
table_map
const_tables
,
table_map
read_tables
,
COND
*
conds
,
int
*
error
);
table_map
read_tables
,
COND
*
conds
,
int
*
error
,
bool
allow_null_cond
=
false
);
enum
find_item_error_report_type
{
REPORT_ALL_ERRORS
,
REPORT_EXCEPT_NOT_FOUND
,
enum
find_item_error_report_type
{
REPORT_ALL_ERRORS
,
REPORT_EXCEPT_NOT_FOUND
,
IGNORE_ERRORS
};
IGNORE_ERRORS
};
extern
const
Item
**
not_found_item
;
extern
const
Item
**
not_found_item
;
...
@@ -861,8 +862,9 @@ void print_plan(JOIN* join, double read_time, double record_count,
...
@@ -861,8 +862,9 @@ void print_plan(JOIN* join, double read_time, double record_count,
void
mysql_print_status
(
THD
*
thd
);
void
mysql_print_status
(
THD
*
thd
);
/* key.cc */
/* key.cc */
int
find_ref_key
(
TABLE
*
form
,
Field
*
field
,
uint
*
offset
);
int
find_ref_key
(
TABLE
*
form
,
Field
*
field
,
uint
*
offset
);
void
key_copy
(
byte
*
key
,
TABLE
*
form
,
uint
index
,
uint
key_length
);
void
key_copy
(
byte
*
to_key
,
byte
*
from_record
,
KEY
*
key_info
,
uint
key_length
);
void
key_restore
(
TABLE
*
form
,
byte
*
key
,
uint
index
,
uint
key_length
);
void
key_restore
(
byte
*
to_record
,
byte
*
from_key
,
KEY
*
key_info
,
uint
key_length
);
bool
key_cmp_if_same
(
TABLE
*
form
,
const
byte
*
key
,
uint
index
,
uint
key_length
);
bool
key_cmp_if_same
(
TABLE
*
form
,
const
byte
*
key
,
uint
index
,
uint
key_length
);
void
key_unpack
(
String
*
to
,
TABLE
*
form
,
uint
index
);
void
key_unpack
(
String
*
to
,
TABLE
*
form
,
uint
index
);
bool
check_if_key_used
(
TABLE
*
table
,
uint
idx
,
List
<
Item
>
&
fields
);
bool
check_if_key_used
(
TABLE
*
table
,
uint
idx
,
List
<
Item
>
&
fields
);
...
...
sql/opt_range.cc
View file @
8ab4a7a1
This diff is collapsed.
Click to expand it.
sql/opt_range.h
View file @
8ab4a7a1
...
@@ -146,7 +146,8 @@ public:
...
@@ -146,7 +146,8 @@ public:
QS_TYPE_RANGE_DESC
=
2
,
QS_TYPE_RANGE_DESC
=
2
,
QS_TYPE_FULLTEXT
=
3
,
QS_TYPE_FULLTEXT
=
3
,
QS_TYPE_ROR_INTERSECT
=
4
,
QS_TYPE_ROR_INTERSECT
=
4
,
QS_TYPE_ROR_UNION
=
5
QS_TYPE_ROR_UNION
=
5
,
QS_TYPE_GROUP_MIN_MAX
=
6
};
};
/* Get type of this quick select - one of the QS_TYPE_* values */
/* Get type of this quick select - one of the QS_TYPE_* values */
...
@@ -278,14 +279,12 @@ public:
...
@@ -278,14 +279,12 @@ public:
int
init
();
int
init
();
int
get_next
();
int
get_next
();
void
range_end
();
void
range_end
();
int
get_next_prefix
(
uint
prefix_length
,
byte
*
cur_prefix
);
bool
reverse_sorted
()
{
return
0
;
}
bool
reverse_sorted
()
{
return
0
;
}
bool
unique_key_range
();
bool
unique_key_range
();
int
init_ror_merged_scan
(
bool
reuse_handler
);
int
init_ror_merged_scan
(
bool
reuse_handler
);
void
save_last_pos
()
void
save_last_pos
()
{
{
file
->
position
(
record
);
}
file
->
position
(
record
);
};
int
get_type
()
{
return
QS_TYPE_RANGE
;
}
int
get_type
()
{
return
QS_TYPE_RANGE
;
}
void
add_keys_and_lengths
(
String
*
key_names
,
String
*
used_lengths
);
void
add_keys_and_lengths
(
String
*
key_names
,
String
*
used_lengths
);
void
add_info_string
(
String
*
str
);
void
add_info_string
(
String
*
str
);
...
@@ -518,6 +517,103 @@ private:
...
@@ -518,6 +517,103 @@ private:
};
};
/*
Index scan for GROUP-BY queries with MIN/MAX aggregate functions.
This class provides a specialized index access method for GROUP-BY queries
of the forms:
SELECT A_1,...,A_k, [B_1,...,B_m], [MIN(C)], [MAX(C)]
FROM T
WHERE [RNG(A_1,...,A_p ; where p <= k)]
[AND EQ(B_1,...,B_m)]
[AND PC(C)]
[AND PA(A_i1,...,A_iq)]
GROUP BY A_1,...,A_k;
or
SELECT DISTINCT A_i1,...,A_ik
FROM T
WHERE [RNG(A_1,...,A_p ; where p <= k)]
[AND PA(A_i1,...,A_iq)];
where all selected fields are parts of the same index.
The class of queries that can be processed by this quick select is fully
specified in the description of get_best_trp_group_min_max() in opt_range.cc.
The get_next() method directly produces result tuples, thus obviating the
need to call end_send_group() because all grouping is already done inside
get_next().
Since one of the requirements is that all select fields are part of the same
index, this class produces only index keys, and not complete records.
*/
class
QUICK_GROUP_MIN_MAX_SELECT
:
public
QUICK_SELECT_I
{
private:
handler
*
file
;
/* The handler used to get data. */
JOIN
*
join
;
/* Descriptor of the current query */
KEY
*
index_info
;
/* The index chosen for data access */
byte
*
record
;
/* Buffer where the next record is returned. */
byte
*
tmp_record
;
/* Temporary storage for next_min(), next_max(). */
byte
*
group_prefix
;
/* Key prefix consisting of the GROUP fields. */
uint
group_prefix_len
;
/* Length of the group prefix. */
byte
*
last_prefix
;
/* Prefix of the last group for detecting EOF. */
bool
have_min
;
/* Specify whether we are computing */
bool
have_max
;
/* a MIN, a MAX, or both. */
bool
seen_first_key
;
/* Denotes whether the first key was retrieved.*/
KEY_PART_INFO
*
min_max_arg_part
;
/* The keypart of the only argument field */
/* of all MIN/MAX functions. */
uint
min_max_arg_len
;
/* The length of the MIN/MAX argument field */
byte
*
key_infix
;
/* Infix of constants from equality predicates. */
uint
key_infix_len
;
DYNAMIC_ARRAY
min_max_ranges
;
/* Array of range ptrs for the MIN/MAX field. */
uint
real_prefix_len
;
/* Length of key prefix extended with key_infix. */
List
<
Item_sum
>
*
min_functions
;
List
<
Item_sum
>
*
max_functions
;
List_iterator
<
Item_sum
>
*
min_functions_it
;
List_iterator
<
Item_sum
>
*
max_functions_it
;
public:
/*
The following two members are public to allow easy access from
TRP_GROUP_MIN_MAX::make_quick()
*/
MEM_ROOT
alloc
;
/* Memory pool for this and quick_prefix_select data. */
QUICK_RANGE_SELECT
*
quick_prefix_select
;
/* For retrieval of group prefixes. */
private:
int
next_prefix
();
int
next_min_in_range
();
int
next_max_in_range
();
int
next_min
();
int
next_max
();
void
update_min_result
();
void
update_max_result
();
public:
QUICK_GROUP_MIN_MAX_SELECT
(
TABLE
*
table
,
JOIN
*
join
,
bool
have_min
,
bool
have_max
,
KEY_PART_INFO
*
min_max_arg_part
,
uint
group_prefix_len
,
uint
used_key_parts
,
KEY
*
index_info
,
uint
use_index
,
double
read_cost
,
ha_rows
records
,
uint
key_infix_len
,
byte
*
key_infix
,
MEM_ROOT
*
parent_alloc
);
~
QUICK_GROUP_MIN_MAX_SELECT
();
bool
add_range
(
SEL_ARG
*
sel_range
);
void
update_key_stat
();
bool
alloc_buffers
();
int
init
();
int
reset
();
int
get_next
();
bool
reverse_sorted
()
{
return
false
;
}
bool
unique_key_range
()
{
return
false
;
}
int
get_type
()
{
return
QS_TYPE_GROUP_MIN_MAX
;
}
void
add_keys_and_lengths
(
String
*
key_names
,
String
*
used_lengths
);
#ifndef DBUG_OFF
void
dbug_dump
(
int
indent
,
bool
verbose
);
#endif
};
class
QUICK_SELECT_DESC
:
public
QUICK_RANGE_SELECT
class
QUICK_SELECT_DESC
:
public
QUICK_RANGE_SELECT
{
{
public:
public:
...
...
sql/opt_sum.cc
View file @
8ab4a7a1
...
@@ -336,7 +336,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
...
@@ -336,7 +336,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
1 Otherwise
1 Otherwise
*/
*/
static
bool
simple_pred
(
Item_func
*
func_item
,
Item
**
args
,
bool
*
inv_order
)
bool
simple_pred
(
Item_func
*
func_item
,
Item
**
args
,
bool
*
inv_order
)
{
{
Item
*
item
;
Item
*
item
;
*
inv_order
=
0
;
*
inv_order
=
0
;
...
...
sql/sql_acl.cc
View file @
8ab4a7a1
...
@@ -1906,7 +1906,7 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs)
...
@@ -1906,7 +1906,7 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs)
col_privs
->
field
[
1
]
->
pack_length
()
+
col_privs
->
field
[
1
]
->
pack_length
()
+
col_privs
->
field
[
2
]
->
pack_length
()
+
col_privs
->
field
[
2
]
->
pack_length
()
+
col_privs
->
field
[
3
]
->
pack_length
());
col_privs
->
field
[
3
]
->
pack_length
());
key_copy
(
key
,
col_privs
,
0
,
key_len
);
key_copy
(
key
,
col_privs
->
record
[
0
],
col_privs
->
key_info
,
key_len
);
col_privs
->
field
[
4
]
->
store
(
""
,
0
,
&
my_charset_latin1
);
col_privs
->
field
[
4
]
->
store
(
""
,
0
,
&
my_charset_latin1
);
col_privs
->
file
->
ha_index_init
(
0
);
col_privs
->
file
->
ha_index_init
(
0
);
if
(
col_privs
->
file
->
index_read
(
col_privs
->
record
[
0
],
if
(
col_privs
->
file
->
index_read
(
col_privs
->
record
[
0
],
...
@@ -2018,7 +2018,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
...
@@ -2018,7 +2018,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
table
->
field
[
3
]
->
store
(
table_name
,(
uint
)
strlen
(
table_name
),
&
my_charset_latin1
);
table
->
field
[
3
]
->
store
(
table_name
,(
uint
)
strlen
(
table_name
),
&
my_charset_latin1
);
key_length
=
(
table
->
field
[
0
]
->
pack_length
()
+
table
->
field
[
1
]
->
pack_length
()
+
key_length
=
(
table
->
field
[
0
]
->
pack_length
()
+
table
->
field
[
1
]
->
pack_length
()
+
table
->
field
[
2
]
->
pack_length
()
+
table
->
field
[
3
]
->
pack_length
());
table
->
field
[
2
]
->
pack_length
()
+
table
->
field
[
3
]
->
pack_length
());
key_copy
(
key
,
table
,
0
,
key_length
);
key_copy
(
key
,
table
->
record
[
0
],
table
->
key_info
,
key_length
);
rights
&=
COL_ACLS
;
// Only ACL for columns
rights
&=
COL_ACLS
;
// Only ACL for columns
...
@@ -2031,7 +2031,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
...
@@ -2031,7 +2031,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
{
{
ulong
privileges
=
xx
->
rights
;
ulong
privileges
=
xx
->
rights
;
bool
old_row_exists
=
0
;
bool
old_row_exists
=
0
;
key_restore
(
table
,
key
,
0
,
key_length
);
key_restore
(
table
->
record
[
0
],
key
,
table
->
key_info
,
key_length
);
table
->
field
[
4
]
->
store
(
xx
->
column
.
ptr
(),
xx
->
column
.
length
(),
table
->
field
[
4
]
->
store
(
xx
->
column
.
ptr
(),
xx
->
column
.
length
(),
&
my_charset_latin1
);
&
my_charset_latin1
);
...
@@ -2047,7 +2047,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
...
@@ -2047,7 +2047,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
}
}
old_row_exists
=
0
;
old_row_exists
=
0
;
restore_record
(
table
,
default_values
);
// Get empty record
restore_record
(
table
,
default_values
);
// Get empty record
key_restore
(
table
,
key
,
0
,
key_length
);
key_restore
(
table
->
record
[
0
],
key
,
table
->
key_info
,
key_length
);
table
->
field
[
4
]
->
store
(
xx
->
column
.
ptr
(),
xx
->
column
.
length
(),
table
->
field
[
4
]
->
store
(
xx
->
column
.
ptr
(),
xx
->
column
.
length
(),
&
my_charset_latin1
);
&
my_charset_latin1
);
}
}
...
...
sql/sql_handler.cc
View file @
8ab4a7a1
...
@@ -337,7 +337,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
...
@@ -337,7 +337,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
send_error
(
thd
,
ER_OUTOFMEMORY
);
send_error
(
thd
,
ER_OUTOFMEMORY
);
goto
err
;
goto
err
;
}
}
key_copy
(
key
,
table
,
keyno
,
key_len
);
key_copy
(
key
,
table
->
record
[
0
],
table
->
key_info
+
keyno
,
key_len
);
err
=
table
->
file
->
index_read
(
table
->
record
[
0
],
err
=
table
->
file
->
index_read
(
table
->
record
[
0
],
key
,
key_len
,
ha_rkey_mode
);
key
,
key_len
,
ha_rkey_mode
);
mode
=
rkey_to_rnext
[(
int
)
ha_rkey_mode
];
mode
=
rkey_to_rnext
[(
int
)
ha_rkey_mode
];
...
...
sql/sql_insert.cc
View file @
8ab4a7a1
...
@@ -719,7 +719,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
...
@@ -719,7 +719,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
goto
err
;
goto
err
;
}
}
}
}
key_copy
((
byte
*
)
key
,
table
,
key_nr
,
0
);
key_copy
((
byte
*
)
key
,
table
->
record
[
0
],
table
->
key_info
+
key_nr
,
0
);
if
((
error
=
(
table
->
file
->
index_read_idx
(
table
->
record
[
1
],
key_nr
,
if
((
error
=
(
table
->
file
->
index_read_idx
(
table
->
record
[
1
],
key_nr
,
(
byte
*
)
key
,
(
byte
*
)
key
,
table
->
key_info
[
key_nr
].
table
->
key_info
[
key_nr
].
...
...
sql/sql_select.cc
View file @
8ab4a7a1
This diff is collapsed.
Click to expand it.
sql/sql_select.h
View file @
8ab4a7a1
...
@@ -303,7 +303,7 @@ class JOIN :public Sql_alloc
...
@@ -303,7 +303,7 @@ class JOIN :public Sql_alloc
void
restore_tmp
();
void
restore_tmp
();
bool
alloc_func_list
();
bool
alloc_func_list
();
bool
make_sum_func_list
(
List
<
Item
>
&
all_fields
,
List
<
Item
>
&
send_fields
,
bool
make_sum_func_list
(
List
<
Item
>
&
all_fields
,
List
<
Item
>
&
send_fields
,
bool
before_group_by
);
bool
before_group_by
,
bool
recompute
=
FALSE
);
inline
void
set_items_ref_array
(
Item
**
ptr
)
inline
void
set_items_ref_array
(
Item
**
ptr
)
{
{
...
@@ -399,6 +399,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
...
@@ -399,6 +399,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
uint
find_shortest_key
(
TABLE
*
table
,
const
key_map
*
usable_keys
);
uint
find_shortest_key
(
TABLE
*
table
,
const
key_map
*
usable_keys
);
/* functions from opt_sum.cc */
/* functions from opt_sum.cc */
bool
simple_pred
(
Item_func
*
func_item
,
Item
**
args
,
bool
*
inv_order
);
int
opt_sum_query
(
TABLE_LIST
*
tables
,
List
<
Item
>
&
all_fields
,
COND
*
conds
);
int
opt_sum_query
(
TABLE_LIST
*
tables
,
List
<
Item
>
&
all_fields
,
COND
*
conds
);
/* from sql_delete.cc, used by opt_range.cc */
/* from sql_delete.cc, used by opt_range.cc */
...
...
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