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