OmniSciDB  94e8789169
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ResultSet.h
Go to the documentation of this file.
1 /*
2  * Copyright 2017 MapD Technologies, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
25 #ifndef QUERYENGINE_RESULTSET_H
26 #define QUERYENGINE_RESULTSET_H
27 
28 #include "CardinalityEstimator.h"
29 #include "DataMgr/Chunk/Chunk.h"
31 #include "ResultSetStorage.h"
32 #include "Shared/quantile.h"
33 #include "TargetValue.h"
34 
35 #include <atomic>
36 #include <functional>
37 #include <list>
38 
39 /*
40  * Stores the underlying buffer and the meta-data for a result set. The buffer
41  * format reflects the main requirements for result sets. Not all queries
42  * specify a GROUP BY clause, but since it's the most important and challenging
43  * case we'll focus on it. Note that the meta-data is stored separately from
44  * the buffer and it's not transferred to GPU.
45  *
46  * 1. It has to be efficient for reduction of partial GROUP BY query results
47  * from multiple devices / cores, the cardinalities can be high. Reduction
48  * currently happens on the host.
49  * 2. No conversions should be needed when buffers are transferred from GPU to
50  * host for reduction. This implies the buffer needs to be "flat", with no
51  * pointers to chase since they have no meaning in a different address space.
52  * 3. Must be size-efficient.
53  *
54  * There are several variations of the format of a result set buffer, but the
55  * most common is a sequence of entries which represent a row in the result or
56  * an empty slot. One entry looks as follows:
57  *
58  * +-+-+-+-+-+-+-+-+-+-+-+--?--+-+-+-+-+-+-+-+-+-+-+-+-+
59  * |key_0| ... |key_N-1| padding |value_0|...|value_N-1|
60  * +-+-+-+-+-+-+-+-+-+-+-+--?--+-+-+-+-+-+-+-+-+-+-+-+-+
61  *
62  * (key_0 ... key_N-1) is a multiple component key, unique within the buffer.
63  * It stores the tuple specified by the GROUP BY clause. All components have
64  * the same width, 4 or 8 bytes. For the 4-byte components, 4-byte padding is
65  * added if the number of components is odd. Not all entries in the buffer are
66  * valid; an empty entry contains EMPTY_KEY_{64, 32} for 8-byte / 4-byte width,
67  * respectively. An empty entry is ignored by subsequent operations on the
68  * result set (reduction, iteration, sort etc).
69  *
70  * value_0 through value_N-1 are 8-byte fields which hold the columns of the
71  * result, like aggregates and projected expressions. They're reduced between
72  * multiple partial results for identical (key_0 ... key_N-1) tuples.
73  *
74  * The order of entries is decided by the type of hash used, which depends on
75  * the range of the keys. For small enough ranges, a perfect hash is used. When
76  * a perfect hash isn't feasible, open addressing (using MurmurHash) with linear
77  * probing is used instead, with a 50% fill rate.
78  */
79 
80 struct ReductionCode;
81 
82 namespace Analyzer {
83 
84 class Expr;
85 class Estimator;
86 struct OrderEntry;
87 
88 } // namespace Analyzer
89 
90 class Executor;
91 
92 class ResultSet;
93 
95  public:
96  using value_type = std::vector<TargetValue>;
97  using difference_type = std::ptrdiff_t;
98  using pointer = std::vector<TargetValue>*;
99  using reference = std::vector<TargetValue>&;
100  using iterator_category = std::input_iterator_tag;
101 
102  bool operator==(const ResultSetRowIterator& other) const {
103  return result_set_ == other.result_set_ &&
105  }
106  bool operator!=(const ResultSetRowIterator& other) const { return !(*this == other); }
107 
108  inline value_type operator*() const;
109  inline ResultSetRowIterator& operator++(void);
111  ResultSetRowIterator iter(*this);
112  ++(*this);
113  return iter;
114  }
115 
116  size_t getCurrentRowBufferIndex() const {
117  if (crt_row_buff_idx_ == 0) {
118  throw std::runtime_error("current row buffer iteration index is undefined");
119  }
120  return crt_row_buff_idx_ - 1;
121  }
122 
123  private:
131 
133  bool translate_strings,
134  bool decimal_to_double)
135  : result_set_(rs)
136  , crt_row_buff_idx_(0)
137  , global_entry_idx_(0)
139  , fetched_so_far_(0)
140  , translate_strings_(translate_strings)
141  , decimal_to_double_(decimal_to_double){};
142 
144 
145  friend class ResultSet;
146 };
147 
148 class TSerializedRows;
149 class ResultSetBuilder;
150 
151 using AppendedStorage = std::vector<std::unique_ptr<ResultSetStorage>>;
152 
153 class ResultSet {
154  public:
156  // Can use derivatives of the builder class to construct a ResultSet
157 
158  ResultSet(const std::vector<TargetInfo>& targets,
159  const ExecutorDeviceType device_type,
161  const std::shared_ptr<RowSetMemoryOwner> row_set_mem_owner,
162  const Catalog_Namespace::Catalog* catalog,
163  const unsigned block_size,
164  const unsigned grid_size);
165 
166  ResultSet(const std::vector<TargetInfo>& targets,
167  const std::vector<ColumnLazyFetchInfo>& lazy_fetch_info,
168  const std::vector<std::vector<const int8_t*>>& col_buffers,
169  const std::vector<std::vector<int64_t>>& frag_offsets,
170  const std::vector<int64_t>& consistent_frag_sizes,
171  const ExecutorDeviceType device_type,
172  const int device_id,
174  const std::shared_ptr<RowSetMemoryOwner> row_set_mem_owner,
175  const Catalog_Namespace::Catalog* catalog,
176  const unsigned block_size,
177  const unsigned grid_size);
178 
179  ResultSet(const std::shared_ptr<const Analyzer::Estimator>,
180  const ExecutorDeviceType device_type,
181  const int device_id,
182  Data_Namespace::DataMgr* data_mgr);
183 
184  ResultSet(const std::string& explanation);
185 
186  ResultSet(int64_t queue_time_ms,
187  int64_t render_time_ms,
188  const std::shared_ptr<RowSetMemoryOwner> row_set_mem_owner);
189 
190  ~ResultSet();
191 
192  inline ResultSetRowIterator rowIterator(size_t from_logical_index,
193  bool translate_strings,
194  bool decimal_to_double) const {
195  ResultSetRowIterator rowIterator(this, translate_strings, decimal_to_double);
196 
197  // move to first logical position
198  ++rowIterator;
199 
200  for (size_t index = 0; index < from_logical_index; index++) {
201  ++rowIterator;
202  }
203 
204  return rowIterator;
205  }
206 
207  inline ResultSetRowIterator rowIterator(bool translate_strings,
208  bool decimal_to_double) const {
209  return rowIterator(0, translate_strings, decimal_to_double);
210  }
211 
213 
214  const ResultSetStorage* allocateStorage() const;
215 
216  const ResultSetStorage* allocateStorage(int8_t*, const std::vector<int64_t>&) const;
217 
218  const ResultSetStorage* allocateStorage(const std::vector<int64_t>&) const;
219 
220  void updateStorageEntryCount(const size_t new_entry_count) {
222  query_mem_desc_.setEntryCount(new_entry_count);
223  CHECK(storage_);
224  storage_->updateEntryCount(new_entry_count);
225  }
226 
227  std::vector<TargetValue> getNextRow(const bool translate_strings,
228  const bool decimal_to_double) const;
229 
230  size_t getCurrentRowBufferIndex() const;
231 
232  std::vector<TargetValue> getRowAt(const size_t index) const;
233 
234  TargetValue getRowAt(const size_t row_idx,
235  const size_t col_idx,
236  const bool translate_strings,
237  const bool decimal_to_double = true) const;
238 
239  // Specialized random access getter for result sets with a single column to
240  // avoid the overhead of building a std::vector<TargetValue> result with only
241  // one element. Only used by RelAlgTranslator::getInIntegerSetExpr currently.
242  OneIntegerColumnRow getOneColRow(const size_t index) const;
243 
244  std::vector<TargetValue> getRowAtNoTranslations(
245  const size_t index,
246  const std::vector<bool>& targets_to_skip = {}) const;
247 
248  bool isRowAtEmpty(const size_t index) const;
249 
250  void sort(const std::list<Analyzer::OrderEntry>& order_entries,
251  const size_t top_n,
252  const Executor* executor);
253 
254  void keepFirstN(const size_t n);
255 
256  void dropFirstN(const size_t n);
257 
258  void append(ResultSet& that);
259 
260  const ResultSetStorage* getStorage() const;
261 
262  size_t colCount() const;
263 
264  SQLTypeInfo getColType(const size_t col_idx) const;
265 
266  size_t rowCount(const bool force_parallel = false) const;
267 
268  void setCachedRowCount(const size_t row_count) const;
269 
270  size_t entryCount() const;
271 
272  size_t getBufferSizeBytes(const ExecutorDeviceType device_type) const;
273 
274  bool definitelyHasNoRows() const;
275 
276  const QueryMemoryDescriptor& getQueryMemDesc() const;
277 
278  const std::vector<TargetInfo>& getTargetInfos() const;
279 
280  const std::vector<int64_t>& getTargetInitVals() const;
281 
282  int8_t* getDeviceEstimatorBuffer() const;
283 
284  int8_t* getHostEstimatorBuffer() const;
285 
286  void syncEstimatorBuffer() const;
287 
288  size_t getNDVEstimator() const;
289 
291  // all in ms
293  int64_t render_time{0};
295  int64_t kernel_queue_time{0};
296  };
297 
298  void setQueueTime(const int64_t queue_time);
299  void setKernelQueueTime(const int64_t kernel_queue_time);
300  void addCompilationQueueTime(const int64_t compilation_queue_time);
301 
302  int64_t getQueueTime() const;
303  int64_t getRenderTime() const;
304 
305  void moveToBegin() const;
306 
307  bool isTruncated() const;
308 
309  bool isExplain() const;
310 
311  void setValidationOnlyRes();
312  bool isValidationOnlyRes() const;
313 
314  bool isGeoColOnGpu(const size_t col_idx) const;
315  int getDeviceId() const;
316 
317  // Called from the executor because in the new ResultSet we assume the 'padded' field
318  // in SlotSize already contains the padding, whereas in the executor it's computed.
319  // Once the buffer initialization moves to ResultSet we can remove this method.
321 
322  void fillOneEntry(const std::vector<int64_t>& entry) {
323  CHECK(storage_);
324  if (storage_->query_mem_desc_.didOutputColumnar()) {
325  storage_->fillOneEntryColWise(entry);
326  } else {
327  storage_->fillOneEntryRowWise(entry);
328  }
329  }
330 
331  void initializeStorage() const;
332 
333  void holdChunks(const std::list<std::shared_ptr<Chunk_NS::Chunk>>& chunks) {
334  chunks_ = chunks;
335  }
336  void holdChunkIterators(const std::shared_ptr<std::list<ChunkIter>> chunk_iters) {
337  chunk_iters_.push_back(chunk_iters);
338  }
339  void holdLiterals(std::vector<int8_t>& literal_buff) {
340  literal_buffers_.push_back(std::move(literal_buff));
341  }
342 
343  std::shared_ptr<RowSetMemoryOwner> getRowSetMemOwner() const {
344  return row_set_mem_owner_;
345  }
346 
347  const std::vector<uint32_t>& getPermutationBuffer() const;
348  const bool isPermutationBufferEmpty() const { return permutation_.empty(); };
349 
350  void serialize(TSerializedRows& serialized_rows) const;
351 
352  static std::unique_ptr<ResultSet> unserialize(const TSerializedRows& serialized_rows,
353  const Executor*);
354 
355  size_t getLimit() const;
356 
360  enum class GeoReturnType {
363  WktString,
368  };
371 
372  void copyColumnIntoBuffer(const size_t column_idx,
373  int8_t* output_buffer,
374  const size_t output_buffer_size) const;
375 
377 
378  bool didOutputColumnar() const { return this->query_mem_desc_.didOutputColumnar(); }
379 
380  bool isZeroCopyColumnarConversionPossible(size_t column_idx) const;
381  const int8_t* getColumnarBuffer(size_t column_idx) const;
382 
385  }
386 
387  const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const {
388  return query_mem_desc_.getPaddedSlotWidthBytes(slot_idx);
389  }
390 
391  // returns a bitmap of all single-slot targets, as well as its count
392  std::tuple<std::vector<bool>, size_t> getSingleSlotTargetBitmap() const;
393 
394  std::tuple<std::vector<bool>, size_t> getSupportedSingleSlotTargetBitmap() const;
395 
396  std::vector<size_t> getSlotIndicesForTargetIndices() const;
397 
398  const std::vector<ColumnLazyFetchInfo>& getLazyFetchInfo() const {
399  return lazy_fetch_info_;
400  }
401 
402  void setSeparateVarlenStorageValid(const bool val) {
404  }
405 
406  std::shared_ptr<const std::vector<std::string>> getStringDictionaryPayloadCopy(
407  const int dict_id) const;
408 
409  template <typename ENTRY_TYPE, QueryDescriptionType QUERY_TYPE, bool COLUMNAR_FORMAT>
410  ENTRY_TYPE getEntryAt(const size_t row_idx,
411  const size_t target_idx,
412  const size_t slot_idx) const;
413 
414  static double calculateQuantile(quantile::TDigest* const t_digest, double const q);
415 
416  private:
418 
419  std::vector<TargetValue> getNextRowImpl(const bool translate_strings,
420  const bool decimal_to_double) const;
421 
422  std::vector<TargetValue> getNextRowUnlocked(const bool translate_strings,
423  const bool decimal_to_double) const;
424 
425  std::vector<TargetValue> getRowAt(const size_t index,
426  const bool translate_strings,
427  const bool decimal_to_double,
428  const bool fixup_count_distinct_pointers,
429  const std::vector<bool>& targets_to_skip = {}) const;
430 
431  // NOTE: just for direct columnarization use at the moment
432  template <typename ENTRY_TYPE>
433  ENTRY_TYPE getColumnarPerfectHashEntryAt(const size_t row_idx,
434  const size_t target_idx,
435  const size_t slot_idx) const;
436 
437  template <typename ENTRY_TYPE>
438  ENTRY_TYPE getRowWisePerfectHashEntryAt(const size_t row_idx,
439  const size_t target_idx,
440  const size_t slot_idx) const;
441 
442  template <typename ENTRY_TYPE>
443  ENTRY_TYPE getRowWiseBaselineEntryAt(const size_t row_idx,
444  const size_t target_idx,
445  const size_t slot_idx) const;
446 
447  template <typename ENTRY_TYPE>
448  ENTRY_TYPE getColumnarBaselineEntryAt(const size_t row_idx,
449  const size_t target_idx,
450  const size_t slot_idx) const;
451 
452  size_t binSearchRowCount() const;
453 
454  size_t parallelRowCount() const;
455 
456  size_t advanceCursorToNextEntry() const;
457 
458  void radixSortOnGpu(const std::list<Analyzer::OrderEntry>& order_entries) const;
459 
460  void radixSortOnCpu(const std::list<Analyzer::OrderEntry>& order_entries) const;
461 
462  static bool isNull(const SQLTypeInfo& ti,
463  const InternalTargetValue& val,
464  const bool float_argument_input);
465 
467  int8_t* rowwise_target_ptr,
468  int8_t* keys_ptr,
469  const size_t entry_buff_idx,
470  const TargetInfo& target_info,
471  const size_t target_logical_idx,
472  const size_t slot_idx,
473  const bool translate_strings,
474  const bool decimal_to_double,
475  const bool fixup_count_distinct_pointers) const;
476 
477  TargetValue getTargetValueFromBufferColwise(const int8_t* col_ptr,
478  const int8_t* keys_ptr,
480  const size_t local_entry_idx,
481  const size_t global_entry_idx,
482  const TargetInfo& target_info,
483  const size_t target_logical_idx,
484  const size_t slot_idx,
485  const bool translate_strings,
486  const bool decimal_to_double) const;
487 
488  TargetValue makeTargetValue(const int8_t* ptr,
489  const int8_t compact_sz,
490  const TargetInfo& target_info,
491  const size_t target_logical_idx,
492  const bool translate_strings,
493  const bool decimal_to_double,
494  const size_t entry_buff_idx) const;
495 
496  TargetValue makeVarlenTargetValue(const int8_t* ptr1,
497  const int8_t compact_sz1,
498  const int8_t* ptr2,
499  const int8_t compact_sz2,
500  const TargetInfo& target_info,
501  const size_t target_logical_idx,
502  const bool translate_strings,
503  const size_t entry_buff_idx) const;
504 
506  int8_t* ptr1;
507  int8_t compact_sz1;
508  int8_t* ptr2;
509  int8_t compact_sz2;
510 
512  : ptr1(nullptr), compact_sz1(0), ptr2(nullptr), compact_sz2(0) {}
513  };
514  TargetValue makeGeoTargetValue(const int8_t* geo_target_ptr,
515  const size_t slot_idx,
516  const TargetInfo& target_info,
517  const size_t target_logical_idx,
518  const size_t entry_buff_idx) const;
519 
522  const size_t fixedup_entry_idx;
523  const size_t storage_idx;
524  };
525 
527  const int8_t* buff,
528  const size_t entry_idx,
529  const size_t target_logical_idx,
530  const StorageLookupResult& storage_lookup_result) const;
531 
532  InternalTargetValue getVarlenOrderEntry(const int64_t str_ptr,
533  const size_t str_len) const;
534 
535  int64_t lazyReadInt(const int64_t ival,
536  const size_t target_logical_idx,
537  const StorageLookupResult& storage_lookup_result) const;
538 
542  std::pair<size_t, size_t> getStorageIndex(const size_t entry_idx) const;
543 
544  const std::vector<const int8_t*>& getColumnFrag(const size_t storge_idx,
545  const size_t col_logical_idx,
546  int64_t& global_idx) const;
547 
548  StorageLookupResult findStorage(const size_t entry_idx) const;
549 
550  struct TargetOffsets {
551  const int8_t* ptr1;
552  const size_t compact_sz1;
553  const int8_t* ptr2;
554  const size_t compact_sz2;
555  };
556 
558  RowWiseTargetAccessor(const ResultSet* result_set)
559  : result_set_(result_set)
561  , key_width_(result_set_->query_mem_desc_.getEffectiveKeyWidth())
565  }
566 
568  const int8_t* buff,
569  const size_t entry_idx,
570  const size_t target_logical_idx,
571  const StorageLookupResult& storage_lookup_result) const;
572 
574 
575  inline const int8_t* get_rowwise_ptr(const int8_t* buff,
576  const size_t entry_idx) const {
577  return buff + entry_idx * row_bytes_;
578  }
579 
580  std::vector<std::vector<TargetOffsets>> offsets_for_storage_;
581 
583 
584  // Row-wise iteration
585  const size_t row_bytes_;
586  const size_t key_width_;
588  };
589 
591  ColumnWiseTargetAccessor(const ResultSet* result_set) : result_set_(result_set) {
593  }
594 
596 
598  const int8_t* buff,
599  const size_t entry_idx,
600  const size_t target_logical_idx,
601  const StorageLookupResult& storage_lookup_result) const;
602 
603  std::vector<std::vector<TargetOffsets>> offsets_for_storage_;
604 
606  };
607 
608  using ApproxMedianBuffers = std::vector<std::vector<double>>;
609 
610  template <typename BUFFER_ITERATOR_TYPE>
612  using BufferIteratorType = BUFFER_ITERATOR_TYPE;
613 
614  ResultSetComparator(const std::list<Analyzer::OrderEntry>& order_entries,
615  const bool use_heap,
616  const ResultSet* result_set,
617  const Executor* executor)
618  : order_entries_(order_entries)
619  , use_heap_(use_heap)
620  , result_set_(result_set)
621  , buffer_itr_(result_set)
622  , executor_(executor)
625  }
626 
629 
630  std::vector<int64_t> materializeCountDistinctColumn(
631  const Analyzer::OrderEntry& order_entry) const;
632  ApproxMedianBuffers::value_type materializeApproxMedianColumn(
633  const Analyzer::OrderEntry& order_entry) const;
634 
635  bool operator()(const uint32_t lhs, const uint32_t rhs) const;
636 
637  // TODO(adb): make order_entries_ a pointer
638  const std::list<Analyzer::OrderEntry> order_entries_;
639  // Think use_heap = reverse_sort_order due to popping from a max-heap data structure.
640  const bool use_heap_;
643  const Executor* executor_;
644  std::vector<std::vector<int64_t>> count_distinct_materialized_buffers_;
646  };
647 
648  std::function<bool(const uint32_t, const uint32_t)> createComparator(
649  const std::list<Analyzer::OrderEntry>& order_entries,
650  const bool use_heap,
651  const Executor* executor) {
652  auto timer = DEBUG_TIMER(__func__);
655  std::make_unique<ResultSetComparator<ColumnWiseTargetAccessor>>(
656  order_entries, use_heap, this, executor);
657  return [this](const uint32_t lhs, const uint32_t rhs) -> bool {
658  return (*this->column_wise_comparator_)(lhs, rhs);
659  };
660  } else {
661  row_wise_comparator_ = std::make_unique<ResultSetComparator<RowWiseTargetAccessor>>(
662  order_entries, use_heap, this, executor);
663  return [this](const uint32_t lhs, const uint32_t rhs) -> bool {
664  return (*this->row_wise_comparator_)(lhs, rhs);
665  };
666  }
667  }
668 
669  static void topPermutation(
670  std::vector<uint32_t>& to_sort,
671  const size_t n,
672  const std::function<bool(const uint32_t, const uint32_t)> compare);
673 
674  void sortPermutation(const std::function<bool(const uint32_t, const uint32_t)> compare);
675 
676  std::vector<uint32_t> initPermutationBuffer(const size_t start, const size_t step);
677 
678  void parallelTop(const std::list<Analyzer::OrderEntry>& order_entries,
679  const size_t top_n,
680  const Executor* executor);
681 
682  void baselineSort(const std::list<Analyzer::OrderEntry>& order_entries,
683  const size_t top_n,
684  const Executor* executor);
685 
686  void doBaselineSort(const ExecutorDeviceType device_type,
687  const std::list<Analyzer::OrderEntry>& order_entries,
688  const size_t top_n,
689  const Executor* executor);
690 
691  bool canUseFastBaselineSort(const std::list<Analyzer::OrderEntry>& order_entries,
692  const size_t top_n);
693 
695 
696  int getGpuCount() const;
697 
698  void serializeProjection(TSerializedRows& serialized_rows) const;
699  void serializeVarlenAggColumn(int8_t* buf,
700  std::vector<std::string>& varlen_bufer) const;
701 
702  void serializeCountDistinctColumns(TSerializedRows&) const;
703 
704  void unserializeCountDistinctColumns(const TSerializedRows&);
705 
707 
708  using BufferSet = std::set<int64_t>;
709  void create_active_buffer_set(BufferSet& count_distinct_active_buffer_set) const;
710 
711  int64_t getDistinctBufferRefFromBufferRowwise(int8_t* rowwise_target_ptr,
712  const TargetInfo& target_info) const;
713 
714  const std::vector<TargetInfo> targets_;
716  const int device_id_;
718  mutable std::unique_ptr<ResultSetStorage> storage_;
720  mutable size_t crt_row_buff_idx_;
721  mutable size_t fetched_so_far_;
722  size_t drop_first_;
723  size_t keep_first_;
724  std::shared_ptr<RowSetMemoryOwner> row_set_mem_owner_;
725  std::vector<uint32_t> permutation_;
726 
728  unsigned block_size_{0};
729  unsigned grid_size_{0};
731 
732  std::list<std::shared_ptr<Chunk_NS::Chunk>> chunks_;
733  std::vector<std::shared_ptr<std::list<ChunkIter>>> chunk_iters_;
734  // TODO(miyu): refine by using one buffer and
735  // setting offset instead of ptr in group by buffer.
736  std::vector<std::vector<int8_t>> literal_buffers_;
737  const std::vector<ColumnLazyFetchInfo> lazy_fetch_info_;
738  std::vector<std::vector<std::vector<const int8_t*>>> col_buffers_;
739  std::vector<std::vector<std::vector<int64_t>>> frag_offsets_;
740  std::vector<std::vector<int64_t>> consistent_frag_sizes_;
741 
742  const std::shared_ptr<const Analyzer::Estimator> estimator_;
744  mutable int8_t* host_estimator_buffer_{nullptr};
746 
747  // only used by serialization
748  using SerializedVarlenBufferStorage = std::vector<std::string>;
749 
750  std::vector<SerializedVarlenBufferStorage> serialized_varlen_buffer_;
752  std::string explanation_;
753  const bool just_explain_;
755  mutable std::atomic<int64_t> cached_row_count_;
756  mutable std::mutex row_iteration_mutex_;
757 
758  // only used by geo
760 
761  // comparators used for sorting (note that the actual compare function is accessed using
762  // the createComparator method)
763  std::unique_ptr<ResultSetComparator<RowWiseTargetAccessor>> row_wise_comparator_;
764  std::unique_ptr<ResultSetComparator<ColumnWiseTargetAccessor>> column_wise_comparator_;
765 
766  friend class ResultSetManager;
767  friend class ResultSetRowIterator;
768  friend class ColumnarResults;
769 };
770 
773  return {};
774  }
775 
776  if (result_set_->just_explain_) {
777  return {result_set_->explanation_};
778  }
779 
780  return result_set_->getRowAt(
782 }
783 
785  if (!result_set_->storage_ && !result_set_->just_explain_) {
786  global_entry_idx_valid_ = false;
787  } else if (result_set_->just_explain_) {
789  fetched_so_far_ = 1;
790  } else {
791  result_set_->advanceCursorToNextEntry(*this);
792  }
793  return *this;
794 }
795 
797  public:
798  ResultSet* reduce(std::vector<ResultSet*>&);
799 
800  std::shared_ptr<ResultSet> getOwnResultSet();
801 
802  void rewriteVarlenAggregates(ResultSet*);
803 
804  private:
805  std::shared_ptr<ResultSet> rs_;
806 };
807 
808 class RowSortException : public std::runtime_error {
809  public:
810  RowSortException(const std::string& cause) : std::runtime_error(cause) {}
811 };
812 
813 namespace result_set {
814 
815 bool can_use_parallel_algorithms(const ResultSet& rows);
816 
817 bool use_parallel_algorithms(const ResultSet& rows);
818 
819 } // namespace result_set
820 
821 #endif // QUERYENGINE_RESULTSET_H
void setSeparateVarlenStorageValid(const bool val)
Definition: ResultSet.h:402
const std::list< Analyzer::OrderEntry > order_entries_
Definition: ResultSet.h:638
void setGeoReturnType(const GeoReturnType val)
Definition: ResultSet.h:370
void serializeVarlenAggColumn(int8_t *buf, std::vector< std::string > &varlen_bufer) const
std::mutex row_iteration_mutex_
Definition: ResultSet.h:756
InternalTargetValue getColumnInternal(const int8_t *buff, const size_t entry_idx, const size_t target_logical_idx, const StorageLookupResult &storage_lookup_result) const
void syncEstimatorBuffer() const
Definition: ResultSet.cpp:422
const int8_t * ptr1
Definition: ResultSet.h:551
const size_t compact_sz2
Definition: ResultSet.h:554
void holdChunks(const std::list< std::shared_ptr< Chunk_NS::Chunk >> &chunks)
Definition: ResultSet.h:333
const QueryMemoryDescriptor & getQueryMemDesc() const
Definition: ResultSet.cpp:398
std::unique_ptr< ResultSetComparator< ColumnWiseTargetAccessor > > column_wise_comparator_
Definition: ResultSet.h:764
std::pair< size_t, size_t > getStorageIndex(const size_t entry_idx) const
Definition: ResultSet.cpp:636
std::shared_ptr< RowSetMemoryOwner > getRowSetMemOwner() const
Definition: ResultSet.h:343
bool isValidationOnlyRes() const
Definition: ResultSet.cpp:475
bool didOutputColumnar() const
Definition: ResultSet.h:378
void setValidationOnlyRes()
Definition: ResultSet.cpp:471
bool for_validation_only_
Definition: ResultSet.h:754
std::ptrdiff_t difference_type
Definition: ResultSet.h:97
ENTRY_TYPE getRowWisePerfectHashEntryAt(const size_t row_idx, const size_t target_idx, const size_t slot_idx) const
class for a per-database catalog. also includes metadata for the current database and the current use...
Definition: Catalog.h:101
void setEntryCount(const size_t val)
double decimal_to_double(const SQLTypeInfo &otype, int64_t oval)
void sort(const std::list< Analyzer::OrderEntry > &order_entries, const size_t top_n, const Executor *executor)
Definition: ResultSet.cpp:495
AppendedStorage appended_storage_
Definition: ResultSet.h:719
ENTRY_TYPE getColumnarPerfectHashEntryAt(const size_t row_idx, const size_t target_idx, const size_t slot_idx) const
GeoReturnType geo_return_type_
Definition: ResultSet.h:759
ExecutorDeviceType
const BufferIteratorType buffer_itr_
Definition: ResultSet.h:642
void moveToBegin() const
Definition: ResultSet.cpp:458
Utility functions for easy access to the result set buffers.
std::shared_ptr< ResultSet > rs_
Definition: ResultSet.h:805
const Executor * executor_
Definition: ResultSet.h:643
std::vector< std::string > SerializedVarlenBufferStorage
Definition: ResultSet.h:748
void initializeStorage() const
QueryDescriptionType getQueryDescriptionType() const
Definition: ResultSet.h:383
ResultSetRowIterator(const ResultSet *rs, bool translate_strings, bool decimal_to_double)
Definition: ResultSet.h:132
const Catalog_Namespace::Catalog * catalog_
Definition: ResultSet.h:727
void unserializeCountDistinctColumns(const TSerializedRows &)
std::vector< TargetValue > getNextRow(const bool translate_strings, const bool decimal_to_double) const
static bool isNull(const SQLTypeInfo &ti, const InternalTargetValue &val, const bool float_argument_input)
ResultSet(const std::vector< TargetInfo > &targets, const ExecutorDeviceType device_type, const QueryMemoryDescriptor &query_mem_desc, const std::shared_ptr< RowSetMemoryOwner > row_set_mem_owner, const Catalog_Namespace::Catalog *catalog, const unsigned block_size, const unsigned grid_size)
Definition: ResultSet.cpp:57
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:717
const std::vector< TargetInfo > & getTargetInfos() const
Definition: ResultSet.cpp:403
std::unique_ptr< ResultSetStorage > storage_
Definition: ResultSet.h:718
void setKernelQueueTime(const int64_t kernel_queue_time)
Definition: ResultSet.cpp:441
bool operator==(const ResultSetRowIterator &other) const
Definition: ResultSet.h:102
ENTRY_TYPE getEntryAt(const size_t row_idx, const size_t target_idx, const size_t slot_idx) const
size_t rowCount(const bool force_parallel=false) const
Definition: ResultSet.cpp:301
ResultSetRowIterator(const ResultSet *rs)
Definition: ResultSet.h:143
TargetValue makeGeoTargetValue(const int8_t *geo_target_ptr, const size_t slot_idx, const TargetInfo &target_info, const size_t target_logical_idx, const size_t entry_buff_idx) const
TargetValue getTargetValueFromBufferRowwise(int8_t *rowwise_target_ptr, int8_t *keys_ptr, const size_t entry_buff_idx, const TargetInfo &target_info, const size_t target_logical_idx, const size_t slot_idx, const bool translate_strings, const bool decimal_to_double, const bool fixup_count_distinct_pointers) const
size_t keep_first_
Definition: ResultSet.h:723
void keepFirstN(const size_t n)
Definition: ResultSet.cpp:47
std::vector< std::shared_ptr< std::list< ChunkIter > > > chunk_iters_
Definition: ResultSet.h:733
void addCompilationQueueTime(const int64_t compilation_queue_time)
Definition: ResultSet.cpp:445
void parallelTop(const std::list< Analyzer::OrderEntry > &order_entries, const size_t top_n, const Executor *executor)
Definition: ResultSet.cpp:595
void serialize(TSerializedRows &serialized_rows) const
std::vector< SerializedVarlenBufferStorage > serialized_varlen_buffer_
Definition: ResultSet.h:750
const size_t compact_sz1
Definition: ResultSet.h:552
int64_t lazyReadInt(const int64_t ival, const size_t target_logical_idx, const StorageLookupResult &storage_lookup_result) const
bool operator!=(const ResultSetRowIterator &other) const
Definition: ResultSet.h:106
size_t colCount() const
Definition: ResultSet.cpp:270
OneIntegerColumnRow getOneColRow(const size_t index) const
TargetValue getTargetValueFromBufferColwise(const int8_t *col_ptr, const int8_t *keys_ptr, const QueryMemoryDescriptor &query_mem_desc, const size_t local_entry_idx, const size_t global_entry_idx, const TargetInfo &target_info, const size_t target_logical_idx, const size_t slot_idx, const bool translate_strings, const bool decimal_to_double) const
ResultSetComparator(const std::list< Analyzer::OrderEntry > &order_entries, const bool use_heap, const ResultSet *result_set, const Executor *executor)
Definition: ResultSet.h:614
void rewriteVarlenAggregates(ResultSet *)
size_t getLimit() const
Definition: ResultSet.cpp:1026
const bool just_explain_
Definition: ResultSet.h:753
std::vector< int64_t > materializeCountDistinctColumn(const Analyzer::OrderEntry &order_entry) const
Definition: ResultSet.cpp:694
ResultSetRowIterator rowIterator(size_t from_logical_index, bool translate_strings, bool decimal_to_double) const
Definition: ResultSet.h:192
unsigned block_size_
Definition: ResultSet.h:728
bool isTruncated() const
Definition: ResultSet.cpp:463
std::vector< uint32_t > permutation_
Definition: ResultSet.h:725
std::atomic< int64_t > cached_row_count_
Definition: ResultSet.h:755
const bool isPermutationBufferEmpty() const
Definition: ResultSet.h:348
size_t parallelRowCount() const
Definition: ResultSet.cpp:359
const size_t key_bytes_with_padding_
Definition: ResultSet.h:587
const ResultSet * result_set_
Definition: ResultSet.h:582
std::vector< uint32_t > initPermutationBuffer(const size_t start, const size_t step)
Definition: ResultSet.cpp:572
std::vector< TargetValue > getRowAtNoTranslations(const size_t index, const std::vector< bool > &targets_to_skip={}) const
const ResultSet * result_set_
Definition: ResultSet.h:124
void radixSortOnCpu(const std::list< Analyzer::OrderEntry > &order_entries) const
Definition: ResultSet.cpp:986
InternalTargetValue getColumnInternal(const int8_t *buff, const size_t entry_idx, const size_t target_logical_idx, const StorageLookupResult &storage_lookup_result) const
std::unique_ptr< ResultSetComparator< RowWiseTargetAccessor > > row_wise_comparator_
Definition: ResultSet.h:763
bool definitelyHasNoRows() const
Definition: ResultSet.cpp:394
ColumnWiseTargetAccessor(const ResultSet *result_set)
Definition: ResultSet.h:591
bool use_parallel_algorithms(const ResultSet &rows)
Definition: ResultSet.cpp:1135
bool isZeroCopyColumnarConversionPossible(size_t column_idx) const
Definition: ResultSet.cpp:1063
std::input_iterator_tag iterator_category
Definition: ResultSet.h:100
size_t global_entry_idx_
Definition: ResultSet.h:126
int8_t * getHostEstimatorBuffer() const
Definition: ResultSet.cpp:418
InternalTargetValue getVarlenOrderEntry(const int64_t str_ptr, const size_t str_len) const
const std::vector< TargetInfo > targets_
Definition: ResultSet.h:714
std::shared_ptr< RowSetMemoryOwner > row_set_mem_owner_
Definition: ResultSet.h:724
size_t drop_first_
Definition: ResultSet.h:722
const ResultSetStorage * allocateStorage() const
std::shared_ptr< const std::vector< std::string > > getStringDictionaryPayloadCopy(const int dict_id) const
Definition: ResultSet.cpp:1030
const int8_t * ptr2
Definition: ResultSet.h:553
std::list< std::shared_ptr< Chunk_NS::Chunk > > chunks_
Definition: ResultSet.h:732
ApproxMedianBuffers materializeApproxMedianColumns() const
Definition: ResultSet.cpp:681
QueryExecutionTimings timings_
Definition: ResultSet.h:730
const ResultSet * result_set_
Definition: ResultSet.h:641
void setQueueTime(const int64_t queue_time)
Definition: ResultSet.cpp:437
void dropFirstN(const size_t n)
Definition: ResultSet.cpp:52
std::vector< std::vector< int8_t > > literal_buffers_
Definition: ResultSet.h:736
std::vector< std::vector< TargetOffsets > > offsets_for_storage_
Definition: ResultSet.h:603
bool canUseFastBaselineSort(const std::list< Analyzer::OrderEntry > &order_entries, const size_t top_n)
unsigned grid_size_
Definition: ResultSet.h:729
std::vector< TargetValue > & reference
Definition: ResultSet.h:99
ResultSet * reduce(std::vector< ResultSet * > &)
std::tuple< std::vector< bool >, size_t > getSingleSlotTargetBitmap() const
Definition: ResultSet.cpp:1076
ResultSetRowIterator & operator++(void)
Definition: ResultSet.h:784
std::shared_ptr< ResultSet > getOwnResultSet()
StorageLookupResult findStorage(const size_t entry_idx) const
Definition: ResultSet.cpp:661
An AbstractBuffer is a unit of data management for a data manager.
static void topPermutation(std::vector< uint32_t > &to_sort, const size_t n, const std::function< bool(const uint32_t, const uint32_t)> compare)
Definition: ResultSet.cpp:927
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
value_type operator*() const
Definition: ResultSet.h:771
const std::vector< ColumnLazyFetchInfo > lazy_fetch_info_
Definition: ResultSet.h:737
RowWiseTargetAccessor(const ResultSet *result_set)
Definition: ResultSet.h:558
std::vector< std::vector< double >> ApproxMedianBuffers
Definition: ResultSet.h:608
void copyColumnIntoBuffer(const size_t column_idx, int8_t *output_buffer, const size_t output_buffer_size) const
RowSortException(const std::string &cause)
Definition: ResultSet.h:810
friend ResultSetBuilder
Definition: ResultSet.h:155
void fixupCountDistinctPointers()
void radixSortOnGpu(const std::list< Analyzer::OrderEntry > &order_entries) const
Definition: ResultSet.cpp:949
const ResultSetStorage * getStorage() const
Definition: ResultSet.cpp:266
QueryDescriptionType getQueryDescriptionType() const
Data_Namespace::DataMgr * data_mgr_
Definition: ResultSet.h:745
static double calculateQuantile(quantile::TDigest *const t_digest, double const q)
Definition: ResultSet.cpp:738
Basic constructors and methods of the row set interface.
int64_t getQueueTime() const
Definition: ResultSet.cpp:449
std::vector< TargetValue > getRowAt(const size_t index) const
void fillOneEntry(const std::vector< int64_t > &entry)
Definition: ResultSet.h:322
void updateStorageEntryCount(const size_t new_entry_count)
Definition: ResultSet.h:220
void serializeProjection(TSerializedRows &serialized_rows) const
ResultSetRowIterator operator++(int)
Definition: ResultSet.h:110
const std::shared_ptr< const Analyzer::Estimator > estimator_
Definition: ResultSet.h:742
SQLTypeInfo getColType(const size_t col_idx) const
Definition: ResultSet.cpp:274
GeoReturnType getGeoReturnType() const
Definition: ResultSet.h:369
ApproxMedianBuffers::value_type materializeApproxMedianColumn(const Analyzer::OrderEntry &order_entry) const
Definition: ResultSet.cpp:748
void holdChunkIterators(const std::shared_ptr< std::list< ChunkIter >> chunk_iters)
Definition: ResultSet.h:336
std::tuple< std::vector< bool >, size_t > getSupportedSingleSlotTargetBitmap() const
Definition: ResultSet.cpp:1100
ExecutorDeviceType getDeviceType() const
Definition: ResultSet.cpp:192
const int8_t * getColumnarBuffer(size_t column_idx) const
Definition: ResultSet.cpp:1070
size_t get_row_bytes(const QueryMemoryDescriptor &query_mem_desc)
bool isExplain() const
Definition: ResultSet.cpp:467
std::vector< TargetValue > value_type
Definition: ResultSet.h:96
void sortPermutation(const std::function< bool(const uint32_t, const uint32_t)> compare)
Definition: ResultSet.cpp:943
bool isGeoColOnGpu(const size_t col_idx) const
const int8_t * get_rowwise_ptr(const int8_t *buff, const size_t entry_idx) const
Definition: ResultSet.h:575
size_t getNDVEstimator() const
std::vector< std::vector< std::vector< const int8_t * > > > col_buffers_
Definition: ResultSet.h:738
bool isRowAtEmpty(const size_t index) const
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
Definition: ResultSet.h:387
size_t entryCount() const
static QueryMemoryDescriptor fixupQueryMemoryDescriptor(const QueryMemoryDescriptor &)
Definition: ResultSet.cpp:483
TargetValue makeTargetValue(const int8_t *ptr, const int8_t compact_sz, const TargetInfo &target_info, const size_t target_logical_idx, const bool translate_strings, const bool decimal_to_double, const size_t entry_buff_idx) const
void baselineSort(const std::list< Analyzer::OrderEntry > &order_entries, const size_t top_n, const Executor *executor)
size_t getCurrentRowBufferIndex() const
Definition: ResultSet.h:116
void append(ResultSet &that)
Definition: ResultSet.cpp:236
std::string explanation_
Definition: ResultSet.h:752
std::vector< std::vector< int64_t > > consistent_frag_sizes_
Definition: ResultSet.h:740
bool operator()(const uint32_t lhs, const uint32_t rhs) const
Definition: ResultSet.cpp:778
int8_t * host_estimator_buffer_
Definition: ResultSet.h:744
friend class ResultSet
Definition: ResultSet.h:143
const ExecutorDeviceType device_type_
Definition: ResultSet.h:715
std::vector< TargetValue > getNextRowImpl(const bool translate_strings, const bool decimal_to_double) const
size_t getCurrentRowBufferIndex() const
Definition: ResultSet.cpp:228
void holdLiterals(std::vector< int8_t > &literal_buff)
Definition: ResultSet.h:339
bool g_enable_watchdog false
Definition: Execute.cpp:76
#define CHECK(condition)
Definition: Logger.h:197
#define DEBUG_TIMER(name)
Definition: Logger.h:313
int getGpuCount() const
size_t getBufferSizeBytes(const ExecutorDeviceType device_type) const
int8_t * getDeviceEstimatorBuffer() const
Definition: ResultSet.cpp:412
size_t fetched_so_far_
Definition: ResultSet.h:721
size_t crt_row_buff_idx_
Definition: ResultSet.h:720
Estimators to be used when precise cardinality isn&#39;t useful.
QueryDescriptionType
Definition: Types.h:26
int64_t getDistinctBufferRefFromBufferRowwise(int8_t *rowwise_target_ptr, const TargetInfo &target_info) const
std::vector< std::vector< std::vector< int64_t > > > frag_offsets_
Definition: ResultSet.h:739
void doBaselineSort(const ExecutorDeviceType device_type, const std::list< Analyzer::OrderEntry > &order_entries, const size_t top_n, const Executor *executor)
bool separate_varlen_storage_valid_
Definition: ResultSet.h:751
boost::variant< ScalarTargetValue, ArrayTargetValue, GeoTargetValue, GeoTargetValuePtr > TargetValue
Definition: TargetValue.h:167
Executor(const ExecutorId id, const size_t block_size_x, const size_t grid_size_x, const size_t max_gpu_slab_size, const std::string &debug_dir, const std::string &debug_file)
Definition: Execute.cpp:138
std::vector< TargetValue > getNextRowUnlocked(const bool translate_strings, const bool decimal_to_double) const
std::vector< TargetValue > * pointer
Definition: ResultSet.h:98
const std::vector< int64_t > & getTargetInitVals() const
Definition: ResultSet.cpp:407
std::vector< size_t > getSlotIndicesForTargetIndices() const
Definition: ResultSet.cpp:1119
const std::vector< uint32_t > & getPermutationBuffer() const
Definition: ResultSet.cpp:591
size_t advanceCursorToNextEntry() const
void create_active_buffer_set(BufferSet &count_distinct_active_buffer_set) const
std::set< int64_t > BufferSet
Definition: ResultSet.h:708
ResultSetRowIterator rowIterator(bool translate_strings, bool decimal_to_double) const
Definition: ResultSet.h:207
Definition: Analyzer.h:1413
BUFFER_ITERATOR_TYPE BufferIteratorType
Definition: ResultSet.h:612
ENTRY_TYPE getColumnarBaselineEntryAt(const size_t row_idx, const size_t target_idx, const size_t slot_idx) const
Data_Namespace::DataMgr * getDataManager() const
size_t crt_row_buff_idx_
Definition: ResultSet.h:125
std::vector< std::vector< int64_t > > count_distinct_materialized_buffers_
Definition: ResultSet.h:644
Data_Namespace::AbstractBuffer * device_estimator_buffer_
Definition: ResultSet.h:743
InternalTargetValue getColumnInternal(const int8_t *buff, const size_t entry_idx, const size_t target_logical_idx, const StorageLookupResult &storage_lookup_result) const
const ApproxMedianBuffers approx_median_materialized_buffers_
Definition: ResultSet.h:645
std::vector< std::vector< TargetOffsets > > offsets_for_storage_
Definition: ResultSet.h:580
bool global_entry_idx_valid_
Definition: ResultSet.h:127
bool can_use_parallel_algorithms(const ResultSet &rows)
Definition: ResultSet.cpp:1131
int64_t getRenderTime() const
Definition: ResultSet.cpp:454
void setCachedRowCount(const size_t row_count) const
Definition: ResultSet.cpp:341
bool isDirectColumnarConversionPossible() const
Definition: ResultSet.cpp:1045
size_t get_key_bytes_rowwise(const QueryMemoryDescriptor &query_mem_desc)
FORCE_INLINE HOST DEVICE T align_to_int64(T addr)
TargetValue makeVarlenTargetValue(const int8_t *ptr1, const int8_t compact_sz1, const int8_t *ptr2, const int8_t compact_sz2, const TargetInfo &target_info, const size_t target_logical_idx, const bool translate_strings, const size_t entry_buff_idx) const
void serializeCountDistinctColumns(TSerializedRows &) const
const ResultSetStorage * storage_ptr
Definition: ResultSet.h:521
std::vector< std::unique_ptr< ResultSetStorage >> AppendedStorage
Definition: ResultSet.h:151
const std::vector< const int8_t * > & getColumnFrag(const size_t storge_idx, const size_t col_logical_idx, int64_t &global_idx) const
size_t binSearchRowCount() const
Definition: ResultSet.cpp:346
const std::vector< ColumnLazyFetchInfo > & getLazyFetchInfo() const
Definition: ResultSet.h:398
std::function< bool(const uint32_t, const uint32_t)> createComparator(const std::list< Analyzer::OrderEntry > &order_entries, const bool use_heap, const Executor *executor)
Definition: ResultSet.h:648
ENTRY_TYPE getRowWiseBaselineEntryAt(const size_t row_idx, const size_t target_idx, const size_t slot_idx) const
int getDeviceId() const
Definition: ResultSet.cpp:479
static std::unique_ptr< ResultSet > unserialize(const TSerializedRows &serialized_rows, const Executor *)
const int device_id_
Definition: ResultSet.h:716