1 /* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. 2 3 This program is free software; you can redistribute it and/or modify 4 it under the terms of the GNU General Public License as published by 5 the Free Software Foundation; version 2 of the License. 6 7 This program is distributed in the hope that it will be useful, 8 but WITHOUT ANY WARRANTY; without even the implied warranty of 9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 GNU General Public License for more details. 11 12 You should have received a copy of the GNU General Public License 13 along with this program; if not, write to the Free Software 14 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ 15 16 #ifndef FILESORT_INCLUDED 17 #define FILESORT_INCLUDED 18 19 #include "my_base.h" /* ha_rows */ 20 #include "sql_alloc.h" 21 #include "filesort_utils.h" 22 23 class SQL_SELECT; 24 class THD; 25 struct TABLE; 26 class Filesort_tracker; 27 struct SORT_FIELD; 28 struct SORT_FIELD_ATTR; 29 typedef struct st_order ORDER; 30 class JOIN; 31 class Addon_fields; 32 class Sort_keys; 33 34 35 /** 36 Sorting related info. 37 To be extended by another WL to include complete filesort implementation. 38 */ 39 class Filesort: public Sql_alloc 40 { 41 public: 42 /** List of expressions to order the table by */ 43 ORDER *order; 44 /** Number of records to return */ 45 ha_rows limit; 46 /** ORDER BY list with some precalculated info for filesort */ 47 SORT_FIELD *sortorder; 48 /** select to use for getting records */ 49 SQL_SELECT *select; 50 /** TRUE <=> free select on destruction */ 51 bool own_select; 52 /** true means we are using Priority Queue for order by with limit. */ 53 bool using_pq; 54 55 /* 56 TRUE means sort operation must produce table rowids. 57 FALSE means that it halso has an option of producing {sort_key, 58 addon_fields} pairs. 59 */ 60 bool sort_positions; 61 62 Filesort_tracker *tracker; 63 Sort_keys *sort_keys; 64 Filesort(ORDER * order_arg,ha_rows limit_arg,bool sort_positions_arg,SQL_SELECT * select_arg)65 Filesort(ORDER *order_arg, ha_rows limit_arg, bool sort_positions_arg, 66 SQL_SELECT *select_arg): 67 order(order_arg), 68 limit(limit_arg), 69 sortorder(NULL), 70 select(select_arg), 71 own_select(false), 72 using_pq(false), 73 sort_positions(sort_positions_arg), 74 sort_keys(NULL) 75 { 76 DBUG_ASSERT(order); 77 }; 78 ~Filesort()79 ~Filesort() { cleanup(); } 80 /* Prepare ORDER BY list for sorting. */ 81 Sort_keys* make_sortorder(THD *thd, JOIN *join, table_map first_table_bit); 82 83 private: 84 void cleanup(); 85 }; 86 87 88 class SORT_INFO 89 { 90 /// Buffer for sorting keys. 91 Filesort_buffer filesort_buffer; 92 93 public: SORT_INFO()94 SORT_INFO() 95 :addon_fields(NULL), record_pointers(0), 96 sort_keys(NULL), 97 sorted_result_in_fsbuf(FALSE) 98 { 99 buffpek.str= 0; 100 my_b_clear(&io_cache); 101 } 102 103 ~SORT_INFO(); 104 free_data()105 void free_data() 106 { 107 close_cached_file(&io_cache); 108 free_addon_buff(); 109 my_free(record_pointers); 110 my_free(buffpek.str); 111 my_free(addon_fields); 112 free_sort_buffer(); 113 } 114 reset()115 void reset() 116 { 117 free_data(); 118 record_pointers= 0; 119 buffpek.str= 0; 120 addon_fields= 0; 121 sorted_result_in_fsbuf= false; 122 } 123 124 void free_addon_buff(); 125 126 IO_CACHE io_cache; /* If sorted through filesort */ 127 LEX_STRING buffpek; /* Buffer for buffpek structures */ 128 Addon_fields *addon_fields; /* Addon field descriptors */ 129 uchar *record_pointers; /* If sorted in memory */ 130 Sort_keys *sort_keys; /* Sort key descriptors*/ 131 132 /** 133 If the entire result of filesort fits in memory, we skip the merge phase. 134 We may leave the result in filesort_buffer 135 (indicated by sorted_result_in_fsbuf), or we may strip away 136 the sort keys, and copy the sorted result into a new buffer. 137 @see save_index() 138 */ 139 bool sorted_result_in_fsbuf; 140 141 /* 142 How many rows in final result. 143 Also how many rows in record_pointers, if used 144 */ 145 ha_rows return_rows; 146 ha_rows examined_rows; /* How many rows read */ 147 ha_rows found_rows; /* How many rows was accepted */ 148 149 /** Sort filesort_buffer */ sort_buffer(Sort_param * param,uint count)150 void sort_buffer(Sort_param *param, uint count) 151 { filesort_buffer.sort_buffer(param, count); } 152 get_sort_keys()153 uchar **get_sort_keys() 154 { return filesort_buffer.get_sort_keys(); } 155 get_sorted_record(uint ix)156 uchar *get_sorted_record(uint ix) 157 { return filesort_buffer.get_sorted_record(ix); } 158 alloc_sort_buffer(uint num_records,uint record_length)159 uchar *alloc_sort_buffer(uint num_records, uint record_length) 160 { return filesort_buffer.alloc_sort_buffer(num_records, record_length); } 161 free_sort_buffer()162 void free_sort_buffer() 163 { filesort_buffer.free_sort_buffer(); } 164 isfull()165 bool isfull() const 166 { return filesort_buffer.isfull(); } init_record_pointers()167 void init_record_pointers() 168 { filesort_buffer.init_record_pointers(); } init_next_record_pointer()169 void init_next_record_pointer() 170 { filesort_buffer.init_next_record_pointer(); } get_next_record_pointer()171 uchar *get_next_record_pointer() 172 { return filesort_buffer.get_next_record_pointer(); } adjust_next_record_pointer(uint val)173 void adjust_next_record_pointer(uint val) 174 { filesort_buffer.adjust_next_record_pointer(val); } 175 get_raw_buf()176 Bounds_checked_array<uchar> get_raw_buf() 177 { return filesort_buffer.get_raw_buf(); } 178 sort_buffer_size()179 size_t sort_buffer_size() const 180 { return filesort_buffer.sort_buffer_size(); } 181 is_allocated()182 bool is_allocated() const 183 { return filesort_buffer.is_allocated(); } set_sort_length(uint val)184 void set_sort_length(uint val) 185 { filesort_buffer.set_sort_length(val); } get_sort_length()186 uint get_sort_length() const 187 { return filesort_buffer.get_sort_length(); } 188 has_filesort_result_in_memory()189 bool has_filesort_result_in_memory() const 190 { 191 return record_pointers || sorted_result_in_fsbuf; 192 } 193 194 /// Are we using "addon fields"? using_addon_fields()195 bool using_addon_fields() const 196 { 197 return addon_fields != NULL; 198 } 199 200 /// Are we using "packed addon fields"? 201 bool using_packed_addons(); 202 203 /** 204 Copies (unpacks) values appended to sorted fields from a buffer back to 205 their regular positions specified by the Field::ptr pointers. 206 @param buff Buffer which to unpack the value from 207 */ 208 template<bool Packed_addon_fields> 209 inline void unpack_addon_fields(uchar *buff); 210 211 bool using_packed_sortkeys(); 212 213 friend SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort, 214 Filesort_tracker* tracker, JOIN *join, 215 table_map first_table_bit); 216 }; 217 218 SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort, 219 Filesort_tracker* tracker, JOIN *join=NULL, 220 table_map first_table_bit=0); 221 222 bool filesort_use_addons(TABLE *table, uint sortlength, 223 uint *length, uint *fields, uint *null_fields, 224 uint *m_packable_length); 225 226 void change_double_for_sort(double nr,uchar *to); 227 void store_length(uchar *to, uint length, uint pack_length); 228 void 229 reverse_key(uchar *to, const SORT_FIELD_ATTR *sort_field); 230 231 #endif /* FILESORT_INCLUDED */ 232