Bug#13633383 63183: SMALL SORT_BUFFER_SIZE CRASH IN MERGE_BUFFERS
This patch is a backport of some of the cleanups/refactorings that were done as part of WL#1393 Optimizing filesort with small limit.
This commit is contained in:
parent
5cfe937f24
commit
8e5d9991d1
53
mysql-test/r/bug13633383.result
Normal file
53
mysql-test/r/bug13633383.result
Normal file
@ -0,0 +1,53 @@
|
||||
#
|
||||
# Bug#13633383 63183: SMALL SORT_BUFFER_SIZE CRASH IN MERGE_BUFFERS
|
||||
#
|
||||
CREATE TABLE t1 (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`col432` bit(8) DEFAULT NULL,
|
||||
`col433` multipoint DEFAULT NULL,
|
||||
`col434` polygon DEFAULT NULL,
|
||||
`col435` decimal(50,17) unsigned DEFAULT NULL,
|
||||
`col436` geometry NOT NULL,
|
||||
`col437` tinyblob NOT NULL,
|
||||
`col438` multipolygon DEFAULT NULL,
|
||||
`col439` mediumblob NOT NULL,
|
||||
`col440` tinyblob NOT NULL,
|
||||
`col441` double unsigned DEFAULT NULL
|
||||
);
|
||||
CREATE TABLE t2 (
|
||||
`a` multipoint DEFAULT NULL,
|
||||
`col460` date DEFAULT NULL,
|
||||
`col461` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`col462` date NOT NULL,
|
||||
`col463` varbinary(89) NOT NULL,
|
||||
`col464` year(4) DEFAULT NULL,
|
||||
`col465` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`col466` varchar(236) CHARACTER SET utf8 NOT NULL,
|
||||
`col467` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
|
||||
);
|
||||
CREATE TABLE t3 (
|
||||
`FTS_DOC_ID` bigint(20) unsigned NOT NULL,
|
||||
`col577` datetime DEFAULT NULL,
|
||||
`col579` bit(38) NOT NULL,
|
||||
`col580` varchar(93) NOT NULL,
|
||||
`col581` datetime DEFAULT NULL,
|
||||
`col583` multipolygon DEFAULT NULL,
|
||||
`col584` bit(47) NOT NULL
|
||||
);
|
||||
set session sort_buffer_size= 32768;
|
||||
select col435
|
||||
from t3
|
||||
natural right outer join t1
|
||||
natural right outer join t2 a
|
||||
left outer join t2 b on 1
|
||||
group by
|
||||
repeat('a',10000) desc,
|
||||
repeat('a',10000)
|
||||
with rollup
|
||||
;
|
||||
col435
|
||||
0.00000000000000000
|
||||
0.00000000000000000
|
||||
0.00000000000000000
|
||||
set session sort_buffer_size= default;
|
||||
DROP TABLE t1, t2, t3;
|
82
mysql-test/t/bug13633383.test
Normal file
82
mysql-test/t/bug13633383.test
Normal file
@ -0,0 +1,82 @@
|
||||
--echo #
|
||||
--echo # Bug#13633383 63183: SMALL SORT_BUFFER_SIZE CRASH IN MERGE_BUFFERS
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`col432` bit(8) DEFAULT NULL,
|
||||
`col433` multipoint DEFAULT NULL,
|
||||
`col434` polygon DEFAULT NULL,
|
||||
`col435` decimal(50,17) unsigned DEFAULT NULL,
|
||||
`col436` geometry NOT NULL,
|
||||
`col437` tinyblob NOT NULL,
|
||||
`col438` multipolygon DEFAULT NULL,
|
||||
`col439` mediumblob NOT NULL,
|
||||
`col440` tinyblob NOT NULL,
|
||||
`col441` double unsigned DEFAULT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE t2 (
|
||||
`a` multipoint DEFAULT NULL,
|
||||
`col460` date DEFAULT NULL,
|
||||
`col461` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`col462` date NOT NULL,
|
||||
`col463` varbinary(89) NOT NULL,
|
||||
`col464` year(4) DEFAULT NULL,
|
||||
`col465` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`col466` varchar(236) CHARACTER SET utf8 NOT NULL,
|
||||
`col467` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
|
||||
);
|
||||
|
||||
CREATE TABLE t3 (
|
||||
`FTS_DOC_ID` bigint(20) unsigned NOT NULL,
|
||||
`col577` datetime DEFAULT NULL,
|
||||
`col579` bit(38) NOT NULL,
|
||||
`col580` varchar(93) NOT NULL,
|
||||
`col581` datetime DEFAULT NULL,
|
||||
`col583` multipolygon DEFAULT NULL,
|
||||
`col584` bit(47) NOT NULL
|
||||
);
|
||||
|
||||
--disable_query_log
|
||||
|
||||
INSERT INTO t1 VALUES (0,0xFF,'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 JæÀ',NULL,0.00000000000000000,'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0àÃ\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0àC\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0àC\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0',0xB623A952C5,'\0\0\0\0\0\0\0\0\0\0\0ðiøÀ\0\0\0\0jøÀ',0x22,0xD81F72A9,56403);
|
||||
INSERT INTO t1 VALUES (-32768,0x00,'\0\0\0\0\0\0\0\0\0\0\0Àrç@\0\0\0\0jøÀ','\0\0\0\0\0\0\0\0\0\0\0\0ÛâÀ\0\0\0\0jøÀ',NULL,'\0\0\0\0\0\0\0\0\0\0\0À6Ò@\0\0\0\0\0jøÀ',0xC80876AF04,'\0\0\0\0\0\0\0\0\0\0\0€[áÀ\0\0\0\0ðiøÀ',0x016C576E34,0x1B,0);
|
||||
INSERT INTO t1 VALUES (-2147483648,0x17,'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0]ÇÀ',NULL,0.00000000000000000,'\0\0\0\0\0\0\0\0\0\0\0ðiøÀìÊFQƒìCµ',0x68D352,'\0\0\0\0\0\0\0\n\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0àÃ\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0àC\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0àÃ\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0àC\0\0\0\0\0àÃ\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0','','',0);
|
||||
INSERT INTO t1 VALUES (1,0xFF,'\0\0\0\0\0\0\0\0\0\0\0Ð÷À\0\0\0\0Àü×À','\0\0\0\0\0\0\0\0\0\0\0`6ë@\0\0\0\0à²î@',32767.00000000000000000,'\0\0\0\0\0\0\0\0\0\0\0ðiø@†ö¯{âÌ',0x1406B0C524,'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0àÃ\0\0\0\0\0àC\0\0\0\0\0àC',0xC04B75CCFD,0xC4CD,1);
|
||||
INSERT INTO t1 VALUES (0,0xFF,NULL,'\0\0\0\0\0\0\0\0\0\0\0\0jø@\0\0\0\0\0(¦À',0.06140000000000000,'\0\0\0\0\0\0\0\0\0\0\0ðiø@$7”H#ÀÐ1',0x3F,'\0\0\0\0\0\0\0\0\0\0\0jøÀCHK¶µ$·',0x1E87C5DA,0xCC870E,NULL);
|
||||
|
||||
|
||||
INSERT INTO t2 VALUES ('\0\0\0\0\0\0\0\0\0\0\0\0k¿À\0\0\0\0\0jø@','2011-02-19','2011-08-10 14:21:44','2012-09-25',0xCCC3,0000,'2012-07-28 16:25:23','idpapxbfjrigkfqnhnfmhvtewlvxfmjhfqizhhsowbetimmkhukpzeixbfyzmsalaafssdovflpvxldldmuamfoulanivuxigbjwkzbapcxmmprpyasaozdqwqjuixajzmiepkcvnvtewdvyodupziffgzbcmsfhikbuehyhzfnxlsdzulbsrqmtszzzupcmxlvcpxahuiotgadwhpcuqmyzgrbkxzxwriqkymdaqnzz','2012-01-20 09:01:25');
|
||||
INSERT INTO t2 VALUES (NULL,'2011-05-14','2012-10-17 04:33:30','2012-01-20','',0000,'2012-05-08 11:06:53','otbywkbfwwtgpfgurtqwgfcwmmntsdxkounuzueoclrpnadghfzmbrh','2012-03-24 21:01:09');
|
||||
INSERT INTO t2 VALUES ('\0\0\0\0\0\0\06ý¹PVh,;bºö$î°','2012-07-21','2011-11-21 04:23:27','2011-06-18',0x21,0000,'2011-09-10 14:01:05','goybgohrexhfqwerpknkbyiqowvcdpyxvbklkbeeuvfbjtkmontmkmgcjutkjphewnvvobzilamtjqjbtvqgczozqcmvbbzvoxkycsvplfykmzpwljdcromsilspjuoyhxwduymxkymvmijehtutftqmpfpbesonppacogyogjqhyonizbsgzwubzgeoehryqswzkftgzhzssnlstuszpwauxmdhgjcawabnjcynzrrh','2012-11-19 18:30:51');
|
||||
INSERT INTO t2 VALUES ('\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0À®ÛÀ','2012-09-01','2012-01-20 09:01:34','2011-02-12',0x1FDF59DC65,0000,'2011-07-07 19:48:34','xohwzrslzxbpxdvqfsumavjwwmsdcgczlmxrtxavsqtnpggxesvekbcelnnrxkvvlwqwbydlhwzltwaurkfltafeijstmzueiqddjdxzddymhsungndmojndbspkezvdfhqxijxxrwiolqgnsedenszkiljgropmcbxsjntjmnonnltyiysuejsznuurmonebslawybppziavystrylwunselezpbslmkzggpziffrud','2012-01-19 22:00:00');
|
||||
INSERT INTO t2 VALUES ('\0\0\0\0\0\0\0\0\0\0\0\0jø@\0\0\0\0\0\0\0\0','0000-00-00','2012-05-21 09:59:10','2011-04-17',0x02307EDF,0000,'2012-01-20 09:01:34','vjcwlxxeydntegsdqhxgriarmbvzwzwdexcalvacxhilaejpmxdpkuvblukchagzoellbdndelfednqktzobyhjqweqaugqnfikdalmaytyunjqvxcsirhaqnvqsstgrgfscnsemseebdemfditoswccsxthnddzslgjkyujxoqsvzrssymoovqmibcmbboruyxlvopengdqqgqwekrflhvjcpondxivnshvhrnqvfls','2012-09-23 23:54:02');
|
||||
|
||||
|
||||
INSERT INTO t3 VALUES (11787,'2012-07-24 15:22:50',0x00000000FF,'qbdydwxepydtonqnghurnuntughjwfygzttqwtmfzfbtifjcearpatksofbrfgnaccvapahywhsstdplphrxbcubhktov','2011-08-27 19:28:03',NULL,0x00000000001C);
|
||||
|
||||
INSERT INTO t3 VALUES (11788,'2012-05-17 08:38:13',0x3FFFFFFFFF,'jkvkjxaikruljqalyvnbfjptxgbpsgnxlzthhcrswwdcfrhilwwgqmxynxjnehwmyfzdyywjzfyasuvjbrevkxtnyodiu','2012-05-09 11:09:52',NULL,0x0000000000B8);
|
||||
|
||||
INSERT INTO t3 VALUES (1,'2011-02-17 19:55:19',0x000098FAF3,'rnzhemtrqjdrappwbmxnzkfatcgtvqklrpfpdqiwjnjbeaxpcbhqqunbzmtmitdszxyrdvkeedqwpbiefqnwvhiznwfyq','2012-11-10 18:00:25','\0\0\0\0\0\0\0\0\0\0\0\0jøÀ\0\0\0\0€1á@',0x7FFFFFFFFFFF);
|
||||
|
||||
INSERT INTO t3 VALUES (11789,'2011-12-26 01:30:56',0x0000000001,'dhryqjghgixymqywclxpovwnlgnltuzdvggmlaxtzrsbpxkahkiahpkrddpoeftqqwejbjxrdzfgvkzvhcalopgumspgg','2011-03-21 06:25:44',NULL,0x00000000293A);
|
||||
|
||||
INSERT INTO t3 VALUES (4294967296,'2011-04-12 21:05:37',0x0000CE3238,'xwcplgaxcpgfsmcjftxffxgmjwabpmrcycbxmwjvqtlvtlwuipuwgbuygnxomjplqohyuqyzsoiggroigcnchzpiilyhe','2012-03-20 05:35:39',NULL,0x00000000006E);
|
||||
|
||||
--enable_query_log
|
||||
|
||||
set session sort_buffer_size= 32768;
|
||||
select col435
|
||||
from t3
|
||||
natural right outer join t1
|
||||
natural right outer join t2 a
|
||||
left outer join t2 b on 1
|
||||
group by
|
||||
repeat('a',10000) desc,
|
||||
repeat('a',10000)
|
||||
with rollup
|
||||
;
|
||||
set session sort_buffer_size= default;
|
||||
|
||||
DROP TABLE t1, t2, t3;
|
@ -893,7 +893,7 @@
|
||||
fun:my_b_flush_io_cache
|
||||
fun:_my_b_write
|
||||
fun:_Z*10write_keysP13st_sort_paramPPhjP11st_io_cacheS4_
|
||||
fun:_Z*13find_all_keysP13st_sort_paramP10SQL_SELECTPPhP11st_io_cacheS6_S6_
|
||||
fun:_Z*13find_all_keysP13st_sort_paramP10SQL_SELECTPPhP11st_io_cacheS6_
|
||||
fun:_Z8filesortP3THDP5TABLEP13st_sort_fieldjP10SQL_SELECTybPy
|
||||
}
|
||||
|
||||
|
179
sql/filesort.cc
179
sql/filesort.cc
@ -48,7 +48,7 @@ static uchar *read_buffpek_from_file(IO_CACHE *buffer_file, uint count,
|
||||
uchar *buf);
|
||||
static ha_rows find_all_keys(SORTPARAM *param,SQL_SELECT *select,
|
||||
uchar * *sort_keys, IO_CACHE *buffer_file,
|
||||
IO_CACHE *tempfile,IO_CACHE *indexfile);
|
||||
IO_CACHE *tempfile);
|
||||
static int write_keys(SORTPARAM *param,uchar * *sort_keys,
|
||||
uint count, IO_CACHE *buffer_file, IO_CACHE *tempfile);
|
||||
static void make_sortkey(SORTPARAM *param,uchar *to, uchar *ref_pos);
|
||||
@ -88,8 +88,6 @@ static void unpack_addon_fields(struct st_sort_addon_field *addon_field,
|
||||
(Needed by UPDATE/INSERT or ALTER TABLE)
|
||||
@param examined_rows Store number of examined rows here
|
||||
|
||||
@todo
|
||||
check why we do this (param.keys--)
|
||||
@note
|
||||
If we sort by position (like if sort_positions is 1) filesort() will
|
||||
call table->prepare_for_position().
|
||||
@ -107,12 +105,12 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
|
||||
bool sort_positions, ha_rows *examined_rows)
|
||||
{
|
||||
int error;
|
||||
ulong memavl, min_sort_memory;
|
||||
ulong memory_available= thd->variables.sortbuff_size;
|
||||
uint maxbuffer;
|
||||
BUFFPEK *buffpek;
|
||||
ha_rows records= HA_POS_ERROR;
|
||||
ha_rows num_rows= HA_POS_ERROR;
|
||||
uchar **sort_keys= 0;
|
||||
IO_CACHE tempfile, buffpek_pointers, *selected_records_file, *outfile;
|
||||
IO_CACHE tempfile, buffpek_pointers, *outfile;
|
||||
SORTPARAM param;
|
||||
bool multi_byte_charset;
|
||||
DBUG_ENTER("filesort");
|
||||
@ -187,86 +185,71 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
|
||||
param.max_rows= max_rows;
|
||||
|
||||
if (select && select->quick)
|
||||
{
|
||||
status_var_increment(thd->status_var.filesort_range_count);
|
||||
}
|
||||
else
|
||||
{
|
||||
status_var_increment(thd->status_var.filesort_scan_count);
|
||||
}
|
||||
#ifdef CAN_TRUST_RANGE
|
||||
if (select && select->quick && select->quick->records > 0L)
|
||||
{
|
||||
records=min((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2),
|
||||
table->file->stats.records)+EXTRA_RECORDS;
|
||||
selected_records_file=0;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
records= table->file->estimate_rows_upper_bound();
|
||||
/*
|
||||
If number of records is not known, use as much of sort buffer
|
||||
as possible.
|
||||
*/
|
||||
if (records == HA_POS_ERROR)
|
||||
records--; // we use 'records+1' below.
|
||||
selected_records_file= 0;
|
||||
}
|
||||
|
||||
// If number of rows is not known, use as much of sort buffer as possible.
|
||||
num_rows= table->file->estimate_rows_upper_bound();
|
||||
|
||||
if (multi_byte_charset &&
|
||||
!(param.tmp_buffer= (char*) my_malloc(param.sort_length,MYF(MY_WME))))
|
||||
goto err;
|
||||
|
||||
memavl= thd->variables.sortbuff_size;
|
||||
min_sort_memory= max(MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
|
||||
while (memavl >= min_sort_memory)
|
||||
{
|
||||
ulong old_memavl;
|
||||
ulong keys= memavl/(param.rec_length+sizeof(char*));
|
||||
param.keys=(uint) min(records+1, keys);
|
||||
|
||||
if (table_sort.sort_keys &&
|
||||
table_sort.sort_keys_size != char_array_size(param.keys,
|
||||
param.rec_length))
|
||||
const ulong min_sort_memory=
|
||||
max(MIN_SORT_MEMORY, param.sort_length * MERGEBUFF2);
|
||||
while (memory_available >= min_sort_memory)
|
||||
{
|
||||
my_free(table_sort.sort_keys);
|
||||
table_sort.sort_keys= NULL;
|
||||
table_sort.sort_keys_size= 0;
|
||||
ulong keys= memory_available / (param.rec_length + sizeof(char*));
|
||||
param.keys=(uint) min(num_rows, keys);
|
||||
if (table_sort.sort_keys &&
|
||||
table_sort.sort_keys_size != char_array_size(param.keys,
|
||||
param.rec_length))
|
||||
{
|
||||
my_free(table_sort.sort_keys);
|
||||
table_sort.sort_keys= NULL;
|
||||
table_sort.sort_keys_size= 0;
|
||||
}
|
||||
if ((table_sort.sort_keys=
|
||||
make_char_array(table_sort.sort_keys,
|
||||
param.keys, param.rec_length, MYF(0))))
|
||||
{
|
||||
table_sort.sort_keys_size=
|
||||
char_array_size(param.keys, param.rec_length);
|
||||
break;
|
||||
}
|
||||
ulong old_memory_available= memory_available;
|
||||
memory_available= memory_available/4*3;
|
||||
if (memory_available < min_sort_memory &&
|
||||
old_memory_available > min_sort_memory)
|
||||
memory_available= min_sort_memory;
|
||||
}
|
||||
if ((table_sort.sort_keys=
|
||||
make_char_array(table_sort.sort_keys,
|
||||
param.keys, param.rec_length, MYF(0))))
|
||||
sort_keys= table_sort.sort_keys;
|
||||
if (memory_available < min_sort_memory)
|
||||
{
|
||||
table_sort.sort_keys_size= char_array_size(param.keys, param.rec_length);
|
||||
break;
|
||||
my_error(ER_OUT_OF_SORTMEMORY,MYF(ME_ERROR+ME_WAITTANG));
|
||||
goto err;
|
||||
}
|
||||
old_memavl=memavl;
|
||||
if ((memavl=memavl/4*3) < min_sort_memory && old_memavl > min_sort_memory)
|
||||
memavl= min_sort_memory;
|
||||
}
|
||||
sort_keys= table_sort.sort_keys;
|
||||
if (memavl < min_sort_memory)
|
||||
{
|
||||
my_error(ER_OUT_OF_SORTMEMORY,MYF(ME_ERROR+ME_WAITTANG));
|
||||
goto err;
|
||||
}
|
||||
if (open_cached_file(&buffpek_pointers,mysql_tmpdir,TEMP_PREFIX,
|
||||
DISK_BUFFER_SIZE, MYF(MY_WME)))
|
||||
goto err;
|
||||
|
||||
param.keys--; /* TODO: check why we do this */
|
||||
param.sort_form= table;
|
||||
param.end=(param.local_sortorder=sortorder)+s_length;
|
||||
if ((records=find_all_keys(¶m,select,sort_keys, &buffpek_pointers,
|
||||
&tempfile, selected_records_file)) ==
|
||||
HA_POS_ERROR)
|
||||
num_rows= find_all_keys(¶m,
|
||||
select,
|
||||
sort_keys,
|
||||
&buffpek_pointers,
|
||||
&tempfile);
|
||||
if (num_rows == HA_POS_ERROR)
|
||||
goto err;
|
||||
maxbuffer= (uint) (my_b_tell(&buffpek_pointers)/sizeof(*buffpek));
|
||||
|
||||
if (maxbuffer == 0) // The whole set is in memory
|
||||
{
|
||||
if (save_index(¶m,sort_keys,(uint) records, &table_sort))
|
||||
if (save_index(¶m,sort_keys,(uint) num_rows, &table_sort))
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
@ -298,8 +281,9 @@ 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.rec_length+sizeof(char*))) /
|
||||
param.rec_length-1);
|
||||
param.keys=((param.keys *
|
||||
(param.rec_length+sizeof(char*))) /
|
||||
param.rec_length - 1);
|
||||
maxbuffer--; // Offset from 0
|
||||
if (merge_many_buff(¶m,(uchar*) sort_keys,buffpek,&maxbuffer,
|
||||
&tempfile))
|
||||
@ -307,13 +291,21 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
|
||||
if (flush_io_cache(&tempfile) ||
|
||||
reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))
|
||||
goto err;
|
||||
if (merge_index(¶m,(uchar*) sort_keys,buffpek,maxbuffer,&tempfile,
|
||||
if (merge_index(¶m,
|
||||
(uchar*) sort_keys,
|
||||
buffpek,
|
||||
maxbuffer,
|
||||
&tempfile,
|
||||
outfile))
|
||||
goto err;
|
||||
}
|
||||
if (records > param.max_rows)
|
||||
records=param.max_rows;
|
||||
error =0;
|
||||
|
||||
if (num_rows > param.max_rows)
|
||||
{
|
||||
// If find_all_keys() produced more results than the query LIMIT.
|
||||
num_rows= param.max_rows;
|
||||
}
|
||||
error= 0;
|
||||
|
||||
err:
|
||||
my_free(param.tmp_buffer);
|
||||
@ -362,15 +354,15 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
|
||||
}
|
||||
else
|
||||
statistic_add(thd->status_var.filesort_rows,
|
||||
(ulong) records, &LOCK_status);
|
||||
(ulong) num_rows, &LOCK_status);
|
||||
*examined_rows= param.examined_rows;
|
||||
#ifdef SKIP_DBUG_IN_FILESORT
|
||||
DBUG_POP(); /* Ok to DBUG */
|
||||
#endif
|
||||
memcpy(&table->sort, &table_sort, sizeof(FILESORT_INFO));
|
||||
DBUG_PRINT("exit",("records: %ld", (long) records));
|
||||
MYSQL_FILESORT_DONE(error, records);
|
||||
DBUG_RETURN(error ? HA_POS_ERROR : records);
|
||||
DBUG_PRINT("exit",("num_rows: %ld", (long) num_rows));
|
||||
MYSQL_FILESORT_DONE(error, num_rows);
|
||||
DBUG_RETURN(error ? HA_POS_ERROR : num_rows);
|
||||
} /* filesort */
|
||||
|
||||
|
||||
@ -513,7 +505,6 @@ static void dbug_print_record(TABLE *table, bool print_rowid)
|
||||
@param buffpek_pointers File to write BUFFPEKs describing sorted segments
|
||||
in tempfile.
|
||||
@param tempfile File to write sorted sequences of sortkeys to.
|
||||
@param indexfile If !NULL, use it for source data (contains rowids)
|
||||
|
||||
@note
|
||||
Basic idea:
|
||||
@ -543,7 +534,7 @@ static void dbug_print_record(TABLE *table, bool print_rowid)
|
||||
static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
|
||||
uchar **sort_keys,
|
||||
IO_CACHE *buffpek_pointers,
|
||||
IO_CACHE *tempfile, IO_CACHE *indexfile)
|
||||
IO_CACHE *tempfile)
|
||||
{
|
||||
int error,flag,quick_select;
|
||||
uint idx,indexpos,ref_length;
|
||||
@ -568,12 +559,11 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
|
||||
ref_pos= ref_buff;
|
||||
quick_select=select && select->quick;
|
||||
record=0;
|
||||
flag= ((!indexfile && file->ha_table_flags() & HA_REC_NOT_IN_SEQ)
|
||||
|| quick_select);
|
||||
if (indexfile || flag)
|
||||
flag= ((file->ha_table_flags() & HA_REC_NOT_IN_SEQ) || quick_select);
|
||||
if (flag)
|
||||
ref_pos= &file->ref[0];
|
||||
next_pos=ref_pos;
|
||||
if (! indexfile && ! quick_select)
|
||||
if (!quick_select)
|
||||
{
|
||||
next_pos=(uchar*) 0; /* Find records in sequence */
|
||||
file->ha_rnd_init(1);
|
||||
@ -611,18 +601,8 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
|
||||
}
|
||||
else /* Not quick-select */
|
||||
{
|
||||
if (indexfile)
|
||||
{
|
||||
if (my_b_read(indexfile,(uchar*) ref_pos,ref_length)) /* purecov: deadcode */
|
||||
{
|
||||
error= my_errno ? my_errno : -1; /* Abort */
|
||||
break;
|
||||
}
|
||||
error=file->rnd_pos(sort_form->record[0],next_pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
error=file->rnd_next(sort_form->record[0]);
|
||||
error= file->rnd_next(sort_form->record[0]);
|
||||
if (!flag)
|
||||
{
|
||||
my_store_ptr(ref_pos,ref_length,record); // Position to row
|
||||
@ -638,7 +618,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
|
||||
if (*killed)
|
||||
{
|
||||
DBUG_PRINT("info",("Sort killed by user"));
|
||||
if (!indexfile && !quick_select)
|
||||
if (!quick_select)
|
||||
{
|
||||
(void) file->extra(HA_EXTRA_NO_CACHE);
|
||||
file->ha_rnd_end();
|
||||
@ -652,9 +632,10 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
|
||||
{
|
||||
if (idx == param->keys)
|
||||
{
|
||||
if (write_keys(param,sort_keys,idx,buffpek_pointers,tempfile))
|
||||
if (write_keys(param, sort_keys,
|
||||
idx, buffpek_pointers, tempfile))
|
||||
DBUG_RETURN(HA_POS_ERROR);
|
||||
idx=0;
|
||||
idx= 0;
|
||||
indexpos++;
|
||||
}
|
||||
make_sortkey(param,sort_keys[idx++],ref_pos);
|
||||
@ -681,15 +662,17 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
|
||||
DBUG_PRINT("test",("error: %d indexpos: %d",error,indexpos));
|
||||
if (error != HA_ERR_END_OF_FILE)
|
||||
{
|
||||
file->print_error(error,MYF(ME_ERROR | ME_WAITTANG)); /* purecov: inspected */
|
||||
file->print_error(error,MYF(ME_ERROR | ME_WAITTANG)); // purecov: inspected
|
||||
DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
|
||||
}
|
||||
if (indexpos && idx &&
|
||||
write_keys(param,sort_keys,idx,buffpek_pointers,tempfile))
|
||||
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->rec_length) :
|
||||
idx);
|
||||
const ha_rows retval=
|
||||
my_b_inited(tempfile) ?
|
||||
(ha_rows) (my_b_tell(tempfile)/param->rec_length) : idx;
|
||||
DBUG_RETURN(retval);
|
||||
} /* find_all_keys */
|
||||
|
||||
|
||||
@ -1269,8 +1252,8 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
|
||||
{
|
||||
buffpek->base= strpos;
|
||||
buffpek->max_keys= maxcount;
|
||||
strpos+= (uint) (error= (int) read_to_buffer(from_file, buffpek,
|
||||
rec_length));
|
||||
strpos+=
|
||||
(uint) (error= (int) read_to_buffer(from_file, buffpek, rec_length));
|
||||
if (error == -1)
|
||||
goto err; /* purecov: inspected */
|
||||
buffpek->max_keys= buffpek->mem_count; // If less data in buffers than expected
|
||||
|
Loading…
x
Reference in New Issue
Block a user