summaryrefslogtreecommitdiff
path: root/sql/filesort.cc
diff options
context:
space:
mode:
authorunknown <monty@mysql.com>2004-10-29 19:26:52 +0300
committerunknown <monty@mysql.com>2004-10-29 19:26:52 +0300
commitf095274fe8c3d3394d6c0ce0a68f4bea04311999 (patch)
tree23bcc9a71fe7237887a111b158e30f5a6bb665d3 /sql/filesort.cc
parentf41bba8c6156a7adf4c67dfa75e16112767a5d3c (diff)
parent5be6c328f5a9f78f37176bbbd88a538fa3b65fe9 (diff)
downloadmariadb-git-f095274fe8c3d3394d6c0ce0a68f4bea04311999.tar.gz
merge with 4.1
BitKeeper/etc/ignore: auto-union BitKeeper/etc/logging_ok: auto-union BitKeeper/triggers/post-commit: Auto merged Docs/Support/texi2html: Auto merged Makefile.am: Auto merged client/Makefile.am: Auto merged client/mysql.cc: Auto merged client/mysqldump.c: Auto merged include/my_base.h: Auto merged include/my_global.h: Auto merged include/my_pthread.h: Auto merged include/my_sys.h: Auto merged include/my_time.h: Auto merged include/mysql.h: Auto merged include/mysql_com.h: Auto merged innobase/buf/buf0buf.c: Auto merged innobase/include/row0mysql.h: Auto merged innobase/row/row0sel.c: Auto merged libmysql/libmysql.c: Auto merged libmysqld/examples/Makefile.am: Auto merged myisam/mi_check.c: Auto merged mysql-test/include/ps_modify.inc: Auto merged mysql-test/install_test_db.sh: Auto merged mysql-test/r/alter_table.result: Auto merged mysql-test/r/auto_increment.result: Auto merged mysql-test/r/bdb.result: Auto merged mysql-test/r/ctype_latin1_de.result: Auto merged mysql-test/r/ctype_recoding.result: Auto merged mysql-test/r/fulltext.result: Auto merged mysql-test/r/func_gconcat.result: Auto merged mysql-test/r/func_group.result: Auto merged mysql-test/r/func_if.result: Auto merged mysql-test/t/derived.test: Auto merged mysql-test/t/insert.test: merge with 4.1 Fixed test case to not use 'if exists' when it shouldn't mysql-test/t/range.test: merge with 4.1 Added missing drop table sql/ha_ndbcluster.cc: merge with 4.1 Simple optimization: use max() instead of ? : sql/item_func.cc: merge with 4.1 (Added back old variable names for easier merges) sql/opt_range.cc: merge with 4.1 Removed argument 'parent_alloc' from QUICK_RANGE_SELECT as this was not used Added assert if using QUICK_GROUP_MIN_MAX_SELECT with parent_alloc as the init() function can't handle this Changed back get_quick_select_for_ref() to use it's own alloc root becasue this function may be called several times for one query sql/sql_handler.cc: merge with 4.1 change variable 'err' to 'error' as same function had a label named 'err' sql/sql_update.cc: Use multi-update code from 5.0 instead of 4.1 We will fix the locking code shortly in 5.0 to be faster than in 4.1
Diffstat (limited to 'sql/filesort.cc')
-rw-r--r--sql/filesort.cc85
1 files changed, 79 insertions, 6 deletions
diff --git a/sql/filesort.cc b/sql/filesort.cc
index ef8148616e5..3e56acefea9 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -179,7 +179,13 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
else
#endif
{
- records=table->file->estimate_number_of_rows();
+ 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;
}
@@ -327,7 +333,7 @@ static char **make_char_array(register uint fields, uint length, myf my_flag)
} /* make_char_array */
- /* Read all buffer pointers into memory */
+/* Read 'count' number of buffer pointers into memory */
static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count)
{
@@ -348,8 +354,40 @@ static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count)
}
-
- /* Search after sort_keys and place them in a temp. file */
+/*
+ Search after sort_keys and write them into tempfile.
+ SYNOPSIS
+ find_all_keys()
+ param Sorting parameter
+ select Use this to get source data
+ sort_keys Array of pointers to sort key + addon buffers.
+ buffpek_pointers File to write BUFFPEKs describing sorted segments
+ in tempfile.
+ tempfile File to write sorted sequences of sortkeys to.
+ indexfile If !NULL, use it for source data (contains rowids)
+
+ NOTE
+ Basic idea:
+ while (get_next_sortkey())
+ {
+ if (no free space in sort_keys buffers)
+ {
+ sort sort_keys buffer;
+ dump sorted sequence to 'tempfile';
+ dump BUFFPEK describing sequence location into 'buffpek_pointers';
+ }
+ put sort key into 'sort_keys';
+ }
+ if (sort_keys has some elements && dumped at least once)
+ sort-dump-dump as above;
+ else
+ don't sort, leave sort_keys array to be sorted by caller.
+
+ All produced sequences are guaranteed to be non-empty.
+ RETURN
+ Number of records written on success.
+ HA_POS_ERROR on error.
+*/
static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
uchar **sort_keys,
@@ -489,7 +527,25 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
} /* find_all_keys */
- /* Skriver en buffert med nycklar till filen */
+/*
+ Sort the buffer and write:
+ 1) the sorted sequence to tempfile
+ 2) a BUFFPEK describing the sorted sequence position to buffpek_pointers
+ (was: Skriver en buffert med nycklar till filen)
+ SYNOPSIS
+ write_keys()
+ param Sort parameters
+ sort_keys Array of pointers to keys to sort
+ count Number of elements in sort_keys array
+ buffpek_pointers One 'BUFFPEK' struct will be written into this file.
+ The BUFFPEK::{file_pos, count} will indicate where
+ the sorted data was stored.
+ tempfile The sorted sequence will be written into this file.
+
+ RETURN
+ 0 OK
+ 1 Error
+*/
static int
write_keys(SORTPARAM *param, register uchar **sort_keys, uint count,
@@ -854,7 +910,21 @@ void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint key_length)
/*
- Merge buffers to one buffer
+ Merge buffers to one buffer
+ SYNOPSIS
+ merge_buffers()
+ param Sort parameter
+ from_file File with source data (BUFFPEKs point to this file)
+ to_file File to write the sorted result data.
+ sort_buffer Buffer for data to store up to MERGEBUFF2 sort keys.
+ lastbuff OUT Store here BUFFPEK describing data written to to_file
+ Fb First element in source BUFFPEKs array
+ Tb Last element in source BUFFPEKs array
+ flag
+
+ RETURN
+ 0 - OK
+ other - error
*/
int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
@@ -893,6 +963,9 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
strpos= (uchar*) sort_buffer;
org_max_rows=max_rows= param->max_rows;
+ /* The following will fire if there is not enough space in sort_buffer */
+ DBUG_ASSERT(maxcount!=0);
+
if (init_queue(&queue, (uint) (Tb-Fb)+1, offsetof(BUFFPEK,key), 0,
(queue_compare) (cmp= get_ptr_compare(sort_length)),
(void*) &sort_length))