diff options
Diffstat (limited to 'sql/filesort.h')
-rw-r--r-- | sql/filesort.h | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/sql/filesort.h b/sql/filesort.h new file mode 100644 index 00000000..ebb521e2 --- /dev/null +++ b/sql/filesort.h @@ -0,0 +1,245 @@ +/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ + +#ifndef FILESORT_INCLUDED +#define FILESORT_INCLUDED + +#include "my_base.h" /* ha_rows */ +#include "sql_alloc.h" +#include "filesort_utils.h" + +class SQL_SELECT; +class THD; +struct TABLE; +class Filesort_tracker; +struct SORT_FIELD; +struct SORT_FIELD_ATTR; +typedef struct st_order ORDER; +class JOIN; +class Addon_fields; +class Sort_keys; + + +/** + Sorting related info. + To be extended by another WL to include complete filesort implementation. +*/ +class Filesort: public Sql_alloc +{ +public: + /** List of expressions to order the table by */ + ORDER *order; + /** Number of records to return */ + ha_rows limit; + /** ORDER BY list with some precalculated info for filesort */ + SORT_FIELD *sortorder; + /* Used with ROWNUM. Contains the number of rows filesort has found so far */ + ha_rows *accepted_rows; + /** select to use for getting records */ + SQL_SELECT *select; + + /** TRUE <=> free select on destruction */ + bool own_select; + /** TRUE means we are using Priority Queue for order by with limit. */ + bool using_pq; + /* + TRUE means sort operation must produce table rowids. + FALSE means that it halso has an option of producing {sort_key, + addon_fields} pairs. + */ + bool sort_positions; + /* + TRUE means all the fields of table of whose bitmap read_set is set + need to be read while reading records in the sort buffer. + FALSE otherwise + */ + bool set_all_read_bits; + + Filesort_tracker *tracker; + Sort_keys *sort_keys; + + /* Unpack temp table columns to base table columns*/ + void (*unpack)(TABLE *); + + Filesort(ORDER *order_arg, ha_rows limit_arg, bool sort_positions_arg, + SQL_SELECT *select_arg): + order(order_arg), + limit(limit_arg), + sortorder(NULL), + accepted_rows(0), + select(select_arg), + own_select(false), + using_pq(false), + sort_positions(sort_positions_arg), + set_all_read_bits(false), + sort_keys(NULL), + unpack(NULL) + { + DBUG_ASSERT(order); + }; + + ~Filesort() { cleanup(); } + /* Prepare ORDER BY list for sorting. */ + Sort_keys* make_sortorder(THD *thd, JOIN *join, table_map first_table_bit); + +private: + void cleanup(); +}; + + +class SORT_INFO +{ + /// Buffer for sorting keys. + Filesort_buffer filesort_buffer; + +public: + SORT_INFO() + :addon_fields(NULL), record_pointers(0), + sort_keys(NULL), + sorted_result_in_fsbuf(FALSE) + { + buffpek.str= 0; + my_b_clear(&io_cache); + } + + ~SORT_INFO(); + + void free_data() + { + close_cached_file(&io_cache); + free_addon_buff(); + my_free(record_pointers); + my_free(buffpek.str); + my_free(addon_fields); + free_sort_buffer(); + } + + void reset() + { + free_data(); + record_pointers= 0; + buffpek.str= 0; + addon_fields= 0; + sorted_result_in_fsbuf= false; + } + + void free_addon_buff(); + + IO_CACHE io_cache; /* If sorted through filesort */ + LEX_STRING buffpek; /* Buffer for buffpek structures */ + Addon_fields *addon_fields; /* Addon field descriptors */ + uchar *record_pointers; /* If sorted in memory */ + Sort_keys *sort_keys; /* Sort key descriptors*/ + + /** + If the entire result of filesort fits in memory, we skip the merge phase. + We may leave the result in filesort_buffer + (indicated by sorted_result_in_fsbuf), or we may strip away + the sort keys, and copy the sorted result into a new buffer. + @see save_index() + */ + bool sorted_result_in_fsbuf; + + /* + How many rows in final result. + Also how many rows in record_pointers, if used + */ + ha_rows return_rows; + ha_rows examined_rows; /* How many rows read */ + ha_rows found_rows; /* How many rows was accepted */ + + /** Sort filesort_buffer */ + void sort_buffer(Sort_param *param, uint count) + { filesort_buffer.sort_buffer(param, count); } + + uchar **get_sort_keys() + { return filesort_buffer.get_sort_keys(); } + + uchar *get_sorted_record(uint ix) + { return filesort_buffer.get_sorted_record(ix); } + + uchar *alloc_sort_buffer(uint num_records, uint record_length) + { return filesort_buffer.alloc_sort_buffer(num_records, record_length); } + + void free_sort_buffer() + { filesort_buffer.free_sort_buffer(); } + + bool isfull() const + { return filesort_buffer.isfull(); } + void init_record_pointers() + { filesort_buffer.init_record_pointers(); } + void init_next_record_pointer() + { filesort_buffer.init_next_record_pointer(); } + uchar *get_next_record_pointer() + { return filesort_buffer.get_next_record_pointer(); } + void adjust_next_record_pointer(uint val) + { filesort_buffer.adjust_next_record_pointer(val); } + + Bounds_checked_array<uchar> get_raw_buf() + { return filesort_buffer.get_raw_buf(); } + + size_t sort_buffer_size() const + { return filesort_buffer.sort_buffer_size(); } + + bool is_allocated() const + { return filesort_buffer.is_allocated(); } + void set_sort_length(uint val) + { filesort_buffer.set_sort_length(val); } + uint get_sort_length() const + { return filesort_buffer.get_sort_length(); } + + bool has_filesort_result_in_memory() const + { + return record_pointers || sorted_result_in_fsbuf; + } + + /// Are we using "addon fields"? + bool using_addon_fields() const + { + return addon_fields != NULL; + } + + /// Are we using "packed addon fields"? + bool using_packed_addons(); + + /** + Copies (unpacks) values appended to sorted fields from a buffer back to + their regular positions specified by the Field::ptr pointers. + @param buff Buffer which to unpack the value from + */ + template<bool Packed_addon_fields> + inline void unpack_addon_fields(uchar *buff); + + bool using_packed_sortkeys(); + + friend SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort, + Filesort_tracker* tracker, JOIN *join, + table_map first_table_bit); +}; + +SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort, + Filesort_tracker* tracker, JOIN *join=NULL, + table_map first_table_bit=0); + +bool filesort_use_addons(TABLE *table, uint sortlength, + uint *length, uint *fields, uint *null_fields, + uint *m_packable_length); + +void change_double_for_sort(double nr,uchar *to); +void store_length(uchar *to, uint length, uint pack_length); +void +reverse_key(uchar *to, const SORT_FIELD_ATTR *sort_field); + +#endif /* FILESORT_INCLUDED */ |