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
66e97ba5
Commit
66e97ba5
authored
Apr 24, 2003
by
guilhem@mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge gbichot@bk-internal.mysql.com:/home/bk/mysql-4.1
into mysql.com:/home/mysql_src/mysql-4.1
parents
b03ec0d7
517a287e
Changes
19
Show whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
591 additions
and
238 deletions
+591
-238
mysql-test/r/ctype_collate.result
mysql-test/r/ctype_collate.result
+42
-42
mysql-test/r/ctype_many.result
mysql-test/r/ctype_many.result
+1
-1
mysql-test/r/func_gconcat.result
mysql-test/r/func_gconcat.result
+1
-1
sql/filesort.cc
sql/filesort.cc
+353
-136
sql/item_strfunc.cc
sql/item_strfunc.cc
+10
-1
sql/mysqld.cc
sql/mysqld.cc
+6
-1
sql/opt_range.cc
sql/opt_range.cc
+4
-4
sql/records.cc
sql/records.cc
+92
-9
sql/set_var.cc
sql/set_var.cc
+6
-0
sql/sql_base.cc
sql/sql_base.cc
+4
-9
sql/sql_class.h
sql/sql_class.h
+1
-0
sql/sql_delete.cc
sql/sql_delete.cc
+5
-5
sql/sql_select.cc
sql/sql_select.cc
+11
-11
sql/sql_sort.h
sql/sql_sort.h
+30
-3
sql/sql_table.cc
sql/sql_table.cc
+5
-5
sql/sql_update.cc
sql/sql_update.cc
+2
-2
sql/structs.h
sql/structs.h
+1
-0
sql/table.h
sql/table.h
+12
-3
sql/uniques.cc
sql/uniques.cc
+5
-5
No files found.
mysql-test/r/ctype_collate.result
View file @
66e97ba5
...
...
@@ -40,26 +40,26 @@ A
a
AD
ad
AE
ae
AE
AF
af
B
b
B
SS
ss
U
u
U
UE
ue
Ü
ü
Y
y
ü
Ü
Z
z
Å
å
Å
Ä
ä
ß
...
...
@@ -69,26 +69,26 @@ A
a
AD
ad
AE
ae
AE
AF
af
B
b
B
SS
ss
U
u
U
UE
ue
Ü
ü
Y
y
ü
Ü
Z
z
Å
å
Å
Ä
ä
ß
...
...
@@ -100,23 +100,23 @@ a
å
AD
ad
AE
ae
Ä
ae
AE
ä
AF
af
B
AF
b
SS
ss
B
ß
ss
SS
U
u
UE
ue
Ü
UE
ü
Ü
Y
y
Z
...
...
@@ -129,23 +129,23 @@ AD
ad
AE
ae
AF
af
AF
Ä
ä
Å
å
B
b
SS
B
ss
SS
ß
U
u
UE
ue
Ü
ü
Ü
Y
y
Z
...
...
@@ -187,26 +187,26 @@ A
a
AD
ad
AE
ae
AE
AF
af
B
b
B
SS
ss
U
u
U
UE
ue
Ü
ü
Y
y
ü
Ü
Z
z
Å
å
Å
Ä
ä
ß
...
...
@@ -218,23 +218,23 @@ a
å
AD
ad
AE
ae
Ä
ae
AE
ä
AF
af
B
AF
b
SS
ss
B
ß
ss
SS
U
u
UE
ue
Ü
UE
ü
Ü
Y
y
Z
...
...
@@ -247,23 +247,23 @@ AD
ad
AE
ae
AF
af
AF
Ä
ä
Å
å
B
b
SS
B
ss
SS
ß
U
u
UE
ue
Ü
ü
Ü
Y
y
Z
...
...
mysql-test/r/ctype_many.result
View file @
66e97ba5
No preview for this file type
mysql-test/r/func_gconcat.result
View file @
66e97ba5
...
...
@@ -146,7 +146,7 @@ select grp,group_concat(c) from t1 group by grp;
grp group_concat(c)
1 NULL
2 b
3
E,D,D
3
D,D,E
4
5 NULL
Warnings:
...
...
sql/filesort.cc
View file @
66e97ba5
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This program is free software; you can redistribute it and/or modify
...
...
@@ -51,6 +52,10 @@ static int merge_index(SORTPARAM *param,uchar *sort_buffer,
static
bool
save_index
(
SORTPARAM
*
param
,
uchar
**
sort_keys
,
uint
count
);
static
uint
sortlength
(
SORT_FIELD
*
sortorder
,
uint
s_length
,
bool
*
multi_byte_charset
);
static
SORT_ADDON_FIELD
*
get_addon_fields
(
THD
*
thd
,
Field
**
ptabfield
,
uint
sortlength
,
uint
*
plength
);
static
void
unpack_addon_fields
(
struct
st_sort_addon_field
*
addon_field
,
byte
*
buff
);
/*
Creates a set of pointers that can be used to read the rows
...
...
@@ -82,16 +87,48 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
DBUG_PUSH
(
""
);
/* No DBUG here */
#endif
outfile
=
table
->
io_cache
;
outfile
=
table
->
sort
.
io_cache
;
my_b_clear
(
&
tempfile
);
my_b_clear
(
&
buffpek_pointers
);
buffpek
=
0
;
sort_keys
=
(
uchar
**
)
NULL
;
error
=
1
;
bzero
((
char
*
)
&
param
,
sizeof
(
param
));
param
.
sort_length
=
sortlength
(
sortorder
,
s_length
,
&
multi_byte_charset
);
param
.
ref_length
=
table
->
file
->
ref_length
;
param
.
sort_length
=
(
sortlength
(
sortorder
,
s_length
,
&
multi_byte_charset
)
+
param
.
ref_length
);
param
.
addon_field
=
0
;
param
.
addon_length
=
0
;
if
(
!
(
table
->
tmp_table
||
table
->
fulltext_searched
))
{
/*
Get the descriptors of all fields whose values are appended
to sorted fields and get its total length in param.spack_length.
*/
param
.
addon_field
=
get_addon_fields
(
thd
,
table
->
field
,
param
.
sort_length
,
&
param
.
addon_length
);
}
table
->
sort
.
addon_buf
=
0
;
table
->
sort
.
addon_length
=
param
.
addon_length
;
table
->
sort
.
addon_field
=
param
.
addon_field
;
table
->
sort
.
unpack
=
unpack_addon_fields
;
if
(
param
.
addon_field
)
{
param
.
res_length
=
param
.
addon_length
;
if
(
!
(
table
->
sort
.
addon_buf
=
(
byte
*
)
my_malloc
(
param
.
addon_length
,
MYF
(
MY_WME
))))
goto
err
;
}
else
{
param
.
res_length
=
param
.
ref_length
;
/*
The reference to the record is considered
as an additional sorted field
*/
param
.
sort_length
+=
param
.
ref_length
;
}
param
.
rec_length
=
param
.
sort_length
+
param
.
addon_length
;
param
.
max_rows
=
max_rows
;
if
(
select
&&
select
->
quick
)
...
...
@@ -115,7 +152,7 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
records
=
table
->
file
->
estimate_number_of_rows
();
selected_records_file
=
0
;
}
if
(
param
.
sort
_length
==
param
.
ref_length
&&
records
>
param
.
max_rows
)
if
(
param
.
rec
_length
==
param
.
ref_length
&&
records
>
param
.
max_rows
)
records
=
param
.
max_rows
;
/* purecov: inspected */
if
(
multi_byte_charset
&&
...
...
@@ -127,9 +164,9 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
while
(
memavl
>=
min_sort_memory
)
{
ulong
old_memavl
;
ulong
keys
=
memavl
/
(
param
.
sort
_length
+
sizeof
(
char
*
));
ulong
keys
=
memavl
/
(
param
.
rec
_length
+
sizeof
(
char
*
));
param
.
keys
=
(
uint
)
min
(
records
+
1
,
keys
);
if
((
sort_keys
=
(
uchar
**
)
make_char_array
(
param
.
keys
,
param
.
sort
_length
,
if
((
sort_keys
=
(
uchar
**
)
make_char_array
(
param
.
keys
,
param
.
rec
_length
,
MYF
(
0
))))
break
;
old_memavl
=
memavl
;
...
...
@@ -176,8 +213,8 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
Use also the space previously used by string pointers in sort_buffer
for temporary key storage.
*/
param
.
keys
=
((
param
.
keys
*
(
param
.
sort
_length
+
sizeof
(
char
*
)))
/
param
.
sort
_length
-
1
);
param
.
keys
=
((
param
.
keys
*
(
param
.
rec
_length
+
sizeof
(
char
*
)))
/
param
.
rec
_length
-
1
);
maxbuffer
--
;
// Offset from 0
if
(
merge_many_buff
(
&
param
,(
uchar
*
)
sort_keys
,
buffpek
,
&
maxbuffer
,
&
tempfile
))
...
...
@@ -356,8 +393,8 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
if
(
write_keys
(
param
,
sort_keys
,
idx
,
buffpek_pointers
,
tempfile
))
DBUG_RETURN
(
HA_POS_ERROR
);
idx
=
0
;
if
(
param
->
ref_length
==
param
->
sort
_length
&&
my_b_tell
(
tempfile
)
/
param
->
sort
_length
>=
param
->
max_rows
)
if
(
param
->
ref_length
==
param
->
rec
_length
&&
my_b_tell
(
tempfile
)
/
param
->
rec
_length
>=
param
->
max_rows
)
{
/*
We are writing the result index file and have found all
...
...
@@ -385,7 +422,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
write_keys
(
param
,
sort_keys
,
idx
,
buffpek_pointers
,
tempfile
))
DBUG_RETURN
(
HA_POS_ERROR
);
/* purecov: inspected */
DBUG_RETURN
(
my_b_inited
(
tempfile
)
?
(
ha_rows
)
(
my_b_tell
(
tempfile
)
/
param
->
sort
_length
)
:
(
ha_rows
)
(
my_b_tell
(
tempfile
)
/
param
->
rec
_length
)
:
idx
);
}
/* find_all_keys */
...
...
@@ -396,27 +433,28 @@ static int
write_keys
(
SORTPARAM
*
param
,
register
uchar
**
sort_keys
,
uint
count
,
IO_CACHE
*
buffpek_pointers
,
IO_CACHE
*
tempfile
)
{
uint
sort_length
;
uint
sort_length
,
rec_length
;
uchar
**
end
;
BUFFPEK
buffpek
;
DBUG_ENTER
(
"write_keys"
);
sort_length
=
param
->
sort_length
;
sort_length
=
param
->
sort_length
;
rec_length
=
param
->
rec_length
;
#ifdef MC68000
quicksort
(
sort_keys
,
count
,
sort_length
);
#else
my_string_ptr_sort
((
gptr
)
sort_keys
,
(
uint
)
count
,
sort_length
);
my_string_ptr_sort
((
gptr
)
sort_keys
,
(
uint
)
count
,
sort_length
);
#endif
if
(
!
my_b_inited
(
tempfile
)
&&
open_cached_file
(
tempfile
,
mysql_tmpdir
,
TEMP_PREFIX
,
DISK_BUFFER_SIZE
,
open_cached_file
(
tempfile
,
mysql_tmpdir
,
TEMP_PREFIX
,
DISK_BUFFER_SIZE
,
MYF
(
MY_WME
)))
goto
err
;
/* purecov: inspected */
buffpek
.
file_pos
=
my_b_tell
(
tempfile
);
buffpek
.
file_pos
=
my_b_tell
(
tempfile
);
if
((
ha_rows
)
count
>
param
->
max_rows
)
count
=
(
uint
)
param
->
max_rows
;
/* purecov: inspected */
buffpek
.
count
=
(
ha_rows
)
count
;
for
(
end
=
sort_keys
+
count
;
sort_keys
!=
end
;
sort_keys
++
)
if
(
my_b_write
(
tempfile
,
(
byte
*
)
*
sort_keys
,(
uint
)
sort
_length
))
if
(
my_b_write
(
tempfile
,
(
byte
*
)
*
sort_keys
,
(
uint
)
rec
_length
))
goto
err
;
if
(
my_b_write
(
buffpek_pointers
,
(
byte
*
)
&
buffpek
,
sizeof
(
buffpek
)))
goto
err
;
...
...
@@ -577,29 +615,56 @@ static void make_sortkey(register SORTPARAM *param,
else
to
+=
sort_field
->
length
;
}
memcpy
((
byte
*
)
to
,
ref_pos
,(
size_s
)
param
->
ref_length
);
/* Save filepos last */
if
(
param
->
addon_field
)
{
/*
Save field values appended to sorted fields.
First null bit indicators are appended then field values follow.
In this implementation we use fixed layout for field values -
the same for all records.
*/
SORT_ADDON_FIELD
*
addonf
=
param
->
addon_field
;
uchar
*
nulls
=
to
;
DBUG_ASSERT
(
addonf
);
bzero
((
char
*
)
nulls
,
addonf
->
offset
);
to
+=
addonf
->
offset
;
for
(
;
(
field
=
addonf
->
field
)
;
addonf
++
)
{
if
(
addonf
->
null_bit
&&
field
->
is_null
())
nulls
[
addonf
->
null_offset
]
|=
addonf
->
null_bit
;
else
field
->
pack
((
char
*
)
to
,
field
->
ptr
);
to
+=
addonf
->
length
;
}
}
else
{
/* Save filepos last */
memcpy
((
byte
*
)
to
,
ref_pos
,
(
size_s
)
param
->
ref_length
);
}
return
;
}
static
bool
save_index
(
SORTPARAM
*
param
,
uchar
**
sort_keys
,
uint
count
)
{
uint
offset
,
re
f
_length
;
uint
offset
,
re
s
_length
;
byte
*
to
;
DBUG_ENTER
(
"save_index"
);
my_string_ptr_sort
((
gptr
)
sort_keys
,
(
uint
)
count
,
param
->
sort_length
);
re
f_length
=
param
->
ref
_length
;
offset
=
param
->
sort_length
-
ref
_length
;
my_string_ptr_sort
((
gptr
)
sort_keys
,
(
uint
)
count
,
param
->
sort_length
);
re
s_length
=
param
->
res
_length
;
offset
=
param
->
rec_length
-
res
_length
;
if
((
ha_rows
)
count
>
param
->
max_rows
)
count
=
(
uint
)
param
->
max_rows
;
if
(
!
(
to
=
param
->
sort_form
->
record_pointers
=
(
byte
*
)
my_malloc
(
ref_length
*
count
,
MYF
(
MY_WME
))))
if
(
!
(
to
=
param
->
sort_form
->
sort
.
record_pointers
=
(
byte
*
)
my_malloc
(
res_length
*
count
,
MYF
(
MY_WME
))))
DBUG_RETURN
(
1
);
/* purecov: inspected */
for
(
uchar
**
end
=
sort_keys
+
count
;
sort_keys
!=
end
;
sort_keys
++
)
for
(
uchar
**
end
=
sort_keys
+
count
;
sort_keys
!=
end
;
sort_keys
++
)
{
memcpy
(
to
,
*
sort_keys
+
offset
,
ref
_length
);
to
+=
ref
_length
;
memcpy
(
to
,
*
sort_keys
+
offset
,
res
_length
);
to
+=
res
_length
;
}
DBUG_RETURN
(
0
);
}
...
...
@@ -654,7 +719,7 @@ int merge_many_buff(SORTPARAM *param, uchar *sort_buffer,
/* This returns (uint) -1 if something goes wrong */
uint
read_to_buffer
(
IO_CACHE
*
fromfile
,
BUFFPEK
*
buffpek
,
uint
sort
_length
)
uint
rec
_length
)
{
register
uint
count
;
uint
length
;
...
...
@@ -662,18 +727,20 @@ uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
if
((
count
=
(
uint
)
min
((
ha_rows
)
buffpek
->
max_keys
,
buffpek
->
count
)))
{
if
(
my_pread
(
fromfile
->
file
,(
byte
*
)
buffpek
->
base
,
(
length
=
sort
_length
*
count
),
buffpek
->
file_pos
,
MYF_RW
))
(
length
=
rec
_length
*
count
),
buffpek
->
file_pos
,
MYF_RW
))
return
((
uint
)
-
1
);
/* purecov: inspected */
buffpek
->
key
=
buffpek
->
base
;
buffpek
->
file_pos
+=
length
;
/* New filepos */
buffpek
->
count
-=
count
;
buffpek
->
mem_count
=
count
;
}
return
(
count
*
sort
_length
);
return
(
count
*
rec
_length
);
}
/* read_to_buffer */
/* Merge buffers to one buffer */
/*
Merge buffers to one buffer
*/
int
merge_buffers
(
SORTPARAM
*
param
,
IO_CACHE
*
from_file
,
IO_CACHE
*
to_file
,
uchar
*
sort_buffer
,
...
...
@@ -681,7 +748,7 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
int
flag
)
{
int
error
;
uint
sort
_length
,
offset
;
uint
rec_length
,
sort_length
,
res
_length
,
offset
;
ulong
maxcount
;
ha_rows
max_rows
,
org_max_rows
;
my_off_t
to_start_filepos
;
...
...
@@ -697,29 +764,32 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
if
(
param
->
not_killable
)
{
killed
=
&
not_killable
;
not_killable
=
0
;
not_killable
=
0
;
}
error
=
0
;
offset
=
(
sort_length
=
param
->
sort_length
)
-
param
->
ref_length
;
maxcount
=
(
ulong
)
(
param
->
keys
/
((
uint
)
(
Tb
-
Fb
)
+
1
));
to_start_filepos
=
my_b_tell
(
to_file
);
strpos
=
(
uchar
*
)
sort_buffer
;
org_max_rows
=
max_rows
=
param
->
max_rows
;
if
(
init_queue
(
&
queue
,(
uint
)
(
Tb
-
Fb
)
+
1
,
offsetof
(
BUFFPEK
,
key
),
0
,
(
queue_compare
)
(
cmp
=
get_ptr_compare
(
sort_length
)),(
void
*
)
&
sort_length
))
rec_length
=
param
->
rec_length
;
res_length
=
param
->
res_length
;
sort_length
=
param
->
sort_length
;
offset
=
rec_length
-
res_length
;
maxcount
=
(
ulong
)
(
param
->
keys
/
((
uint
)
(
Tb
-
Fb
)
+
1
));
to_start_filepos
=
my_b_tell
(
to_file
);
strpos
=
(
uchar
*
)
sort_buffer
;
org_max_rows
=
max_rows
=
param
->
max_rows
;
if
(
init_queue
(
&
queue
,
(
uint
)
(
Tb
-
Fb
)
+
1
,
offsetof
(
BUFFPEK
,
key
),
0
,
(
queue_compare
)
(
cmp
=
get_ptr_compare
(
sort_length
)),
(
void
*
)
&
sort_length
))
DBUG_RETURN
(
1
);
/* purecov: inspected */
for
(
buffpek
=
Fb
;
buffpek
<=
Tb
;
buffpek
++
)
{
buffpek
->
base
=
strpos
;
buffpek
->
max_keys
=
maxcount
;
strpos
+=
(
uint
)
(
error
=
(
int
)
read_to_buffer
(
from_file
,
buffpek
,
sort
_length
));
buffpek
->
max_keys
=
maxcount
;
strpos
+=
(
uint
)
(
error
=
(
int
)
read_to_buffer
(
from_file
,
buffpek
,
rec
_length
));
if
(
error
==
-
1
)
goto
err
;
/* purecov: inspected */
queue_insert
(
&
queue
,(
byte
*
)
buffpek
);
queue_insert
(
&
queue
,
(
byte
*
)
buffpek
);
}
if
(
param
->
unique_buff
)
...
...
@@ -732,66 +802,69 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
This is safe as we know that there is always more than one element
in each block to merge (This is guaranteed by the Unique:: algorithm
*/
buffpek
=
(
BUFFPEK
*
)
queue_top
(
&
queue
);
memcpy
(
param
->
unique_buff
,
buffpek
->
key
,
sort
_length
);
if
(
my_b_write
(
to_file
,
(
byte
*
)
buffpek
->
key
,
sort
_length
))
buffpek
=
(
BUFFPEK
*
)
queue_top
(
&
queue
);
memcpy
(
param
->
unique_buff
,
buffpek
->
key
,
rec
_length
);
if
(
my_b_write
(
to_file
,
(
byte
*
)
buffpek
->
key
,
rec
_length
))
{
error
=
1
;
goto
err
;
/* purecov: inspected */
}
buffpek
->
key
+=
sort
_length
;
buffpek
->
key
+=
rec
_length
;
buffpek
->
mem_count
--
;
if
(
!--
max_rows
)
{
error
=
0
;
/* purecov: inspected */
error
=
0
;
/* purecov: inspected */
goto
end
;
/* purecov: inspected */
}
queue_replaced
(
&
queue
);
// Top element has been used
}
else
cmp
=
0
;
// Not unique
cmp
=
0
;
// Not unique
while
(
queue
.
elements
>
1
)
{
if
(
*
killed
)
{
error
=
1
;
goto
err
;
/* purecov: inspected */
error
=
1
;
goto
err
;
/* purecov: inspected */
}
for
(;;)
{
buffpek
=
(
BUFFPEK
*
)
queue_top
(
&
queue
);
buffpek
=
(
BUFFPEK
*
)
queue_top
(
&
queue
);
if
(
cmp
)
// Remove duplicates
{
if
(
!
(
*
cmp
)(
&
sort_length
,
&
(
param
->
unique_buff
),
(
uchar
**
)
&
buffpek
->
key
))
goto
skip_duplicate
;
memcpy
(
param
->
unique_buff
,
(
uchar
*
)
buffpek
->
key
,
sort
_length
);
memcpy
(
param
->
unique_buff
,
(
uchar
*
)
buffpek
->
key
,
rec
_length
);
}
if
(
flag
==
0
)
{
if
(
my_b_write
(
to_file
,(
byte
*
)
buffpek
->
key
,
sort
_length
))
if
(
my_b_write
(
to_file
,(
byte
*
)
buffpek
->
key
,
rec
_length
))
{
error
=
1
;
goto
err
;
/* purecov: inspected */
}
}
else
{
WRITE_REF
(
to_file
,(
byte
*
)
buffpek
->
key
+
offset
);
if
(
my_b_write
(
to_file
,
(
byte
*
)
buffpek
->
key
+
offset
,
res_length
))
{
error
=
1
;
goto
err
;
/* purecov: inspected */
}
}
if
(
!--
max_rows
)
{
error
=
0
;
/* purecov: inspected */
error
=
0
;
/* purecov: inspected */
goto
end
;
/* purecov: inspected */
}
skip_duplicate:
buffpek
->
key
+=
sort
_length
;
buffpek
->
key
+=
rec
_length
;
if
(
!
--
buffpek
->
mem_count
)
{
if
(
!
(
error
=
(
int
)
read_to_buffer
(
from_file
,
buffpek
,
sort
_length
)))
if
(
!
(
error
=
(
int
)
read_to_buffer
(
from_file
,
buffpek
,
rec
_length
)))
{
uchar
*
base
=
buffpek
->
base
;
ulong
max_keys
=
buffpek
->
max_keys
;
uchar
*
base
=
buffpek
->
base
;
ulong
max_keys
=
buffpek
->
max_keys
;
VOID
(
queue_remove
(
&
queue
,
0
));
...
...
@@ -801,15 +874,15 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
refpek
++
)
{
buffpek
=
*
refpek
;
if
(
buffpek
->
base
+
buffpek
->
max_keys
*
sort
_length
==
base
)
if
(
buffpek
->
base
+
buffpek
->
max_keys
*
rec
_length
==
base
)
{
buffpek
->
max_keys
+=
max_keys
;
buffpek
->
max_keys
+=
max_keys
;
break
;
}
else
if
(
base
+
max_keys
*
sort
_length
==
buffpek
->
base
)
else
if
(
base
+
max_keys
*
rec
_length
==
buffpek
->
base
)
{
buffpek
->
base
=
base
;
buffpek
->
max_keys
+=
max_keys
;
buffpek
->
base
=
base
;
buffpek
->
max_keys
+=
max_keys
;
break
;
}
}
...
...
@@ -821,9 +894,9 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
queue_replaced
(
&
queue
);
/* Top element has been replaced */
}
}
buffpek
=
(
BUFFPEK
*
)
queue_top
(
&
queue
);
buffpek
=
(
BUFFPEK
*
)
queue_top
(
&
queue
);
buffpek
->
base
=
sort_buffer
;
buffpek
->
max_keys
=
param
->
keys
;
buffpek
->
max_keys
=
param
->
keys
;
/*
As we know all entries in the buffer are unique, we only have to
...
...
@@ -833,7 +906,7 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
{
if
(
!
(
*
cmp
)(
&
sort_length
,
&
(
param
->
unique_buff
),
(
uchar
**
)
&
buffpek
->
key
))
{
buffpek
->
key
+=
sort_length
;
// Remove duplicate
buffpek
->
key
+=
rec_length
;
// Remove duplicate
--
buffpek
->
mem_count
;
}
}
...
...
@@ -842,36 +915,39 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
{
if
((
ha_rows
)
buffpek
->
mem_count
>
max_rows
)
{
/* Don't write too many records */
buffpek
->
mem_count
=
(
uint
)
max_rows
;
buffpek
->
count
=
0
;
/* Don't read more */
buffpek
->
mem_count
=
(
uint
)
max_rows
;
buffpek
->
count
=
0
;
/* Don't read more */
}
max_rows
-=
buffpek
->
mem_count
;
max_rows
-=
buffpek
->
mem_count
;
if
(
flag
==
0
)
{
if
(
my_b_write
(
to_file
,(
byte
*
)
buffpek
->
key
,
(
sort
_length
*
buffpek
->
mem_count
)))
(
rec
_length
*
buffpek
->
mem_count
)))
{
error
=
1
;
goto
err
;
/* purecov: inspected */
error
=
1
;
goto
err
;
/* purecov: inspected */
}
}
else
{
register
uchar
*
end
;
strpos
=
buffpek
->
key
+
offset
;
for
(
end
=
strpos
+
buffpek
->
mem_count
*
sort_length
;
for
(
end
=
strpos
+
buffpek
->
mem_count
*
rec_length
;
strpos
!=
end
;
strpos
+=
sort_length
)
strpos
+=
rec_length
)
{
if
(
my_b_write
(
to_file
,
(
byte
*
)
strpos
,
res_length
))
{
WRITE_REF
(
to_file
,
strpos
);
error
=
1
;
goto
err
;
}
}
}
while
((
error
=
(
int
)
read_to_buffer
(
from_file
,
buffpek
,
sort_length
))
}
while
((
error
=
(
int
)
read_to_buffer
(
from_file
,
buffpek
,
rec_length
))
!=
-
1
&&
error
!=
0
);
end:
lastbuff
->
count
=
min
(
org_max_rows
-
max_rows
,
param
->
max_rows
);
lastbuff
->
file_pos
=
to_start_filepos
;
lastbuff
->
count
=
min
(
org_max_rows
-
max_rows
,
param
->
max_rows
);
lastbuff
->
file_pos
=
to_start_filepos
;
err:
delete_queue
(
&
queue
);
DBUG_RETURN
(
error
);
...
...
@@ -925,7 +1001,6 @@ sortlength(SORT_FIELD *sortorder, uint s_length, bool *multi_byte_charset)
sortorder
->
need_strxnfrm
=
0
;
if
(
sortorder
->
field
)
{
if
(
sortorder
->
field
->
type
()
==
FIELD_TYPE_BLOB
)
sortorder
->
length
=
thd
->
variables
.
max_sort_length
;
else
...
...
@@ -981,6 +1056,148 @@ sortlength(SORT_FIELD *sortorder, uint s_length, bool *multi_byte_charset)
}
/*
Get descriptors of fields appended to sorted fields and
calculate its total length
SYNOPSIS
get_addon_fields()
thd Current thread
ptabfields Array of references to the table fields
sortlength Total length of sorted fields
plength out: Total length of appended fields
DESCRIPTION
The function first finds out what fields are used in the result set.
Then it calculates the length of the buffer to store the values of
these fields together with the value of sort values.
If the calculated length is not greater than max_length_for_sort_data
the function allocates memory for an array of descriptors containing
layouts for the values of the non-sorted fields in the buffer and
fills them.
NOTES
The null bits for the appended values are supposed to be put together
and stored the buffer just ahead of the value of the first field.
RETURN
Pointer to the layout descriptors for the appended fields, if any
NULL - if we do not store field values with sort data.
*/
static
SORT_ADDON_FIELD
*
get_addon_fields
(
THD
*
thd
,
Field
**
ptabfield
,
uint
sortlength
,
uint
*
plength
)
{
Field
**
pfield
;
Field
*
field
;
SORT_ADDON_FIELD
*
addonf
;
uint
length
=
0
;
uint
fields
=
0
;
uint
null_fields
=
0
;
/*
If there is a reference to a field in the query add it
to the the set of appended fields.
Note for future refinement:
This this a too strong condition.
Actually we need only the fields referred in the
result set. And for some of them it makes sense to use
the values directly from sorted fields.
*/
*
plength
=
0
;
/*
The following statement is added to avoid sorting in alter_table.
The fact is the filter 'field->query_id != thd->query_id'
doesn't work for alter table
*/
if
(
thd
->
lex
.
sql_command
!=
SQLCOM_SELECT
)
return
0
;
for
(
pfield
=
ptabfield
;
(
field
=
*
pfield
)
;
pfield
++
)
{
if
(
field
->
query_id
!=
thd
->
query_id
)
continue
;
if
(
field
->
flags
&
BLOB_FLAG
)
return
0
;
length
+=
field
->
max_packed_col_length
(
field
->
pack_length
());
if
(
field
->
maybe_null
())
null_fields
++
;
fields
++
;
}
if
(
!
fields
)
return
0
;
length
+=
(
null_fields
+
7
)
/
8
;
if
(
length
+
sortlength
>
thd
->
variables
.
max_length_for_sort_data
||
!
(
addonf
=
(
SORT_ADDON_FIELD
*
)
my_malloc
(
sizeof
(
SORT_ADDON_FIELD
)
*
(
fields
+
1
),
MYF
(
MY_WME
))))
return
0
;
*
plength
=
length
;
length
=
(
null_fields
+
7
)
/
8
;
null_fields
=
0
;
for
(
pfield
=
ptabfield
;
(
field
=
*
pfield
)
;
pfield
++
)
{
if
(
field
->
query_id
!=
thd
->
query_id
)
continue
;
addonf
->
field
=
field
;
addonf
->
offset
=
length
;
if
(
field
->
maybe_null
())
{
addonf
->
null_offset
=
null_fields
/
8
;
addonf
->
null_bit
=
1
<<
(
null_fields
&
7
);
null_fields
++
;
}
else
{
addonf
->
null_offset
=
0
;
addonf
->
null_bit
=
0
;
}
addonf
->
length
=
field
->
max_packed_col_length
(
field
->
pack_length
());
length
+=
addonf
->
length
;
addonf
++
;
}
addonf
->
field
=
0
;
// Put end marker
DBUG_PRINT
(
"info"
,(
"addon_length: %d"
,
length
));
return
(
addonf
-
fields
);
}
/*
Copy (unpack) values appended to sorted fields from a buffer back to
their regular positions specified by the Field::ptr pointers.
SYNOPSIS
unpack_addon_fields()
addon_field Array of descriptors for appended fields
buff Buffer which to unpack the value from
NOTES
The function is supposed to be used only as a callback function
when getting field values for the sorted result set.
RETURN
void.
*/
static
void
unpack_addon_fields
(
struct
st_sort_addon_field
*
addon_field
,
byte
*
buff
)
{
Field
*
field
;
SORT_ADDON_FIELD
*
addonf
=
addon_field
;
for
(
;
(
field
=
addonf
->
field
)
;
addonf
++
)
{
if
(
addonf
->
null_bit
&&
(
addonf
->
null_bit
&
buff
[
addonf
->
null_offset
]))
{
field
->
set_null
();
continue
;
}
field
->
set_notnull
();
field
->
unpack
(
field
->
ptr
,
(
char
*
)
buff
+
addonf
->
offset
);
}
}
/*
** functions to change a double or float to a sortable string
** The following should work for IEEE
...
...
sql/item_strfunc.cc
View file @
66e97ba5
...
...
@@ -2943,7 +2943,7 @@ String *Item_func_compress::val_str(String *str)
*/
ulong
new_size
=
(
ulong
)((
res
->
length
()
*
120
)
/
100
)
+
12
;
buffer
.
realloc
((
uint32
)
new_size
+
4
);
buffer
.
realloc
((
uint32
)
new_size
+
4
+
1
);
Byte
*
body
=
((
Byte
*
)
buffer
.
c_ptr
())
+
4
;
if
((
err
=
compress
(
body
,
&
new_size
,
...
...
@@ -2956,6 +2956,15 @@ String *Item_func_compress::val_str(String *str)
}
int4store
(
buffer
.
c_ptr
(),
res
->
length
()
&
0x3FFFFFFF
);
/* This is for the stupid char fields which trim ' ': */
char
*
last_char
=
((
char
*
)
body
)
+
new_size
-
1
;
if
(
*
last_char
==
' '
)
{
*++
last_char
=
'.'
;
new_size
++
;
}
buffer
.
length
((
uint32
)
new_size
+
4
);
return
&
buffer
;
...
...
sql/mysqld.cc
View file @
66e97ba5
...
...
@@ -3458,7 +3458,7 @@ enum options
OPT_MAX_BINLOG_CACHE_SIZE
,
OPT_MAX_BINLOG_SIZE
,
OPT_MAX_CONNECTIONS
,
OPT_MAX_CONNECT_ERRORS
,
OPT_MAX_DELAYED_THREADS
,
OPT_MAX_HEP_TABLE_SIZE
,
OPT_MAX_JOIN_SIZE
,
OPT_MAX_SORT_LENGTH
,
OPT_MAX_JOIN_SIZE
,
OPT_MAX_
LENGTH_FOR_SORT_DATA
,
OPT_MAX_
SORT_LENGTH
,
OPT_MAX_TMP_TABLES
,
OPT_MAX_USER_CONNECTIONS
,
OPT_MAX_WRITE_LOCK_COUNT
,
OPT_BULK_INSERT_BUFFER_SIZE
,
OPT_MAX_ERROR_COUNT
,
OPT_MAX_PREP_STMT
,
...
...
@@ -4164,6 +4164,11 @@ Disable with --skip-innodb (will save memory)",
(
gptr
*
)
&
global_system_variables
.
max_join_size
,
(
gptr
*
)
&
max_system_variables
.
max_join_size
,
0
,
GET_HA_ROWS
,
REQUIRED_ARG
,
~
0L
,
1
,
~
0L
,
0
,
1
,
0
},
{
"max_length_for_sort_data"
,
OPT_MAX_LENGTH_FOR_SORT_DATA
,
"Max number of bytes in sorted records"
,
(
gptr
*
)
&
global_system_variables
.
max_length_for_sort_data
,
(
gptr
*
)
&
max_system_variables
.
max_length_for_sort_data
,
0
,
GET_ULONG
,
REQUIRED_ARG
,
1024
,
4
,
8192
*
1024L
,
0
,
1
,
0
},
{
"max_prepared_statements"
,
OPT_MAX_PREP_STMT
,
"Max number of prepared_statements for a thread"
,
(
gptr
*
)
&
global_system_variables
.
max_prep_stmt_count
,
...
...
sql/opt_range.cc
View file @
66e97ba5
...
...
@@ -349,13 +349,13 @@ SQL_SELECT *make_select(TABLE *head, table_map const_tables,
select
->
head
=
head
;
select
->
cond
=
conds
;
if
(
head
->
io_cache
)
if
(
head
->
sort
.
io_cache
)
{
select
->
file
=
*
head
->
io_cache
;
select
->
file
=
*
head
->
sort
.
io_cache
;
select
->
records
=
(
ha_rows
)
(
select
->
file
.
end_of_file
/
head
->
file
->
ref_length
);
my_free
((
gptr
)
(
head
->
io_cache
),
MYF
(
0
));
head
->
io_cache
=
0
;
my_free
((
gptr
)
(
head
->
sort
.
io_cache
),
MYF
(
0
));
head
->
sort
.
io_cache
=
0
;
}
DBUG_RETURN
(
select
);
}
...
...
sql/records.cc
View file @
66e97ba5
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This program is free software; you can redistribute it and/or modify
...
...
@@ -22,6 +23,8 @@
static
int
rr_quick
(
READ_RECORD
*
info
);
static
int
rr_sequential
(
READ_RECORD
*
info
);
static
int
rr_from_tempfile
(
READ_RECORD
*
info
);
static
int
rr_unpack_from_tempfile
(
READ_RECORD
*
info
);
static
int
rr_unpack_from_buffer
(
READ_RECORD
*
info
);
static
int
rr_from_pointers
(
READ_RECORD
*
info
);
static
int
rr_from_cache
(
READ_RECORD
*
info
);
static
int
init_rr_cache
(
READ_RECORD
*
info
);
...
...
@@ -41,8 +44,16 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
info
->
table
=
table
;
info
->
file
=
table
->
file
;
info
->
forms
=
&
info
->
table
;
/* Only one table */
info
->
record
=
table
->
record
[
0
];
info
->
ref_length
=
table
->
file
->
ref_length
;
if
(
table
->
sort
.
addon_field
)
{
info
->
rec_buf
=
table
->
sort
.
addon_buf
;
info
->
ref_length
=
table
->
sort
.
addon_length
;
}
else
{
info
->
record
=
table
->
record
[
0
];
info
->
ref_length
=
table
->
file
->
ref_length
;
}
info
->
select
=
select
;
info
->
print_error
=
print_error
;
info
->
ignore_not_found_rows
=
0
;
...
...
@@ -51,11 +62,12 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
if
(
select
&&
my_b_inited
(
&
select
->
file
))
tempfile
=
&
select
->
file
;
else
tempfile
=
table
->
io_cache
;
tempfile
=
table
->
sort
.
io_cache
;
if
(
tempfile
&&
my_b_inited
(
tempfile
))
// Test if ref-records was used
{
DBUG_PRINT
(
"info"
,(
"using rr_from_tempfile"
));
info
->
read_record
=
rr_from_tempfile
;
info
->
read_record
=
(
table
->
sort
.
addon_field
?
rr_unpack_from_tempfile
:
rr_from_tempfile
);
info
->
io_cache
=
tempfile
;
reinit_io_cache
(
info
->
io_cache
,
READ_CACHE
,
0L
,
0
,
0
);
info
->
ref_pos
=
table
->
file
->
ref
;
...
...
@@ -85,13 +97,15 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
DBUG_PRINT
(
"info"
,(
"using rr_quick"
));
info
->
read_record
=
rr_quick
;
}
else
if
(
table
->
record_pointers
)
else
if
(
table
->
sort
.
record_pointers
)
{
DBUG_PRINT
(
"info"
,(
"using record_pointers"
));
table
->
file
->
rnd_init
(
0
);
info
->
cache_pos
=
table
->
record_pointers
;
info
->
cache_end
=
info
->
cache_pos
+
table
->
found_records
*
info
->
ref_length
;
info
->
read_record
=
rr_from_pointers
;
info
->
cache_pos
=
table
->
sort
.
record_pointers
;
info
->
cache_end
=
info
->
cache_pos
+
table
->
sort
.
found_records
*
info
->
ref_length
;
info
->
read_record
=
(
table
->
sort
.
addon_field
?
rr_unpack_from_buffer
:
rr_from_pointers
);
}
else
{
...
...
@@ -120,6 +134,19 @@ void end_read_record(READ_RECORD *info)
}
if
(
info
->
table
)
{
TABLE
*
table
=
info
->
table
;
if
(
table
->
sort
.
record_pointers
)
{
my_free
((
gptr
)
table
->
sort
.
record_pointers
,
MYF
(
0
));
table
->
sort
.
record_pointers
=
0
;
}
if
(
table
->
sort
.
addon_buf
)
{
my_free
((
char
*
)
table
->
sort
.
addon_buf
,
MYF
(
0
));
my_free
((
char
*
)
table
->
sort
.
addon_field
,
MYF
(
MY_ALLOW_ZERO_PTR
));
table
->
sort
.
addon_buf
=
0
;
table
->
sort
.
addon_field
=
0
;
}
(
void
)
info
->
file
->
extra
(
HA_EXTRA_NO_CACHE
);
(
void
)
info
->
file
->
rnd_end
();
info
->
table
=
0
;
...
...
@@ -200,6 +227,34 @@ tryNext:
}
/* rr_from_tempfile */
/*
Read a result set record from a temporary file after sorting
SYNOPSIS
rr_unpack_from_tempfile()
info Reference to the context including record descriptors
DESCRIPTION
The function first reads the next sorted record from the temporary file.
into a buffer. If a success it calls a callback function that unpacks
the fields values use in the result set from this buffer into their
positions in the regular record buffer.
RETURN
0 - Record successfully read.
-1 - There is no record to be read anymore.
*/
static
int
rr_unpack_from_tempfile
(
READ_RECORD
*
info
)
{
if
(
my_b_read
(
info
->
io_cache
,
info
->
rec_buf
,
info
->
ref_length
))
return
-
1
;
TABLE
*
table
=
info
->
table
;
(
*
table
->
sort
.
unpack
)(
table
->
sort
.
addon_field
,
info
->
rec_buf
);
return
0
;
}
static
int
rr_from_pointers
(
READ_RECORD
*
info
)
{
int
tmp
;
...
...
@@ -228,6 +283,34 @@ tryNext:
return
tmp
;
}
/*
Read a result set record from a buffer after sorting
SYNOPSIS
rr_unpack_from_buffer()
info Reference to the context including record descriptors
DESCRIPTION
The function first reads the next sorted record from the sort buffer.
If a success it calls a callback function that unpacks
the fields values use in the result set from this buffer into their
positions in the regular record buffer.
RETURN
0 - Record successfully read.
-1 - There is no record to be read anymore.
*/
static
int
rr_unpack_from_buffer
(
READ_RECORD
*
info
)
{
if
(
info
->
cache_pos
==
info
->
cache_end
)
return
-
1
;
/* End of buffer */
TABLE
*
table
=
info
->
table
;
(
*
table
->
sort
.
unpack
)(
table
->
sort
.
addon_field
,
info
->
cache_pos
);
info
->
cache_pos
+=
info
->
ref_length
;
return
0
;
}
/* cacheing of records from a database */
static
int
init_rr_cache
(
READ_RECORD
*
info
)
...
...
sql/set_var.cc
View file @
66e97ba5
...
...
@@ -167,6 +167,8 @@ sys_var_thd_ulong sys_pseudo_thread_id("pseudo_thread_id",
sys_var_thd_ha_rows
sys_max_join_size
(
"max_join_size"
,
&
SV
::
max_join_size
,
fix_max_join_size
);
sys_var_thd_ulong
sys_max_length_for_sort_data
(
"max_length_for_sort_data"
,
&
SV
::
max_length_for_sort_data
);
#ifndef TO_BE_DELETED
/* Alias for max_join_size */
sys_var_thd_ha_rows
sys_sql_max_join_size
(
"sql_max_join_size"
,
&
SV
::
max_join_size
,
...
...
@@ -385,6 +387,7 @@ sys_var *sys_variables[]=
&
sys_max_error_count
,
&
sys_max_heap_table_size
,
&
sys_max_join_size
,
&
sys_max_length_for_sort_data
,
&
sys_max_prep_stmt_count
,
&
sys_max_sort_length
,
&
sys_max_tmp_tables
,
...
...
@@ -541,6 +544,9 @@ struct show_var_st init_vars[]= {
{
sys_max_delayed_threads
.
name
,(
char
*
)
&
sys_max_delayed_threads
,
SHOW_SYS
},
{
sys_max_heap_table_size
.
name
,(
char
*
)
&
sys_max_heap_table_size
,
SHOW_SYS
},
{
sys_max_join_size
.
name
,
(
char
*
)
&
sys_max_join_size
,
SHOW_SYS
},
{
sys_max_length_for_sort_data
.
name
,
(
char
*
)
&
sys_max_length_for_sort_data
,
SHOW_SYS
},
{
sys_max_prep_stmt_count
.
name
,(
char
*
)
&
sys_max_prep_stmt_count
,
SHOW_SYS
},
{
sys_max_sort_length
.
name
,
(
char
*
)
&
sys_max_sort_length
,
SHOW_SYS
},
{
sys_max_user_connections
.
name
,(
char
*
)
&
sys_max_user_connections
,
SHOW_SYS
},
...
...
sql/sql_base.cc
View file @
66e97ba5
...
...
@@ -245,16 +245,11 @@ static void free_cache_entry(TABLE *table)
void
free_io_cache
(
TABLE
*
table
)
{
DBUG_ENTER
(
"free_io_cache"
);
if
(
table
->
io_cache
)
if
(
table
->
sort
.
io_cache
)
{
close_cached_file
(
table
->
io_cache
);
my_free
((
gptr
)
table
->
io_cache
,
MYF
(
0
));
table
->
io_cache
=
0
;
}
if
(
table
->
record_pointers
)
{
my_free
((
gptr
)
table
->
record_pointers
,
MYF
(
0
));
table
->
record_pointers
=
0
;
close_cached_file
(
table
->
sort
.
io_cache
);
my_free
((
gptr
)
table
->
sort
.
io_cache
,
MYF
(
0
));
table
->
sort
.
io_cache
=
0
;
}
DBUG_VOID_RETURN
;
}
...
...
sql/sql_class.h
View file @
66e97ba5
...
...
@@ -354,6 +354,7 @@ struct system_variables
ulong
max_allowed_packet
;
ulong
max_error_count
;
ulong
max_heap_table_size
;
ulong
max_length_for_sort_data
;
ulong
max_prep_stmt_count
;
ulong
max_sort_length
;
ulong
max_tmp_tables
;
...
...
sql/sql_delete.cc
View file @
66e97ba5
...
...
@@ -124,11 +124,11 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order,
bzero
((
char
*
)
&
tables
,
sizeof
(
tables
));
tables
.
table
=
table
;
table
->
io_cache
=
(
IO_CACHE
*
)
my_malloc
(
sizeof
(
IO_CACHE
),
table
->
sort
.
io_cache
=
(
IO_CACHE
*
)
my_malloc
(
sizeof
(
IO_CACHE
),
MYF
(
MY_FAE
|
MY_ZEROFILL
));
if
(
setup_order
(
thd
,
0
,
&
tables
,
fields
,
all_fields
,
order
)
||
!
(
sortorder
=
make_unireg_sortorder
(
order
,
&
length
))
||
(
table
->
found_records
=
filesort
(
thd
,
table
,
sortorder
,
length
,
(
table
->
sort
.
found_records
=
filesort
(
thd
,
table
,
sortorder
,
length
,
(
SQL_SELECT
*
)
0
,
HA_POS_ERROR
,
&
examined_rows
))
==
HA_POS_ERROR
)
...
...
sql/sql_select.cc
View file @
66e97ba5
...
...
@@ -4010,7 +4010,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
case
Item_sum
:
:
AVG_FUNC
:
/* Place for sum & count */
if
(
group
)
return
new
Field_string
(
sizeof
(
double
)
+
sizeof
(
longlong
),
maybe_null
,
item
->
name
,
table
,
&
my_charset_bin
);
0
,
item
->
name
,
table
,
&
my_charset_bin
);
else
return
new
Field_double
(
item_sum
->
max_length
,
maybe_null
,
item
->
name
,
table
,
item_sum
->
decimals
);
...
...
@@ -4018,7 +4018,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
case
Item_sum
:
:
STD_FUNC
:
if
(
group
)
return
new
Field_string
(
sizeof
(
double
)
*
2
+
sizeof
(
longlong
),
maybe_null
,
item
->
name
,
table
,
&
my_charset_bin
);
0
,
item
->
name
,
table
,
&
my_charset_bin
);
else
return
new
Field_double
(
item_sum
->
max_length
,
maybe_null
,
item
->
name
,
table
,
item_sum
->
decimals
);
...
...
@@ -5622,11 +5622,11 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
TABLE
*
table
=
jt
->
table
;
join
->
select_options
^=
OPTION_FOUND_ROWS
;
if
(
table
->
record_pointers
||
(
table
->
io_cache
&&
my_b_inited
(
table
->
io_cache
)))
if
(
table
->
sort
.
record_pointers
||
(
table
->
sort
.
io_cache
&&
my_b_inited
(
table
->
sort
.
io_cache
)))
{
/* Using filesort */
join
->
send_records
=
table
->
found_records
;
join
->
send_records
=
table
->
sort
.
found_records
;
}
else
{
...
...
@@ -6461,7 +6461,7 @@ create_sort_index(THD *thd, JOIN_TAB *tab, ORDER *order,
if
(
!
(
sortorder
=
make_unireg_sortorder
(
order
,
&
length
)))
goto
err
;
/* purecov: inspected */
/* It's not fatal if the following alloc fails */
table
->
io_cache
=
(
IO_CACHE
*
)
my_malloc
(
sizeof
(
IO_CACHE
),
table
->
sort
.
io_cache
=
(
IO_CACHE
*
)
my_malloc
(
sizeof
(
IO_CACHE
),
MYF
(
MY_WME
|
MY_ZEROFILL
));
table
->
status
=
0
;
// May be wrong if quick_select
...
...
@@ -6491,9 +6491,9 @@ create_sort_index(THD *thd, JOIN_TAB *tab, ORDER *order,
}
if
(
table
->
tmp_table
)
table
->
file
->
info
(
HA_STATUS_VARIABLE
);
// Get record count
table
->
found_records
=
filesort
(
thd
,
table
,
sortorder
,
length
,
table
->
sort
.
found_records
=
filesort
(
thd
,
table
,
sortorder
,
length
,
select
,
filesort_limit
,
&
examined_rows
);
tab
->
records
=
table
->
found_records
;
// For SQL_CALC_ROWS
tab
->
records
=
table
->
sort
.
found_records
;
// For SQL_CALC_ROWS
delete
select
;
// filesort did select
tab
->
select
=
0
;
tab
->
select_cond
=
0
;
...
...
@@ -6505,7 +6505,7 @@ create_sort_index(THD *thd, JOIN_TAB *tab, ORDER *order,
table
->
key_read
=
0
;
table
->
file
->
extra
(
HA_EXTRA_NO_KEYREAD
);
}
DBUG_RETURN
(
table
->
found_records
==
HA_POS_ERROR
);
DBUG_RETURN
(
table
->
sort
.
found_records
==
HA_POS_ERROR
);
err:
DBUG_RETURN
(
-
1
);
}
...
...
sql/sql_sort.h
View file @
66e97ba5
...
...
@@ -19,6 +19,30 @@
#define MERGEBUFF 7
#define MERGEBUFF2 15
/*
The structure SORT_ADDON_FIELD describes a fixed layout
for field values appended to sorted values in records to be sorted
in the sort buffer.
Only fixed layout is supported now.
Null bit maps for the appended values is placed before the values
themselves. Offsets are from the last sorted field, that is from the
record referefence, which is still last component of sorted records.
It is preserved for backward compatiblility.
The structure is used tp store values of the additional fields
in the sort buffer. It is used also when these values are read
from a temporary file/buffer. As the reading procedures are beyond the
scope of the 'filesort' code the values have to be retrieved via
the callback function 'unpack_addon_fields'.
*/
typedef
struct
st_sort_addon_field
{
/* Sort addon packed field */
Field
*
field
;
/* Original field */
uint
offset
;
/* Offset from the last sorted field */
uint
null_offset
;
/* Offset to to null bit from the last sorted field */
uint
length
;
/* Length in the sort buffer */
uint8
null_bit
;
/* Null bit mask for the field */
}
SORT_ADDON_FIELD
;
typedef
struct
st_buffpek
{
/* Struktur om sorteringsbuffrarna */
my_off_t
file_pos
;
/* Where we are in the sort file */
uchar
*
base
,
*
key
;
/* key pointers */
...
...
@@ -27,15 +51,18 @@ typedef struct st_buffpek { /* Struktur om sorteringsbuffrarna */
ulong
max_keys
;
/* Max keys in buffert */
}
BUFFPEK
;
typedef
struct
st_sort_param
{
uint
sort_length
;
/* Length of sort column
s */
uint
keys
;
/* Max keys / buffert
*/
uint
rec_length
;
/* Length of sorted record
s */
uint
sort_length
;
/* Length of sorted columns
*/
uint
ref_length
;
/* Length of record ref. */
uint
addon_length
;
/* Length of added packed fields */
uint
res_length
;
/* Length of records in final sorted file/buffer */
uint
keys
;
/* Max keys / buffer */
ha_rows
max_rows
,
examined_rows
;
TABLE
*
sort_form
;
/* For quicker make_sortkey */
SORT_FIELD
*
local_sortorder
;
SORT_FIELD
*
end
;
SORT_ADDON_FIELD
*
addon_field
;
/* Descriptors for companion fields */
uchar
*
unique_buff
;
bool
not_killable
;
char
*
tmp_buffer
;
...
...
sql/sql_table.cc
View file @
66e97ba5
...
...
@@ -2342,7 +2342,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
if
(
order
)
{
from
->
io_cache
=
(
IO_CACHE
*
)
my_malloc
(
sizeof
(
IO_CACHE
),
from
->
sort
.
io_cache
=
(
IO_CACHE
*
)
my_malloc
(
sizeof
(
IO_CACHE
),
MYF
(
MY_FAE
|
MY_ZEROFILL
));
bzero
((
char
*
)
&
tables
,
sizeof
(
tables
));
tables
.
table
=
from
;
...
...
@@ -2355,7 +2355,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
setup_order
(
thd
,
thd
->
lex
.
select_lex
.
ref_pointer_array
,
&
tables
,
fields
,
all_fields
,
order
)
||
!
(
sortorder
=
make_unireg_sortorder
(
order
,
&
length
))
||
(
from
->
found_records
=
filesort
(
thd
,
from
,
sortorder
,
length
,
(
from
->
sort
.
found_records
=
filesort
(
thd
,
from
,
sortorder
,
length
,
(
SQL_SELECT
*
)
0
,
HA_POS_ERROR
,
&
examined_rows
))
==
HA_POS_ERROR
)
...
...
sql/sql_update.cc
View file @
66e97ba5
...
...
@@ -201,14 +201,14 @@ int mysql_update(THD *thd,
bzero
((
char
*
)
&
tables
,
sizeof
(
tables
));
tables
.
table
=
table
;
table
->
io_cache
=
(
IO_CACHE
*
)
my_malloc
(
sizeof
(
IO_CACHE
),
table
->
sort
.
io_cache
=
(
IO_CACHE
*
)
my_malloc
(
sizeof
(
IO_CACHE
),
MYF
(
MY_FAE
|
MY_ZEROFILL
));
if
(
setup_ref_array
(
thd
,
&
thd
->
lex
.
select_lex
.
ref_pointer_array
,
order_num
)
||
setup_order
(
thd
,
thd
->
lex
.
select_lex
.
ref_pointer_array
,
&
tables
,
fields
,
all_fields
,
order
)
||
!
(
sortorder
=
make_unireg_sortorder
(
order
,
&
length
))
||
(
table
->
found_records
=
filesort
(
thd
,
table
,
sortorder
,
length
,
(
table
->
sort
.
found_records
=
filesort
(
thd
,
table
,
sortorder
,
length
,
(
SQL_SELECT
*
)
0
,
HA_POS_ERROR
,
&
examined_rows
))
==
HA_POS_ERROR
)
...
...
sql/structs.h
View file @
66e97ba5
...
...
@@ -104,6 +104,7 @@ typedef struct st_read_record { /* Parameter to read_record */
uint
index
;
byte
*
ref_pos
;
/* pointer to form->refpos */
byte
*
record
;
byte
*
rec_buf
;
/* to read field values after filesort */
byte
*
cache
,
*
cache_pos
,
*
cache_end
,
*
read_positions
;
IO_CACHE
*
io_cache
;
bool
print_error
,
ignore_not_found_rows
;
...
...
sql/table.h
View file @
66e97ba5
...
...
@@ -44,6 +44,17 @@ typedef struct st_grant_info
enum
tmp_table_type
{
NO_TMP_TABLE
=
0
,
TMP_TABLE
=
1
,
TRANSACTIONAL_TMP_TABLE
=
2
};
typedef
struct
st_filesort_info
{
IO_CACHE
*
io_cache
;
/* If sorted through filebyte */
byte
*
addon_buf
;
/* Pointer to a buffer if sorted with fields */
uint
addon_length
;
/* Length of the buffer */
struct
st_sort_addon_field
*
addon_field
;
/* Pointer to the fields info */
void
(
*
unpack
)(
struct
st_sort_addon_field
*
,
byte
*
);
/* To unpack back */
byte
*
record_pointers
;
/* If sorted in memory */
ha_rows
found_records
;
/* How many records in sort */
}
FILESORT_INFO
;
/* Table cache entry struct */
class
Field_timestamp
;
...
...
@@ -120,9 +131,7 @@ struct st_table {
table_map
map
;
/* ID bit of table (1,2,4,8,16...) */
ulong
version
,
flush_version
;
uchar
*
null_flags
;
IO_CACHE
*
io_cache
;
/* If sorted trough filebyte */
byte
*
record_pointers
;
/* If sorted in memory */
ha_rows
found_records
;
/* How many records in sort */
FILESORT_INFO
sort
;
ORDER
*
group
;
ha_rows
quick_rows
[
MAX_KEY
];
uint
quick_key_parts
[
MAX_KEY
];
...
...
sql/uniques.cc
View file @
66e97ba5
...
...
@@ -95,12 +95,12 @@ bool Unique::flush()
bool
Unique
::
get
(
TABLE
*
table
)
{
SORTPARAM
sort_param
;
table
->
found_records
=
elements
+
tree
.
elements_in_tree
;
table
->
sort
.
found_records
=
elements
+
tree
.
elements_in_tree
;
if
(
my_b_tell
(
&
file
)
==
0
)
{
/* Whole tree is in memory; Don't use disk if you don't need to */
if
((
record_pointers
=
table
->
record_pointers
=
(
byte
*
)
if
((
record_pointers
=
table
->
sort
.
record_pointers
=
(
byte
*
)
my_malloc
(
tree
.
size_of_element
*
tree
.
elements_in_tree
,
MYF
(
0
))))
{
(
void
)
tree_walk
(
&
tree
,
(
tree_walk_action
)
unique_write_to_ptrs
,
...
...
@@ -112,7 +112,7 @@ bool Unique::get(TABLE *table)
if
(
flush
())
return
1
;
IO_CACHE
*
outfile
=
table
->
io_cache
;
IO_CACHE
*
outfile
=
table
->
sort
.
io_cache
;
BUFFPEK
*
file_ptr
=
(
BUFFPEK
*
)
file_ptrs
.
buffer
;
uint
maxbuffer
=
file_ptrs
.
elements
-
1
;
uchar
*
sort_buffer
;
...
...
@@ -120,7 +120,7 @@ bool Unique::get(TABLE *table)
bool
error
=
1
;
/* Open cached file if it isn't open */
outfile
=
table
->
io_cache
=
(
IO_CACHE
*
)
my_malloc
(
sizeof
(
IO_CACHE
),
outfile
=
table
->
sort
.
io_cache
=
(
IO_CACHE
*
)
my_malloc
(
sizeof
(
IO_CACHE
),
MYF
(
MY_ZEROFILL
));
if
(
!
outfile
||
!
my_b_inited
(
outfile
)
&&
...
...
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