OmniSciDB  d2f719934e
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups 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 #include <optional>
39 
40 /*
41  * Stores the underlying buffer and the meta-data for a result set. The buffer
42  * format reflects the main requirements for result sets. Not all queries
43  * specify a GROUP BY clause, but since it's the most important and challenging
44  * case we'll focus on it. Note that the meta-data is stored separately from
45  * the buffer and it's not transferred to GPU.
46  *
47  * 1. It has to be efficient for reduction of partial GROUP BY query results
48  * from multiple devices / cores, the cardinalities can be high. Reduction
49  * currently happens on the host.
50  * 2. No conversions should be needed when buffers are transferred from GPU to
51  * host for reduction. This implies the buffer needs to be "flat", with no
52  * pointers to chase since they have no meaning in a different address space.
53  * 3. Must be size-efficient.
54  *
55  * There are several variations of the format of a result set buffer, but the
56  * most common is a sequence of entries which represent a row in the result or
57  * an empty slot. One entry looks as follows:
58  *
59  * +-+-+-+-+-+-+-+-+-+-+-+--?--+-+-+-+-+-+-+-+-+-+-+-+-+
60  * |key_0| ... |key_N-1| padding |value_0|...|value_N-1|
61  * +-+-+-+-+-+-+-+-+-+-+-+--?--+-+-+-+-+-+-+-+-+-+-+-+-+
62  *
63  * (key_0 ... key_N-1) is a multiple component key, unique within the buffer.
64  * It stores the tuple specified by the GROUP BY clause. All components have
65  * the same width, 4 or 8 bytes. For the 4-byte components, 4-byte padding is
66  * added if the number of components is odd. Not all entries in the buffer are
67  * valid; an empty entry contains EMPTY_KEY_{64, 32} for 8-byte / 4-byte width,
68  * respectively. An empty entry is ignored by subsequent operations on the
69  * result set (reduction, iteration, sort etc).
70  *
71  * value_0 through value_N-1 are 8-byte fields which hold the columns of the
72  * result, like aggregates and projected expressions. They're reduced between
73  * multiple partial results for identical (key_0 ... key_N-1) tuples.
74  *
75  * The order of entries is decided by the type of hash used, which depends on
76  * the range of the keys. For small enough ranges, a perfect hash is used. When
77  * a perfect hash isn't feasible, open addressing (using MurmurHash) with linear
78  * probing is used instead, with a 50% fill rate.
79  */
80 
81 struct ReductionCode;
82 
83 namespace Analyzer {
84 
85 class Expr;
86 class Estimator;
87 struct OrderEntry;
88 
89 } // namespace Analyzer
90 
91 class Executor;
92 
93 class ResultSet;
94 
96  public:
97  using value_type = std::vector<TargetValue>;
98  using difference_type = std::ptrdiff_t;
99  using pointer = std::vector<TargetValue>*;
100  using reference = std::vector<TargetValue>&;
101  using iterator_category = std::input_iterator_tag;
102 
103  bool operator==(const ResultSetRowIterator& other) const {
104  return result_set_ == other.result_set_ &&
106  }
107  bool operator!=(const ResultSetRowIterator& other) const { return !(*this == other); }
108 
109  inline value_type operator*() const;
110  inline ResultSetRowIterator& operator++(void);
112  ResultSetRowIterator iter(*this);
113  ++(*this);
114  return iter;
115  }
116 
117  size_t getCurrentRowBufferIndex() const {
118  if (crt_row_buff_idx_ == 0) {
119  throw std::runtime_error("current row buffer iteration index is undefined");
120  }
121  return crt_row_buff_idx_ - 1;
122  }
123 
124  private:
132 
134  bool translate_strings,
135  bool decimal_to_double)
136  : result_set_(rs)
137  , crt_row_buff_idx_(0)
138  , global_entry_idx_(0)
140  , fetched_so_far_(0)
141  , translate_strings_(translate_strings)
142  , decimal_to_double_(decimal_to_double){};
143 
145 
146  friend class ResultSet;
147 };
148 
149 class TSerializedRows;
150 class ResultSetBuilder;
151 
152 using AppendedStorage = std::vector<std::unique_ptr<ResultSetStorage>>;
153 using PermutationIdx = uint32_t;
154 using Permutation = std::vector<PermutationIdx>;
156 using Comparator = std::function<bool(const PermutationIdx, const PermutationIdx)>;
157 
158 class ResultSet {
159  public:
161  // Can use derivatives of the builder class to construct a ResultSet
162 
163  ResultSet(const std::vector<TargetInfo>& targets,
164  const ExecutorDeviceType device_type,
166  const std::shared_ptr<RowSetMemoryOwner> row_set_mem_owner,
167  const Catalog_Namespace::Catalog* catalog,
168  const unsigned block_size,
169  const unsigned grid_size);
170 
171  ResultSet(const std::vector<TargetInfo>& targets,
172  const std::vector<ColumnLazyFetchInfo>& lazy_fetch_info,
173  const std::vector<std::vector<const int8_t*>>& col_buffers,
174  const std::vector<std::vector<int64_t>>& frag_offsets,
175  const std::vector<int64_t>& consistent_frag_sizes,
176  const ExecutorDeviceType device_type,
177  const int device_id,
179  const std::shared_ptr<RowSetMemoryOwner> row_set_mem_owner,
180  const Catalog_Namespace::Catalog* catalog,
181  const unsigned block_size,
182  const unsigned grid_size);
183 
184  ResultSet(const std::shared_ptr<const Analyzer::Estimator>,
185  const ExecutorDeviceType device_type,
186  const int device_id,
187  Data_Namespace::DataMgr* data_mgr);
188 
189  ResultSet(const std::string& explanation);
190 
191  ResultSet(int64_t queue_time_ms,
192  int64_t render_time_ms,
193  const std::shared_ptr<RowSetMemoryOwner> row_set_mem_owner);
194 
195  ~ResultSet();
196 
197  std::string toString() const {
198  return typeName(this) + "(targets=" + ::toString(targets_) +
199  ", query_mem_desc=" + ::toString(query_mem_desc_) + ")";
200  }
201 
202  inline ResultSetRowIterator rowIterator(size_t from_logical_index,
203  bool translate_strings,
204  bool decimal_to_double) const {
205  ResultSetRowIterator rowIterator(this, translate_strings, decimal_to_double);
206 
207  // move to first logical position
208  ++rowIterator;
209 
210  for (size_t index = 0; index < from_logical_index; index++) {
211  ++rowIterator;
212  }
213 
214  return rowIterator;
215  }
216 
217  inline ResultSetRowIterator rowIterator(bool translate_strings,
218  bool decimal_to_double) const {
219  return rowIterator(0, translate_strings, decimal_to_double);
220  }
221 
223 
224  const ResultSetStorage* allocateStorage() const;
225 
227  int8_t*,
228  const std::vector<int64_t>&,
229  std::shared_ptr<VarlenOutputInfo> = nullptr) const;
230 
231  const ResultSetStorage* allocateStorage(const std::vector<int64_t>&) const;
232 
233  void updateStorageEntryCount(const size_t new_entry_count) {
235  query_mem_desc_.setEntryCount(new_entry_count);
236  CHECK(storage_);
237  storage_->updateEntryCount(new_entry_count);
238  }
239 
240  std::vector<TargetValue> getNextRow(const bool translate_strings,
241  const bool decimal_to_double) const;
242 
243  size_t getCurrentRowBufferIndex() const;
244 
245  std::vector<TargetValue> getRowAt(const size_t index) const;
246 
247  TargetValue getRowAt(const size_t row_idx,
248  const size_t col_idx,
249  const bool translate_strings,
250  const bool decimal_to_double = true) const;
251 
252  // Specialized random access getter for result sets with a single column to
253  // avoid the overhead of building a std::vector<TargetValue> result with only
254  // one element. Only used by RelAlgTranslator::getInIntegerSetExpr currently.
255  OneIntegerColumnRow getOneColRow(const size_t index) const;
256 
257  std::vector<TargetValue> getRowAtNoTranslations(
258  const size_t index,
259  const std::vector<bool>& targets_to_skip = {}) const;
260 
261  bool isRowAtEmpty(const size_t index) const;
262 
263  void sort(const std::list<Analyzer::OrderEntry>& order_entries,
264  size_t top_n,
265  const Executor* executor);
266 
267  void keepFirstN(const size_t n);
268 
269  void dropFirstN(const size_t n);
270 
271  void append(ResultSet& that);
272 
273  const ResultSetStorage* getStorage() const;
274 
275  size_t colCount() const;
276 
277  SQLTypeInfo getColType(const size_t col_idx) const;
278 
279  size_t rowCount(const bool force_parallel = false) const;
280 
281  void setCachedRowCount(const size_t row_count) const;
282 
283  bool isEmpty() const;
284 
293  size_t entryCount() const;
294 
295  size_t getBufferSizeBytes(const ExecutorDeviceType device_type) const;
296 
297  bool definitelyHasNoRows() const;
298 
299  const QueryMemoryDescriptor& getQueryMemDesc() const;
300 
301  const std::vector<TargetInfo>& getTargetInfos() const;
302 
303  const std::vector<int64_t>& getTargetInitVals() const;
304 
305  int8_t* getDeviceEstimatorBuffer() const;
306 
307  int8_t* getHostEstimatorBuffer() const;
308 
309  void syncEstimatorBuffer() const;
310 
311  size_t getNDVEstimator() const;
312 
314  // all in ms
316  int64_t render_time{0};
318  int64_t kernel_queue_time{0};
319  };
320 
321  void setQueueTime(const int64_t queue_time);
322  void setKernelQueueTime(const int64_t kernel_queue_time);
323  void addCompilationQueueTime(const int64_t compilation_queue_time);
324 
325  int64_t getQueueTime() const;
326  int64_t getRenderTime() const;
327 
328  void moveToBegin() const;
329 
330  bool isTruncated() const;
331 
332  bool isExplain() const;
333 
334  void setValidationOnlyRes();
335  bool isValidationOnlyRes() const;
336 
337  std::string getExplanation() const {
338  if (just_explain_) {
339  return explanation_;
340  }
341  return {};
342  }
343 
344  bool isGeoColOnGpu(const size_t col_idx) const;
345  int getDeviceId() const;
346 
347  // Called from the executor because in the new ResultSet we assume the 'padded' field
348  // in SlotSize already contains the padding, whereas in the executor it's computed.
349  // Once the buffer initialization moves to ResultSet we can remove this method.
351 
352  void fillOneEntry(const std::vector<int64_t>& entry) {
353  CHECK(storage_);
354  if (storage_->query_mem_desc_.didOutputColumnar()) {
355  storage_->fillOneEntryColWise(entry);
356  } else {
357  storage_->fillOneEntryRowWise(entry);
358  }
359  }
360 
361  void initializeStorage() const;
362 
363  void holdChunks(const std::list<std::shared_ptr<Chunk_NS::Chunk>>& chunks) {
364  chunks_ = chunks;
365  }
366  void holdChunkIterators(const std::shared_ptr<std::list<ChunkIter>> chunk_iters) {
367  chunk_iters_.push_back(chunk_iters);
368  }
369  void holdLiterals(std::vector<int8_t>& literal_buff) {
370  literal_buffers_.push_back(std::move(literal_buff));
371  }
372 
373  std::shared_ptr<RowSetMemoryOwner> getRowSetMemOwner() const {
374  return row_set_mem_owner_;
375  }
376 
377  const Permutation& getPermutationBuffer() const;
378  const bool isPermutationBufferEmpty() const { return permutation_.empty(); };
379 
380  void serialize(TSerializedRows& serialized_rows) const;
381 
382  static std::unique_ptr<ResultSet> unserialize(const TSerializedRows& serialized_rows,
383  const Executor*);
384 
385  size_t getLimit() const;
386 
390  enum class GeoReturnType {
393  WktString,
398  };
401 
402  void copyColumnIntoBuffer(const size_t column_idx,
403  int8_t* output_buffer,
404  const size_t output_buffer_size) const;
405 
407 
408  bool didOutputColumnar() const { return this->query_mem_desc_.didOutputColumnar(); }
409 
410  bool isZeroCopyColumnarConversionPossible(size_t column_idx) const;
411  const int8_t* getColumnarBuffer(size_t column_idx) const;
412 
415  }
416 
417  const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const {
418  return query_mem_desc_.getPaddedSlotWidthBytes(slot_idx);
419  }
420 
421  // returns a bitmap of all single-slot targets, as well as its count
422  std::tuple<std::vector<bool>, size_t> getSingleSlotTargetBitmap() const;
423 
424  std::tuple<std::vector<bool>, size_t> getSupportedSingleSlotTargetBitmap() const;
425 
426  std::vector<size_t> getSlotIndicesForTargetIndices() const;
427 
428  const std::vector<ColumnLazyFetchInfo>& getLazyFetchInfo() const {
429  return lazy_fetch_info_;
430  }
431 
432  void setSeparateVarlenStorageValid(const bool val) {
434  }
435 
436  const std::vector<std::string> getStringDictionaryPayloadCopy(const int dict_id) const;
437 
438  StringDictionaryProxy* getStringDictionaryProxy(int const dict_id) const;
439 
440  template <typename ENTRY_TYPE, QueryDescriptionType QUERY_TYPE, bool COLUMNAR_FORMAT>
441  ENTRY_TYPE getEntryAt(const size_t row_idx,
442  const size_t target_idx,
443  const size_t slot_idx) const;
444 
445  static double calculateQuantile(quantile::TDigest* const t_digest);
446 
447  void translateDictEncodedString(std::vector<TargetInfo> const&, size_t const start_idx);
448 
450  size_t prev_target_idx_{0};
452  size_t agg_idx_{0};
453  int8_t const* buf_ptr_{nullptr};
454  int8_t compact_sz1_;
455  };
456 
457  void eachCellInColumn(RowIterationState&, std::function<void(int8_t const*)>);
458 
459  private:
461 
462  std::vector<TargetValue> getNextRowImpl(const bool translate_strings,
463  const bool decimal_to_double) const;
464 
465  std::vector<TargetValue> getNextRowUnlocked(const bool translate_strings,
466  const bool decimal_to_double) const;
467 
468  std::vector<TargetValue> getRowAt(const size_t index,
469  const bool translate_strings,
470  const bool decimal_to_double,
471  const bool fixup_count_distinct_pointers,
472  const std::vector<bool>& targets_to_skip = {}) const;
473 
474  // NOTE: just for direct columnarization use at the moment
475  template <typename ENTRY_TYPE>
476  ENTRY_TYPE getColumnarPerfectHashEntryAt(const size_t row_idx,
477  const size_t target_idx,
478  const size_t slot_idx) const;
479 
480  template <typename ENTRY_TYPE>
481  ENTRY_TYPE getRowWisePerfectHashEntryAt(const size_t row_idx,
482  const size_t target_idx,
483  const size_t slot_idx) const;
484 
485  template <typename ENTRY_TYPE>
486  ENTRY_TYPE getRowWiseBaselineEntryAt(const size_t row_idx,
487  const size_t target_idx,
488  const size_t slot_idx) const;
489 
490  template <typename ENTRY_TYPE>
491  ENTRY_TYPE getColumnarBaselineEntryAt(const size_t row_idx,
492  const size_t target_idx,
493  const size_t slot_idx) const;
494 
495  size_t binSearchRowCount() const;
496 
497  size_t parallelRowCount() const;
498 
499  size_t advanceCursorToNextEntry() const;
500 
501  void radixSortOnGpu(const std::list<Analyzer::OrderEntry>& order_entries) const;
502 
503  void radixSortOnCpu(const std::list<Analyzer::OrderEntry>& order_entries) const;
504 
505  static bool isNull(const SQLTypeInfo& ti,
506  const InternalTargetValue& val,
507  const bool float_argument_input);
508 
510  int8_t* rowwise_target_ptr,
511  int8_t* keys_ptr,
512  const size_t entry_buff_idx,
513  const TargetInfo& target_info,
514  const size_t target_logical_idx,
515  const size_t slot_idx,
516  const bool translate_strings,
517  const bool decimal_to_double,
518  const bool fixup_count_distinct_pointers) const;
519 
520  TargetValue getTargetValueFromBufferColwise(const int8_t* col_ptr,
521  const int8_t* keys_ptr,
523  const size_t local_entry_idx,
524  const size_t global_entry_idx,
525  const TargetInfo& target_info,
526  const size_t target_logical_idx,
527  const size_t slot_idx,
528  const bool translate_strings,
529  const bool decimal_to_double) const;
530 
531  TargetValue makeTargetValue(const int8_t* ptr,
532  const int8_t compact_sz,
533  const TargetInfo& target_info,
534  const size_t target_logical_idx,
535  const bool translate_strings,
536  const bool decimal_to_double,
537  const size_t entry_buff_idx) const;
538 
539  TargetValue makeVarlenTargetValue(const int8_t* ptr1,
540  const int8_t compact_sz1,
541  const int8_t* ptr2,
542  const int8_t compact_sz2,
543  const TargetInfo& target_info,
544  const size_t target_logical_idx,
545  const bool translate_strings,
546  const size_t entry_buff_idx) const;
547 
549  int8_t* ptr1;
550  int8_t compact_sz1;
551  int8_t* ptr2;
552  int8_t compact_sz2;
553 
555  : ptr1(nullptr), compact_sz1(0), ptr2(nullptr), compact_sz2(0) {}
556  };
557  TargetValue makeGeoTargetValue(const int8_t* geo_target_ptr,
558  const size_t slot_idx,
559  const TargetInfo& target_info,
560  const size_t target_logical_idx,
561  const size_t entry_buff_idx) const;
562 
565  const size_t fixedup_entry_idx;
566  const size_t storage_idx;
567  };
568 
569  InternalTargetValue getVarlenOrderEntry(const int64_t str_ptr,
570  const size_t str_len) const;
571 
572  int64_t lazyReadInt(const int64_t ival,
573  const size_t target_logical_idx,
574  const StorageLookupResult& storage_lookup_result) const;
575 
579  std::pair<size_t, size_t> getStorageIndex(const size_t entry_idx) const;
580 
581  const std::vector<const int8_t*>& getColumnFrag(const size_t storge_idx,
582  const size_t col_logical_idx,
583  int64_t& global_idx) const;
584 
585  const VarlenOutputInfo* getVarlenOutputInfo(const size_t entry_idx) const;
586 
587  StorageLookupResult findStorage(const size_t entry_idx) const;
588 
589  struct TargetOffsets {
590  const int8_t* ptr1;
591  const size_t compact_sz1;
592  const int8_t* ptr2;
593  const size_t compact_sz2;
594  };
595 
597  RowWiseTargetAccessor(const ResultSet* result_set)
598  : result_set_(result_set)
600  , key_width_(result_set_->query_mem_desc_.getEffectiveKeyWidth())
604  }
605 
607  const int8_t* buff,
608  const size_t entry_idx,
609  const size_t target_logical_idx,
610  const StorageLookupResult& storage_lookup_result) const;
611 
613 
614  inline const int8_t* get_rowwise_ptr(const int8_t* buff,
615  const size_t entry_idx) const {
616  return buff + entry_idx * row_bytes_;
617  }
618 
619  std::vector<std::vector<TargetOffsets>> offsets_for_storage_;
620 
622 
623  // Row-wise iteration
624  const size_t row_bytes_;
625  const size_t key_width_;
627  };
628 
630  ColumnWiseTargetAccessor(const ResultSet* result_set) : result_set_(result_set) {
632  }
633 
635 
637  const int8_t* buff,
638  const size_t entry_idx,
639  const size_t target_logical_idx,
640  const StorageLookupResult& storage_lookup_result) const;
641 
642  std::vector<std::vector<TargetOffsets>> offsets_for_storage_;
643 
645  };
646 
647  using ApproxQuantileBuffers = std::vector<std::vector<double>>;
648 
649  template <typename BUFFER_ITERATOR_TYPE>
651  using BufferIteratorType = BUFFER_ITERATOR_TYPE;
652 
653  ResultSetComparator(const std::list<Analyzer::OrderEntry>& order_entries,
654  const ResultSet* result_set,
655  const PermutationView permutation,
656  const Executor* executor,
657  const bool single_threaded)
658  : order_entries_(order_entries)
659  , result_set_(result_set)
660  , permutation_(permutation)
661  , buffer_itr_(result_set)
662  , executor_(executor)
663  , single_threaded_(single_threaded)
666  }
667 
670 
671  std::vector<int64_t> materializeCountDistinctColumn(
672  const Analyzer::OrderEntry& order_entry) const;
673  ApproxQuantileBuffers::value_type materializeApproxQuantileColumn(
674  const Analyzer::OrderEntry& order_entry) const;
675 
676  bool operator()(const PermutationIdx lhs, const PermutationIdx rhs) const;
677 
678  const std::list<Analyzer::OrderEntry>& order_entries_;
682  const Executor* executor_;
683  const bool single_threaded_;
684  std::vector<std::vector<int64_t>> count_distinct_materialized_buffers_;
686  };
687 
688  Comparator createComparator(const std::list<Analyzer::OrderEntry>& order_entries,
689  const PermutationView permutation,
690  const Executor* executor,
691  const bool single_threaded) {
692  auto timer = DEBUG_TIMER(__func__);
695  order_entries, this, permutation, executor, single_threaded)](
696  const PermutationIdx lhs, const PermutationIdx rhs) {
697  return rsc(lhs, rhs);
698  };
699  } else {
701  order_entries, this, permutation, executor, single_threaded)](
702  const PermutationIdx lhs, const PermutationIdx rhs) {
703  return rsc(lhs, rhs);
704  };
705  }
706  }
707 
709  const size_t n,
710  const Comparator&);
711 
713  PermutationIdx const begin,
714  PermutationIdx const end) const;
715 
716  void parallelTop(const std::list<Analyzer::OrderEntry>& order_entries,
717  const size_t top_n,
718  const Executor* executor);
719 
720  void baselineSort(const std::list<Analyzer::OrderEntry>& order_entries,
721  const size_t top_n,
722  const Executor* executor);
723 
724  void doBaselineSort(const ExecutorDeviceType device_type,
725  const std::list<Analyzer::OrderEntry>& order_entries,
726  const size_t top_n,
727  const Executor* executor);
728 
729  bool canUseFastBaselineSort(const std::list<Analyzer::OrderEntry>& order_entries,
730  const size_t top_n);
731 
733 
734  int getGpuCount() const;
735 
736  void serializeProjection(TSerializedRows& serialized_rows) const;
737  void serializeVarlenAggColumn(int8_t* buf,
738  std::vector<std::string>& varlen_bufer) const;
739 
740  void serializeCountDistinctColumns(TSerializedRows&) const;
741 
742  void unserializeCountDistinctColumns(const TSerializedRows&);
743 
745 
746  using BufferSet = std::set<int64_t>;
747  void create_active_buffer_set(BufferSet& count_distinct_active_buffer_set) const;
748 
749  int64_t getDistinctBufferRefFromBufferRowwise(int8_t* rowwise_target_ptr,
750  const TargetInfo& target_info) const;
751 
752  const std::vector<TargetInfo> targets_;
754  const int device_id_;
756  mutable std::unique_ptr<ResultSetStorage> storage_;
758  mutable size_t crt_row_buff_idx_;
759  mutable size_t fetched_so_far_;
760  size_t drop_first_;
761  size_t keep_first_;
762  std::shared_ptr<RowSetMemoryOwner> row_set_mem_owner_;
764 
766  unsigned block_size_{0};
767  unsigned grid_size_{0};
769 
770  std::list<std::shared_ptr<Chunk_NS::Chunk>> chunks_;
771  std::vector<std::shared_ptr<std::list<ChunkIter>>> chunk_iters_;
772  // TODO(miyu): refine by using one buffer and
773  // setting offset instead of ptr in group by buffer.
774  std::vector<std::vector<int8_t>> literal_buffers_;
775  const std::vector<ColumnLazyFetchInfo> lazy_fetch_info_;
776  std::vector<std::vector<std::vector<const int8_t*>>> col_buffers_;
777  std::vector<std::vector<std::vector<int64_t>>> frag_offsets_;
778  std::vector<std::vector<int64_t>> consistent_frag_sizes_;
779 
780  const std::shared_ptr<const Analyzer::Estimator> estimator_;
782  mutable int8_t* host_estimator_buffer_{nullptr};
784 
785  // only used by serialization
786  using SerializedVarlenBufferStorage = std::vector<std::string>;
787 
788  std::vector<SerializedVarlenBufferStorage> serialized_varlen_buffer_;
790  std::string explanation_;
791  const bool just_explain_;
793  mutable std::atomic<int64_t> cached_row_count_;
794  mutable std::mutex row_iteration_mutex_;
795 
796  // only used by geo
798 
799  friend class ResultSetManager;
800  friend class ResultSetRowIterator;
801  friend class ColumnarResults;
802 };
803 
806  return {};
807  }
808 
809  if (result_set_->just_explain_) {
810  return {result_set_->explanation_};
811  }
812 
813  return result_set_->getRowAt(
815 }
816 
818  if (!result_set_->storage_ && !result_set_->just_explain_) {
819  global_entry_idx_valid_ = false;
820  } else if (result_set_->just_explain_) {
822  fetched_so_far_ = 1;
823  } else {
824  result_set_->advanceCursorToNextEntry(*this);
825  }
826  return *this;
827 }
828 
830  public:
831  ResultSet* reduce(std::vector<ResultSet*>&);
832 
833  std::shared_ptr<ResultSet> getOwnResultSet();
834 
835  void rewriteVarlenAggregates(ResultSet*);
836 
837  private:
838  std::shared_ptr<ResultSet> rs_;
839 };
840 
841 class RowSortException : public std::runtime_error {
842  public:
843  RowSortException(const std::string& cause) : std::runtime_error(cause) {}
844 };
845 
846 namespace result_set {
847 
848 bool can_use_parallel_algorithms(const ResultSet& rows);
849 
850 std::optional<size_t> first_dict_encoded_idx(std::vector<TargetInfo> const&);
851 
852 bool use_parallel_algorithms(const ResultSet& rows);
853 
854 } // namespace result_set
855 
856 #endif // QUERYENGINE_RESULTSET_H
void setSeparateVarlenStorageValid(const bool val)
Definition: ResultSet.h:432
void setGeoReturnType(const GeoReturnType val)
Definition: ResultSet.h:400
void serializeVarlenAggColumn(int8_t *buf, std::vector< std::string > &varlen_bufer) const
std::mutex row_iteration_mutex_
Definition: ResultSet.h:794
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:534
const int8_t * ptr1
Definition: ResultSet.h:590
const size_t compact_sz2
Definition: ResultSet.h:593
void holdChunks(const std::list< std::shared_ptr< Chunk_NS::Chunk >> &chunks)
Definition: ResultSet.h:363
const QueryMemoryDescriptor & getQueryMemDesc() const
Definition: ResultSet.cpp:510
std::pair< size_t, size_t > getStorageIndex(const size_t entry_idx) const
Definition: ResultSet.cpp:751
std::shared_ptr< RowSetMemoryOwner > getRowSetMemOwner() const
Definition: ResultSet.h:373
bool isValidationOnlyRes() const
Definition: ResultSet.cpp:585
Permutation permutation_
Definition: ResultSet.h:763
bool didOutputColumnar() const
Definition: ResultSet.h:408
void setValidationOnlyRes()
Definition: ResultSet.cpp:581
PermutationView initPermutationBuffer(PermutationView permutation, PermutationIdx const begin, PermutationIdx const end) const
Definition: ResultSet.cpp:683
bool for_validation_only_
Definition: ResultSet.h:792
std::ptrdiff_t difference_type
Definition: ResultSet.h:98
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:114
void setEntryCount(const size_t val)
double decimal_to_double(const SQLTypeInfo &otype, int64_t oval)
const ApproxQuantileBuffers approx_quantile_materialized_buffers_
Definition: ResultSet.h:685
AppendedStorage appended_storage_
Definition: ResultSet.h:757
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:797
ExecutorDeviceType
const BufferIteratorType buffer_itr_
Definition: ResultSet.h:681
void moveToBegin() const
Definition: ResultSet.cpp:568
Utility functions for easy access to the result set buffers.
std::shared_ptr< ResultSet > rs_
Definition: ResultSet.h:838
const Executor * executor_
Definition: ResultSet.h:682
std::vector< std::string > SerializedVarlenBufferStorage
Definition: ResultSet.h:786
void initializeStorage() const
QueryDescriptionType getQueryDescriptionType() const
Definition: ResultSet.h:413
ResultSetRowIterator(const ResultSet *rs, bool translate_strings, bool decimal_to_double)
Definition: ResultSet.h:133
const Catalog_Namespace::Catalog * catalog_
Definition: ResultSet.h:765
void unserializeCountDistinctColumns(const TSerializedRows &)
ApproxQuantileBuffers materializeApproxQuantileColumns() const
Definition: ResultSet.cpp:796
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:58
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:755
const std::vector< TargetInfo > & getTargetInfos() const
Definition: ResultSet.cpp:515
std::optional< size_t > first_dict_encoded_idx(std::vector< TargetInfo > const &)
Definition: ResultSet.cpp:1255
std::unique_ptr< ResultSetStorage > storage_
Definition: ResultSet.h:756
void setKernelQueueTime(const int64_t kernel_queue_time)
Definition: ResultSet.cpp:551
bool operator==(const ResultSetRowIterator &other) const
Definition: ResultSet.h:103
std::string getExplanation() const
Definition: ResultSet.h:337
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:408
ResultSetRowIterator(const ResultSet *rs)
Definition: ResultSet.h:144
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:761
void keepFirstN(const size_t n)
Definition: ResultSet.cpp:48
std::vector< std::shared_ptr< std::list< ChunkIter > > > chunk_iters_
Definition: ResultSet.h:771
void addCompilationQueueTime(const int64_t compilation_queue_time)
Definition: ResultSet.cpp:555
std::vector< std::vector< double >> ApproxQuantileBuffers
Definition: ResultSet.h:647
void parallelTop(const std::list< Analyzer::OrderEntry > &order_entries, const size_t top_n, const Executor *executor)
Definition: ResultSet.cpp:703
void serialize(TSerializedRows &serialized_rows) const
std::vector< SerializedVarlenBufferStorage > serialized_varlen_buffer_
Definition: ResultSet.h:788
const size_t compact_sz1
Definition: ResultSet.h:591
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:107
size_t colCount() const
Definition: ResultSet.cpp:276
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
void rewriteVarlenAggregates(ResultSet *)
size_t getLimit() const
Definition: ResultSet.cpp:1138
const bool just_explain_
Definition: ResultSet.h:791
std::vector< int64_t > materializeCountDistinctColumn(const Analyzer::OrderEntry &order_entry) const
Definition: ResultSet.cpp:809
ApproxQuantileBuffers::value_type materializeApproxQuantileColumn(const Analyzer::OrderEntry &order_entry) const
Definition: ResultSet.cpp:855
ResultSetRowIterator rowIterator(size_t from_logical_index, bool translate_strings, bool decimal_to_double) const
Definition: ResultSet.h:202
unsigned block_size_
Definition: ResultSet.h:766
bool isTruncated() const
Definition: ResultSet.cpp:573
std::atomic< int64_t > cached_row_count_
Definition: ResultSet.h:793
const bool isPermutationBufferEmpty() const
Definition: ResultSet.h:378
size_t parallelRowCount() const
Definition: ResultSet.cpp:466
const size_t key_bytes_with_padding_
Definition: ResultSet.h:626
const ResultSet * result_set_
Definition: ResultSet.h:621
std::vector< TargetValue > getRowAtNoTranslations(const size_t index, const std::vector< bool > &targets_to_skip={}) const
const ResultSet * result_set_
Definition: ResultSet.h:125
void radixSortOnCpu(const std::list< Analyzer::OrderEntry > &order_entries) const
Definition: ResultSet.cpp:1098
bool definitelyHasNoRows() const
Definition: ResultSet.cpp:506
ColumnWiseTargetAccessor(const ResultSet *result_set)
Definition: ResultSet.h:630
const std::vector< std::string > getStringDictionaryPayloadCopy(const int dict_id) const
Definition: ResultSet.cpp:1142
bool use_parallel_algorithms(const ResultSet &rows)
Definition: ResultSet.cpp:1262
bool isZeroCopyColumnarConversionPossible(size_t column_idx) const
Definition: ResultSet.cpp:1175
std::input_iterator_tag iterator_category
Definition: ResultSet.h:101
size_t global_entry_idx_
Definition: ResultSet.h:127
int8_t * getHostEstimatorBuffer() const
Definition: ResultSet.cpp:530
InternalTargetValue getVarlenOrderEntry(const int64_t str_ptr, const size_t str_len) const
const std::vector< TargetInfo > targets_
Definition: ResultSet.h:752
std::shared_ptr< RowSetMemoryOwner > row_set_mem_owner_
Definition: ResultSet.h:762
size_t drop_first_
Definition: ResultSet.h:760
const ResultSetStorage * allocateStorage() const
std::string toString() const
Definition: ResultSet.h:197
const int8_t * ptr2
Definition: ResultSet.h:592
std::list< std::shared_ptr< Chunk_NS::Chunk > > chunks_
Definition: ResultSet.h:770
QueryExecutionTimings timings_
Definition: ResultSet.h:768
const ResultSet * result_set_
Definition: ResultSet.h:679
void sort(const std::list< Analyzer::OrderEntry > &order_entries, size_t top_n, const Executor *executor)
Definition: ResultSet.cpp:605
void setQueueTime(const int64_t queue_time)
Definition: ResultSet.cpp:547
void dropFirstN(const size_t n)
Definition: ResultSet.cpp:53
std::vector< std::vector< int8_t > > literal_buffers_
Definition: ResultSet.h:774
std::vector< std::vector< TargetOffsets > > offsets_for_storage_
Definition: ResultSet.h:642
bool canUseFastBaselineSort(const std::list< Analyzer::OrderEntry > &order_entries, const size_t top_n)
unsigned grid_size_
Definition: ResultSet.h:767
const std::list< Analyzer::OrderEntry > & order_entries_
Definition: ResultSet.h:678
std::vector< TargetValue > & reference
Definition: ResultSet.h:100
std::vector< PermutationIdx > Permutation
Definition: ResultSet.h:154
ResultSet * reduce(std::vector< ResultSet * > &)
std::tuple< std::vector< bool >, size_t > getSingleSlotTargetBitmap() const
Definition: ResultSet.cpp:1188
ResultSetRowIterator & operator++(void)
Definition: ResultSet.h:817
std::shared_ptr< ResultSet > getOwnResultSet()
StorageLookupResult findStorage(const size_t entry_idx) const
Definition: ResultSet.cpp:776
Comparator createComparator(const std::list< Analyzer::OrderEntry > &order_entries, const PermutationView permutation, const Executor *executor, const bool single_threaded)
Definition: ResultSet.h:688
An AbstractBuffer is a unit of data management for a data manager.
const PermutationView permutation_
Definition: ResultSet.h:680
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
value_type operator*() const
Definition: ResultSet.h:804
const std::vector< ColumnLazyFetchInfo > lazy_fetch_info_
Definition: ResultSet.h:775
RowWiseTargetAccessor(const ResultSet *result_set)
Definition: ResultSet.h:597
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:843
std::function< bool(const PermutationIdx, const PermutationIdx)> Comparator
Definition: ResultSet.h:156
static double calculateQuantile(quantile::TDigest *const t_digest)
Definition: ResultSet.cpp:845
friend ResultSetBuilder
Definition: ResultSet.h:160
const VarlenOutputInfo * getVarlenOutputInfo(const size_t entry_idx) const
void fixupCountDistinctPointers()
void radixSortOnGpu(const std::list< Analyzer::OrderEntry > &order_entries) const
Definition: ResultSet.cpp:1059
const ResultSetStorage * getStorage() const
Definition: ResultSet.cpp:272
QueryDescriptionType getQueryDescriptionType() const
Data_Namespace::DataMgr * data_mgr_
Definition: ResultSet.h:783
Basic constructors and methods of the row set interface.
int64_t getQueueTime() const
Definition: ResultSet.cpp:559
std::vector< TargetValue > getRowAt(const size_t index) const
Executor(const ExecutorId id, Data_Namespace::DataMgr *data_mgr, 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:156
void fillOneEntry(const std::vector< int64_t > &entry)
Definition: ResultSet.h:352
void updateStorageEntryCount(const size_t new_entry_count)
Definition: ResultSet.h:233
uint32_t PermutationIdx
Definition: ResultSet.h:153
void serializeProjection(TSerializedRows &serialized_rows) const
ResultSetRowIterator operator++(int)
Definition: ResultSet.h:111
const std::shared_ptr< const Analyzer::Estimator > estimator_
Definition: ResultSet.h:780
SQLTypeInfo getColType(const size_t col_idx) const
Definition: ResultSet.cpp:280
GeoReturnType getGeoReturnType() const
Definition: ResultSet.h:399
void holdChunkIterators(const std::shared_ptr< std::list< ChunkIter >> chunk_iters)
Definition: ResultSet.h:366
std::tuple< std::vector< bool >, size_t > getSupportedSingleSlotTargetBitmap() const
Definition: ResultSet.cpp:1212
ExecutorDeviceType getDeviceType() const
Definition: ResultSet.cpp:193
StringDictionaryProxy * getStringDictionaryProxy(int const dict_id) const
Definition: ResultSet.cpp:289
const int8_t * getColumnarBuffer(size_t column_idx) const
Definition: ResultSet.cpp:1182
ResultSetComparator(const std::list< Analyzer::OrderEntry > &order_entries, const ResultSet *result_set, const PermutationView permutation, const Executor *executor, const bool single_threaded)
Definition: ResultSet.h:653
void eachCellInColumn(RowIterationState &, std::function< void(int8_t const *)>)
Definition: ResultSet.cpp:337
size_t get_row_bytes(const QueryMemoryDescriptor &query_mem_desc)
bool isExplain() const
Definition: ResultSet.cpp:577
std::vector< TargetValue > value_type
Definition: ResultSet.h:97
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:614
size_t getNDVEstimator() const
std::vector< std::vector< std::vector< const int8_t * > > > col_buffers_
Definition: ResultSet.h:776
bool isRowAtEmpty(const size_t index) const
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
Definition: ResultSet.h:417
size_t entryCount() const
static QueryMemoryDescriptor fixupQueryMemoryDescriptor(const QueryMemoryDescriptor &)
Definition: ResultSet.cpp:593
std::string typeName(const T *v)
Definition: toString.h:93
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:117
const Permutation & getPermutationBuffer() const
Definition: ResultSet.cpp:699
void append(ResultSet &that)
Definition: ResultSet.cpp:242
std::string explanation_
Definition: ResultSet.h:790
std::vector< std::vector< int64_t > > consistent_frag_sizes_
Definition: ResultSet.h:778
int8_t * host_estimator_buffer_
Definition: ResultSet.h:782
friend class ResultSet
Definition: ResultSet.h:144
void translateDictEncodedString(std::vector< TargetInfo > const &, size_t const start_idx)
Definition: ResultSet.cpp:301
const ExecutorDeviceType device_type_
Definition: ResultSet.h:753
std::vector< TargetValue > getNextRowImpl(const bool translate_strings, const bool decimal_to_double) const
static PermutationView topPermutation(PermutationView, const size_t n, const Comparator &)
Definition: ResultSet.cpp:1045
size_t getCurrentRowBufferIndex() const
Definition: ResultSet.cpp:234
void holdLiterals(std::vector< int8_t > &literal_buff)
Definition: ResultSet.h:369
bool g_enable_watchdog false
Definition: Execute.cpp:76
#define CHECK(condition)
Definition: Logger.h:211
#define DEBUG_TIMER(name)
Definition: Logger.h:358
int getGpuCount() const
size_t getBufferSizeBytes(const ExecutorDeviceType device_type) const
int8_t * getDeviceEstimatorBuffer() const
Definition: ResultSet.cpp:524
size_t fetched_so_far_
Definition: ResultSet.h:759
size_t crt_row_buff_idx_
Definition: ResultSet.h:758
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:777
bool operator()(const PermutationIdx lhs, const PermutationIdx rhs) const
Definition: ResultSet.cpp:888
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:789
boost::variant< ScalarTargetValue, ArrayTargetValue, GeoTargetValue, GeoTargetValuePtr > TargetValue
Definition: TargetValue.h:167
std::vector< TargetValue > getNextRowUnlocked(const bool translate_strings, const bool decimal_to_double) const
std::vector< TargetValue > * pointer
Definition: ResultSet.h:99
bool isEmpty() const
Definition: ResultSet.cpp:486
const std::vector< int64_t > & getTargetInitVals() const
Definition: ResultSet.cpp:519
std::vector< size_t > getSlotIndicesForTargetIndices() const
Definition: ResultSet.cpp:1231
size_t advanceCursorToNextEntry() const
void create_active_buffer_set(BufferSet &count_distinct_active_buffer_set) const
std::set< int64_t > BufferSet
Definition: ResultSet.h:746
constexpr double n
Definition: Utm.h:39
ResultSetRowIterator rowIterator(bool translate_strings, bool decimal_to_double) const
Definition: ResultSet.h:217
Definition: Analyzer.h:1573
BUFFER_ITERATOR_TYPE BufferIteratorType
Definition: ResultSet.h:651
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:126
std::vector< std::vector< int64_t > > count_distinct_materialized_buffers_
Definition: ResultSet.h:684
Data_Namespace::AbstractBuffer * device_estimator_buffer_
Definition: ResultSet.h:781
InternalTargetValue getColumnInternal(const int8_t *buff, const size_t entry_idx, const size_t target_logical_idx, const StorageLookupResult &storage_lookup_result) const
std::vector< std::vector< TargetOffsets > > offsets_for_storage_
Definition: ResultSet.h:619
bool global_entry_idx_valid_
Definition: ResultSet.h:128
bool can_use_parallel_algorithms(const ResultSet &rows)
Definition: ResultSet.cpp:1243
int64_t getRenderTime() const
Definition: ResultSet.cpp:564
void setCachedRowCount(const size_t row_count) const
Definition: ResultSet.cpp:448
bool isDirectColumnarConversionPossible() const
Definition: ResultSet.cpp:1157
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:564
std::vector< std::unique_ptr< ResultSetStorage >> AppendedStorage
Definition: ResultSet.h:152
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:453
const std::vector< ColumnLazyFetchInfo > & getLazyFetchInfo() const
Definition: ResultSet.h:428
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:589
static std::unique_ptr< ResultSet > unserialize(const TSerializedRows &serialized_rows, const Executor *)
const int device_id_
Definition: ResultSet.h:754