1 /* Copyright (C) 2014 InfiniDB, Inc.
2    Copyright (c) 2019 MariaDB Corporation
3 
4    This program is free software; you can redistribute it and/or
5    modify it under the terms of the GNU General Public License
6    as published by the Free Software Foundation; version 2 of
7    the License.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17    MA 02110-1301, USA. */
18 
19 //  $Id: idborderby.h 4012 2013-07-24 21:04:45Z pleblanc $
20 
21 
22 /** @file */
23 
24 #ifndef IDB_ORDER_BY_H
25 #define IDB_ORDER_BY_H
26 
27 #include <queue>
28 #include <utility>
29 #include <vector>
30 #include <sstream>
31 #include <boost/shared_array.hpp>
32 #include <boost/scoped_ptr.hpp>
33 
34 #ifdef _MSC_VER
35 #include <unordered_set>
36 #else
37 #include <tr1/unordered_set>
38 #endif
39 
40 #include "rowgroup.h"
41 #include "hasher.h"
42 #include "stlpoolallocator.h"
43 
44 // forward reference
45 namespace joblist
46 {
47 class  ResourceManager;
48 }
49 
50 
51 namespace ordering
52 {
53 
54 template<typename _Tp, typename _Sequence = std::vector<_Tp>,
55     typename _Compare  = std::less<typename _Sequence::value_type> >
56 class reservablePQ: private std::priority_queue<_Tp, _Sequence, _Compare>
57 {
58 public:
59     typedef typename std::priority_queue<_Tp, _Sequence, _Compare>::size_type size_type;
60     reservablePQ(size_type capacity = 0) { reserve(capacity); };
reserve(size_type capacity)61     void reserve(size_type capacity) { this->c.reserve(capacity); }
capacity()62     size_type capacity() const { return this->c.capacity(); }
63     using std::priority_queue<_Tp, _Sequence, _Compare>::size;
64     using std::priority_queue<_Tp, _Sequence, _Compare>::top;
65     using std::priority_queue<_Tp, _Sequence, _Compare>::pop;
66     using std::priority_queue<_Tp, _Sequence, _Compare>::push;
67     using std::priority_queue<_Tp, _Sequence, _Compare>::empty;
68 };
69 
70 // forward reference
71 class  IdbCompare;
72 class OrderByRow;
73 
74 typedef reservablePQ<OrderByRow> SortingPQ;
75 
76 // order by specification
77 struct IdbSortSpec
78 {
79     int fIndex;
80     // TODO There are three ordering specs since 10.2
81     int fAsc;   // <ordering specification> ::= ASC | DESC
82     int fNf;    // <null ordering> ::= NULLS FIRST | NULLS LAST
83 
IdbSortSpecIdbSortSpec84     IdbSortSpec() : fIndex(-1), fAsc(1), fNf(1) {}
IdbSortSpecIdbSortSpec85     IdbSortSpec(int i, bool b) : fIndex(i), fAsc(b ? 1 : -1), fNf(fAsc) {}
IdbSortSpecIdbSortSpec86     IdbSortSpec(int i, bool b, bool n) : fIndex(i), fAsc(b ? 1 : -1), fNf(n ? 1 : -1) {}
87 };
88 
89 
90 // compare functor for different datatypes
91 // cannot use template because Row's getXxxField method.
92 class Compare
93 {
94 public:
Compare(const IdbSortSpec & spec)95     Compare(const IdbSortSpec& spec) : fSpec(spec) {}
~Compare()96     virtual ~Compare() {}
97 
98     virtual int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer) = 0;
revertSortSpec()99     void revertSortSpec()
100     {
101         fSpec.fAsc = -fSpec.fAsc;
102         fSpec.fNf = -fSpec.fNf;
103     }
104 
105 protected:
106     IdbSortSpec fSpec;
107 };
108 
109 // Comparators for signed types
110 
111 class TinyIntCompare : public Compare
112 {
113 public:
TinyIntCompare(const IdbSortSpec & spec)114     TinyIntCompare(const IdbSortSpec& spec) : Compare(spec) {}
115 
116     int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
117 };
118 
119 
120 class SmallIntCompare : public Compare
121 {
122 public:
SmallIntCompare(const IdbSortSpec & spec)123     SmallIntCompare(const IdbSortSpec& spec) : Compare(spec) {}
124 
125     int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
126 };
127 
128 
129 class IntCompare : public Compare
130 {
131 public:
IntCompare(const IdbSortSpec & spec)132     IntCompare(const IdbSortSpec& spec) : Compare(spec) {}
133 
134     int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
135 };
136 
137 
138 class BigIntCompare : public Compare
139 {
140 public:
BigIntCompare(const IdbSortSpec & spec)141     BigIntCompare(const IdbSortSpec& spec) : Compare(spec) {}
142 
143     int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
144 };
145 
146 // End of comparators for signed types
147 // Comparators for unsigned types
148 
149 class UTinyIntCompare : public Compare
150 {
151 public:
UTinyIntCompare(const IdbSortSpec & spec)152     UTinyIntCompare(const IdbSortSpec& spec) : Compare(spec) {}
153 
154     int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
155 };
156 
157 
158 class USmallIntCompare : public Compare
159 {
160 public:
USmallIntCompare(const IdbSortSpec & spec)161     USmallIntCompare(const IdbSortSpec& spec) : Compare(spec) {}
162 
163     int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
164 };
165 
166 
167 class UIntCompare : public Compare
168 {
169 public:
UIntCompare(const IdbSortSpec & spec)170     UIntCompare(const IdbSortSpec& spec) : Compare(spec) {}
171 
172     int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
173 };
174 
175 
176 class UBigIntCompare : public Compare
177 {
178 public:
UBigIntCompare(const IdbSortSpec & spec)179     UBigIntCompare(const IdbSortSpec& spec) : Compare(spec) {}
180 
181     int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
182 };
183 
184 // end of comparators for unsigned types
185 
186 // Comparators for float types
187 
188 class DoubleCompare : public Compare
189 {
190 public:
DoubleCompare(const IdbSortSpec & spec)191     DoubleCompare(const IdbSortSpec& spec) : Compare(spec) {}
192 
193     int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
194 };
195 
196 
197 class LongDoubleCompare : public Compare
198 {
199 public:
LongDoubleCompare(const IdbSortSpec & spec)200     LongDoubleCompare(const IdbSortSpec& spec) : Compare(spec) {}
201 
202     int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
203 };
204 
205 
206 class FloatCompare : public Compare
207 {
208 public:
FloatCompare(const IdbSortSpec & spec)209     FloatCompare(const IdbSortSpec& spec) : Compare(spec) {}
210 
211     int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
212 };
213 
214 // End of comparators for float types
215 // Comparators for temporal types
216 
217 class DateCompare : public Compare
218 {
219 public:
DateCompare(const IdbSortSpec & spec)220     DateCompare(const IdbSortSpec& spec) : Compare(spec) {}
221 
222     int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
223 };
224 
225 
226 class DatetimeCompare : public Compare
227 {
228 public:
DatetimeCompare(const IdbSortSpec & spec)229     DatetimeCompare(const IdbSortSpec& spec) : Compare(spec) {}
230 
231     int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
232 };
233 
234 
235 class TimeCompare : public Compare
236 {
237 public:
TimeCompare(const IdbSortSpec & spec)238     TimeCompare(const IdbSortSpec& spec) : Compare(spec) {}
239 
240     int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
241 };
242 
243 // End of comparators for temporal types
244 
245 // Comparators for non-fixed size types
246 
247 class StringCompare : public Compare
248 {
249 public:
StringCompare(const IdbSortSpec & spec)250     StringCompare(const IdbSortSpec& spec) : Compare(spec), cs(NULL) {}
251 
252     int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
253 
254     CHARSET_INFO* cs;
255 };
256 
257 // End of comparators for variable sized types
258 
259 class CompareRule
260 {
261 public:
fIdbCompare(c)262     CompareRule(IdbCompare* c = NULL) : fIdbCompare(c) {}
263 
264 
265     bool less(rowgroup::Row::Pointer r1, rowgroup::Row::Pointer r2);
266 
267     void compileRules(const std::vector<IdbSortSpec>&, const rowgroup::RowGroup&);
268     void revertRules();
269 
270     std::vector<Compare*>           fCompares;
271     IdbCompare*                     fIdbCompare;
272 };
273 
274 
275 class IdbCompare
276 {
277 public:
IdbCompare()278     IdbCompare() {};
~IdbCompare()279     virtual ~IdbCompare() {};
280 
281     virtual void initialize(const rowgroup::RowGroup&);
282     void setStringTable(bool b);
283 
row1()284     rowgroup::Row& row1()
285     {
286         return fRow1;
287     }
row2()288     rowgroup::Row& row2()
289     {
290         return fRow2;
291     }
292 
rowGroup()293     rowgroup::RowGroup* rowGroup()
294     {
295         return &fRowGroup;
296     }
297 protected:
298     rowgroup::RowGroup              fRowGroup;
299     rowgroup::Row                   fRow1;
300     rowgroup::Row                   fRow2;
301 };
302 
303 
304 class OrderByRow
305 {
306 public:
OrderByRow(const rowgroup::Row & r,CompareRule & c)307     OrderByRow(const rowgroup::Row& r, CompareRule& c) : fData(r.getPointer()), fRule(&c) {}
308 
309     bool operator < (const OrderByRow& rhs) const
310     {
311         return fRule->less(fData, rhs.fData);
312     }
313 
314     rowgroup::Row::Pointer          fData;
315     CompareRule*                    fRule;
316 };
317 
318 
319 class EqualCompData : public IdbCompare
320 {
321 public:
EqualCompData(std::vector<uint64_t> & v)322     EqualCompData(std::vector<uint64_t>& v) : fIndex(v) {}
EqualCompData(std::vector<uint64_t> & v,const rowgroup::RowGroup & rg)323     EqualCompData(std::vector<uint64_t>& v, const rowgroup::RowGroup& rg) :
324         fIndex(v)
325     {
326         initialize(rg);
327     }
328 
~EqualCompData()329     ~EqualCompData() {};
330 
331     bool operator()(rowgroup::Row::Pointer, rowgroup::Row::Pointer);
332 
333     std::vector<uint64_t>           fIndex;
334 };
335 
336 
337 class OrderByData : public IdbCompare
338 {
339 public:
340     OrderByData(const std::vector<IdbSortSpec>&, const rowgroup::RowGroup&);
341     virtual ~OrderByData();
342 
operator()343     bool operator() (rowgroup::Row::Pointer p1, rowgroup::Row::Pointer p2)
344     {
345         return fRule.less(p1, p2);
346     }
rule()347     const CompareRule& rule() const
348     {
349         return fRule;
350     }
351 
352 protected:
353     CompareRule                     fRule;
354 };
355 
356 
357 // base classs for order by clause used in IDB
358 class IdbOrderBy : public IdbCompare
359 {
360 public:
361     IdbOrderBy();
362     virtual ~IdbOrderBy();
363 
364     virtual void initialize(const rowgroup::RowGroup&);
365     virtual void processRow(const rowgroup::Row&) = 0;
366     virtual uint64_t getKeyLength() const = 0;
367     virtual const std::string toString() const = 0;
368 
369     bool getData(rowgroup::RGData& data);
370 
distinct(bool b)371     void distinct(bool b)
372     {
373         fDistinct = b;
374     }
distinct()375     bool distinct() const
376     {
377         return fDistinct;
378     }
getQueue()379     SortingPQ& getQueue()
380     {
381         return fOrderByQueue;
382     }
getRule()383     CompareRule &getRule()
384     {
385         return fRule;
386     }
387 
388     SortingPQ                           fOrderByQueue;
389 protected:
390     std::vector<IdbSortSpec>            fOrderByCond;
391     rowgroup::Row                       fRow0;
392     CompareRule                         fRule;
393 
394     rowgroup::RGData        fData;
395     std::queue<rowgroup::RGData> fDataQueue;
396 
397     struct Hasher
398     {
399         IdbOrderBy* ts;
400         utils::Hasher_r h;
401         uint32_t colCount;
HasherHasher402         Hasher(IdbOrderBy* t, uint32_t c) : ts(t), colCount(c) { }
403         uint64_t operator()(const rowgroup::Row::Pointer&) const;
404     };
405     struct Eq
406     {
407         IdbOrderBy* ts;
408         uint32_t colCount;
EqEq409         Eq(IdbOrderBy* t, uint32_t c) : ts(t), colCount(c) { }
410         bool operator()(const rowgroup::Row::Pointer&, const rowgroup::Row::Pointer&) const;
411     };
412 
413     typedef std::tr1::unordered_set<rowgroup::Row::Pointer, Hasher, Eq,
414             utils::STLPoolAllocator<rowgroup::Row::Pointer> > DistinctMap_t;
415     boost::scoped_ptr<DistinctMap_t>    fDistinctMap;
416     rowgroup::Row row1, row2;  // scratch space for Hasher & Eq
417 
418     bool                                fDistinct;
419     uint64_t                            fMemSize;
420     uint64_t                            fRowsPerRG;
421     uint64_t                            fErrorCode;
422     joblist::ResourceManager*           fRm;
423     boost::shared_ptr<int64_t>			fSessionMemLimit;
424 };
425 
426 
427 }
428 
429 #endif  // IDB_ORDER_BY_H
430 
431