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-1301 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
23class SQL_SELECT;
24class THD;
25struct TABLE;
26class Filesort_tracker;
27struct SORT_FIELD;
28typedef struct st_order ORDER;
29class JOIN;
30
31
32/**
33 Sorting related info.
34 To be extended by another WL to include complete filesort implementation.
35*/
36class Filesort: public Sql_alloc
37{
38public:
39 /** List of expressions to order the table by */
40 ORDER *order;
41 /** Number of records to return */
42 ha_rows limit;
43 /** ORDER BY list with some precalculated info for filesort */
44 SORT_FIELD *sortorder;
45 /** select to use for getting records */
46 SQL_SELECT *select;
47 /** TRUE <=> free select on destruction */
48 bool own_select;
49 /** true means we are using Priority Queue for order by with limit. */
50 bool using_pq;
51
52 /*
53 TRUE means sort operation must produce table rowids.
54 FALSE means that it halso has an option of producing {sort_key,
55 addon_fields} pairs.
56 */
57 bool sort_positions;
58
59 Filesort_tracker *tracker;
60
61 Filesort(ORDER *order_arg, ha_rows limit_arg, bool sort_positions_arg,
62 SQL_SELECT *select_arg):
63 order(order_arg),
64 limit(limit_arg),
65 sortorder(NULL),
66 select(select_arg),
67 own_select(false),
68 using_pq(false),
69 sort_positions(sort_positions_arg)
70 {
71 DBUG_ASSERT(order);
72 };
73
74 ~Filesort() { cleanup(); }
75 /* Prepare ORDER BY list for sorting. */
76 uint make_sortorder(THD *thd, JOIN *join, table_map first_table_bit);
77
78private:
79 void cleanup();
80};
81
82
83class SORT_INFO
84{
85 /// Buffer for sorting keys.
86 Filesort_buffer filesort_buffer;
87
88public:
89 SORT_INFO()
90 :addon_field(0), record_pointers(0)
91 {
92 buffpek.str= 0;
93 my_b_clear(&io_cache);
94 }
95
96 ~SORT_INFO();
97
98 void free_data()
99 {
100 close_cached_file(&io_cache);
101 my_free(record_pointers);
102 my_free(buffpek.str);
103 my_free(addon_field);
104 }
105
106 void reset()
107 {
108 free_data();
109 record_pointers= 0;
110 buffpek.str= 0;
111 addon_field= 0;
112 }
113
114
115 IO_CACHE io_cache; /* If sorted through filesort */
116 LEX_STRING buffpek; /* Buffer for buffpek structures */
117 LEX_STRING addon_buf; /* Pointer to a buffer if sorted with fields */
118 struct st_sort_addon_field *addon_field; /* Pointer to the fields info */
119 /* To unpack back */
120 void (*unpack)(struct st_sort_addon_field *, uchar *, uchar *);
121 uchar *record_pointers; /* If sorted in memory */
122 /*
123 How many rows in final result.
124 Also how many rows in record_pointers, if used
125 */
126 ha_rows return_rows;
127 ha_rows examined_rows; /* How many rows read */
128 ha_rows found_rows; /* How many rows was accepted */
129
130 /** Sort filesort_buffer */
131 void sort_buffer(Sort_param *param, uint count)
132 { filesort_buffer.sort_buffer(param, count); }
133
134 /**
135 Accessors for Filesort_buffer (which @c).
136 */
137 uchar *get_record_buffer(uint idx)
138 { return filesort_buffer.get_record_buffer(idx); }
139
140 uchar **get_sort_keys()
141 { return filesort_buffer.get_sort_keys(); }
142
143 uchar **alloc_sort_buffer(uint num_records, uint record_length)
144 { return filesort_buffer.alloc_sort_buffer(num_records, record_length); }
145
146 void free_sort_buffer()
147 { filesort_buffer.free_sort_buffer(); }
148
149 void init_record_pointers()
150 { filesort_buffer.init_record_pointers(); }
151
152 size_t sort_buffer_size() const
153 { return filesort_buffer.sort_buffer_size(); }
154
155 friend SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort,
156 Filesort_tracker* tracker, JOIN *join,
157 table_map first_table_bit);
158};
159
160SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort,
161 Filesort_tracker* tracker, JOIN *join=NULL,
162 table_map first_table_bit=0);
163
164void change_double_for_sort(double nr,uchar *to);
165
166#endif /* FILESORT_INCLUDED */
167