OmniSciDB  8a228a1076
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 "TargetValue.h"
32 
33 #include <atomic>
34 #include <functional>
35 #include <list>
36 
37 /*
38  * Stores the underlying buffer and the meta-data for a result set. The buffer
39  * format reflects the main requirements for result sets. Not all queries
40  * specify a GROUP BY clause, but since it's the most important and challenging
41  * case we'll focus on it. Note that the meta-data is stored separately from
42  * the buffer and it's not transferred to GPU.
43  *
44  * 1. It has to be efficient for reduction of partial GROUP BY query results
45  * from multiple devices / cores, the cardinalities can be high. Reduction
46  * currently happens on the host.
47  * 2. No conversions should be needed when buffers are transferred from GPU to
48  * host for reduction. This implies the buffer needs to be "flat", with no
49  * pointers to chase since they have no meaning in a different address space.
50  * 3. Must be size-efficient.
51  *
52  * There are several variations of the format of a result set buffer, but the
53  * most common is a sequence of entries which represent a row in the result or
54  * an empty slot. One entry looks as follows:
55  *
56  * +-+-+-+-+-+-+-+-+-+-+-+--?--+-+-+-+-+-+-+-+-+-+-+-+-+
57  * |key_0| ... |key_N-1| padding |value_0|...|value_N-1|
58  * +-+-+-+-+-+-+-+-+-+-+-+--?--+-+-+-+-+-+-+-+-+-+-+-+-+
59  *
60  * (key_0 ... key_N-1) is a multiple component key, unique within the buffer.
61  * It stores the tuple specified by the GROUP BY clause. All components have
62  * the same width, 4 or 8 bytes. For the 4-byte components, 4-byte padding is
63  * added if the number of components is odd. Not all entries in the buffer are
64  * valid; an empty entry contains EMPTY_KEY_{64, 32} for 8-byte / 4-byte width,
65  * respectively. An empty entry is ignored by subsequent operations on the
66  * result set (reduction, iteration, sort etc).
67  *
68  * value_0 through value_N-1 are 8-byte fields which hold the columns of the
69  * result, like aggregates and projected expressions. They're reduced between
70  * multiple partial results for identical (key_0 ... key_N-1) tuples.
71  *
72  * The order of entries is decided by the type of hash used, which depends on
73  * the range of the keys. For small enough ranges, a perfect hash is used. When
74  * a perfect hash isn't feasible, open addressing (using MurmurHash) with linear
75  * probing is used instead, with a 50% fill rate.
76  */
77 
78 struct ReductionCode;
79 
81  public:
82  ResultSetStorage(const std::vector<TargetInfo>& targets,
83  const QueryMemoryDescriptor& query_mem_desc,
84  int8_t* buff,
85  const bool buff_is_provided);
86 
87  void reduce(const ResultSetStorage& that,
88  const std::vector<std::string>& serialized_varlen_buffer,
89  const ReductionCode& reduction_code) const;
90 
92  const std::vector<std::string>& serialized_varlen_buffer) const;
93 
94  int8_t* getUnderlyingBuffer() const;
95 
96  size_t getEntryCount() const { return query_mem_desc_.getEntryCount(); }
97 
98  template <class KeyType>
99  void moveEntriesToBuffer(int8_t* new_buff, const size_t new_entry_count) const;
100 
101  template <class KeyType>
102  void moveOneEntryToBuffer(const size_t entry_index,
103  int64_t* new_buff_i64,
104  const size_t new_entry_count,
105  const size_t key_count,
106  const size_t row_qw_count,
107  const int64_t* src_buff,
108  const size_t key_byte_width) const;
109 
110  void updateEntryCount(const size_t new_entry_count) {
111  query_mem_desc_.setEntryCount(new_entry_count);
112  }
113 
114  // Reduces results for a single row when using interleaved bin layouts
115  static bool reduceSingleRow(const int8_t* row_ptr,
116  const int8_t warp_count,
117  const bool is_columnar,
118  const bool replace_bitmap_ptr_with_bitmap_sz,
119  std::vector<int64_t>& agg_vals,
120  const QueryMemoryDescriptor& query_mem_desc,
121  const std::vector<TargetInfo>& targets,
122  const std::vector<int64_t>& agg_init_vals);
123 
124  private:
126  int8_t* this_buff,
127  const int8_t* that_buff,
128  const ResultSetStorage& that,
129  const size_t start_index,
130  const size_t end_index,
131  const std::vector<std::string>& serialized_varlen_buffer) const;
132 
133  void copyKeyColWise(const size_t entry_idx,
134  int8_t* this_buff,
135  const int8_t* that_buff) const;
136 
137  bool isEmptyEntry(const size_t entry_idx, const int8_t* buff) const;
138  bool isEmptyEntry(const size_t entry_idx) const;
139  bool isEmptyEntryColumnar(const size_t entry_idx, const int8_t* buff) const;
140 
141  void reduceOneEntryBaseline(int8_t* this_buff,
142  const int8_t* that_buff,
143  const size_t i,
144  const size_t that_entry_count,
145  const ResultSetStorage& that) const;
146 
147  void reduceOneEntrySlotsBaseline(int64_t* this_entry_slots,
148  const int64_t* that_buff,
149  const size_t that_entry_idx,
150  const size_t that_entry_count,
151  const ResultSetStorage& that) const;
152 
153  void initializeBaselineValueSlots(int64_t* this_entry_slots) const;
154 
155  void reduceOneSlotBaseline(int64_t* this_buff,
156  const size_t this_slot,
157  const int64_t* that_buff,
158  const size_t that_entry_count,
159  const size_t that_slot,
160  const TargetInfo& target_info,
161  const size_t target_logical_idx,
162  const size_t target_slot_idx,
163  const size_t init_agg_val_idx,
164  const ResultSetStorage& that) const;
165 
167  void reduceOneSlotSingleValue(int8_t* this_ptr1,
168  const TargetInfo& target_info,
169  const size_t target_slot_idx,
170  const size_t init_agg_val_idx,
171  const int8_t* that_ptr1) const;
172 
174  void reduceOneSlot(int8_t* this_ptr1,
175  int8_t* this_ptr2,
176  const int8_t* that_ptr1,
177  const int8_t* that_ptr2,
178  const TargetInfo& target_info,
179  const size_t target_logical_idx,
180  const size_t target_slot_idx,
181  const size_t init_agg_val_idx,
182  const ResultSetStorage& that,
183  const size_t first_slot_idx_for_target,
184  const std::vector<std::string>& serialized_varlen_buffer) const;
185 
186  void reduceOneCountDistinctSlot(int8_t* this_ptr1,
187  const int8_t* that_ptr1,
188  const size_t target_logical_idx,
189  const ResultSetStorage& that) const;
190 
191  void fillOneEntryRowWise(const std::vector<int64_t>& entry);
192 
193  void fillOneEntryColWise(const std::vector<int64_t>& entry);
194 
195  void initializeRowWise() const;
196 
197  void initializeColWise() const;
198 
199  // TODO(alex): remove the following two methods, see comment about
200  // count_distinct_sets_mapping_.
201  void addCountDistinctSetPointerMapping(const int64_t remote_ptr, const int64_t ptr);
202 
203  int64_t mappedPtr(const int64_t) const;
204 
205  size_t binSearchRowCount() const;
206 
207  const std::vector<TargetInfo> targets_;
209  int8_t* buff_;
210  const bool buff_is_provided_;
211  std::vector<int64_t> target_init_vals_;
212  // Provisional field used for multi-node until we improve the count distinct
213  // and flatten the main group by buffer and the distinct buffers in a single,
214  // contiguous buffer which we'll be able to serialize as a no-op. Used to
215  // re-route the pointers in the result set received over the wire to this
216  // machine address-space. Not efficient at all, just a placeholder!
217  std::unordered_map<int64_t, int64_t> count_distinct_sets_mapping_;
218 
219  friend class ResultSet;
220  friend class ResultSetManager;
221 };
222 
223 namespace Analyzer {
224 
225 class Expr;
226 class Estimator;
227 struct OrderEntry;
228 
229 } // namespace Analyzer
230 
231 class Executor;
232 
234  const bool is_lazily_fetched;
235  const int local_col_id;
237 };
238 
240  const int64_t value;
241  const bool valid;
242 };
243 
244 class ResultSet;
245 
247  public:
248  using value_type = std::vector<TargetValue>;
249  using difference_type = std::ptrdiff_t;
250  using pointer = std::vector<TargetValue>*;
251  using reference = std::vector<TargetValue>&;
252  using iterator_category = std::input_iterator_tag;
253 
254  bool operator==(const ResultSetRowIterator& other) const {
255  return result_set_ == other.result_set_ &&
256  crt_row_buff_idx_ == other.crt_row_buff_idx_;
257  }
258  bool operator!=(const ResultSetRowIterator& other) const { return !(*this == other); }
259 
260  inline value_type operator*() const;
261  inline ResultSetRowIterator& operator++(void);
263  ResultSetRowIterator iter(*this);
264  ++(*this);
265  return iter;
266  }
267 
268  size_t getCurrentRowBufferIndex() const {
269  if (crt_row_buff_idx_ == 0) {
270  throw std::runtime_error("current row buffer iteration index is undefined");
271  }
272  return crt_row_buff_idx_ - 1;
273  }
274 
275  private:
283 
285  bool translate_strings,
286  bool decimal_to_double)
287  : result_set_(rs)
288  , crt_row_buff_idx_(0)
289  , global_entry_idx_(0)
290  , global_entry_idx_valid_(false)
291  , fetched_so_far_(0)
292  , translate_strings_(translate_strings)
293  , decimal_to_double_(decimal_to_double){};
294 
295  ResultSetRowIterator(const ResultSet* rs) : ResultSetRowIterator(rs, false, false){};
296 
297  friend class ResultSet;
298 };
299 
300 class TSerializedRows;
301 
302 using AppendedStorage = std::vector<std::unique_ptr<ResultSetStorage>>;
303 
304 class ResultSet {
305  public:
306  ResultSet(const std::vector<TargetInfo>& targets,
307  const ExecutorDeviceType device_type,
308  const QueryMemoryDescriptor& query_mem_desc,
309  const std::shared_ptr<RowSetMemoryOwner> row_set_mem_owner,
310  const Executor* executor);
311 
312  ResultSet(const std::vector<TargetInfo>& targets,
313  const std::vector<ColumnLazyFetchInfo>& lazy_fetch_info,
314  const std::vector<std::vector<const int8_t*>>& col_buffers,
315  const std::vector<std::vector<int64_t>>& frag_offsets,
316  const std::vector<int64_t>& consistent_frag_sizes,
317  const ExecutorDeviceType device_type,
318  const int device_id,
319  const QueryMemoryDescriptor& query_mem_desc,
320  const std::shared_ptr<RowSetMemoryOwner> row_set_mem_owner,
321  const Executor* executor);
322 
323  ResultSet(const std::shared_ptr<const Analyzer::Estimator>,
324  const ExecutorDeviceType device_type,
325  const int device_id,
326  Data_Namespace::DataMgr* data_mgr);
327 
328  ResultSet(const std::string& explanation);
329 
330  ResultSet(int64_t queue_time_ms,
331  int64_t render_time_ms,
332  const std::shared_ptr<RowSetMemoryOwner> row_set_mem_owner);
333 
334  ~ResultSet();
335 
336  inline ResultSetRowIterator rowIterator(size_t from_logical_index,
337  bool translate_strings,
338  bool decimal_to_double) const {
339  ResultSetRowIterator rowIterator(this, translate_strings, decimal_to_double);
340 
341  // move to first logical position
342  ++rowIterator;
343 
344  for (size_t index = 0; index < from_logical_index; index++) {
345  ++rowIterator;
346  }
347 
348  return rowIterator;
349  }
350 
351  inline ResultSetRowIterator rowIterator(bool translate_strings,
352  bool decimal_to_double) const {
353  return rowIterator(0, translate_strings, decimal_to_double);
354  }
355 
356  ExecutorDeviceType getDeviceType() const;
357 
358  const ResultSetStorage* allocateStorage() const;
359 
360  const ResultSetStorage* allocateStorage(int8_t*, const std::vector<int64_t>&) const;
361 
362  const ResultSetStorage* allocateStorage(const std::vector<int64_t>&) const;
363 
364  void updateStorageEntryCount(const size_t new_entry_count) {
366  query_mem_desc_.setEntryCount(new_entry_count);
367  CHECK(storage_);
368  storage_->updateEntryCount(new_entry_count);
369  }
370 
371  std::vector<TargetValue> getNextRow(const bool translate_strings,
372  const bool decimal_to_double) const;
373 
374  size_t getCurrentRowBufferIndex() const;
375 
376  std::vector<TargetValue> getRowAt(const size_t index) const;
377 
378  TargetValue getRowAt(const size_t row_idx,
379  const size_t col_idx,
380  const bool translate_strings,
381  const bool decimal_to_double = true) const;
382 
383  // Specialized random access getter for result sets with a single column to
384  // avoid the overhead of building a std::vector<TargetValue> result with only
385  // one element. Only used by RelAlgTranslator::getInIntegerSetExpr currently.
386  OneIntegerColumnRow getOneColRow(const size_t index) const;
387 
388  std::vector<TargetValue> getRowAtNoTranslations(
389  const size_t index,
390  const std::vector<bool>& targets_to_skip = {}) const;
391 
392  bool isRowAtEmpty(const size_t index) const;
393 
394  void sort(const std::list<Analyzer::OrderEntry>& order_entries, const size_t top_n);
395 
396  void keepFirstN(const size_t n);
397 
398  void dropFirstN(const size_t n);
399 
400  void append(ResultSet& that);
401 
402  const ResultSetStorage* getStorage() const;
403 
404  size_t colCount() const;
405 
406  SQLTypeInfo getColType(const size_t col_idx) const;
407 
408  size_t rowCount(const bool force_parallel = false) const;
409 
410  void setCachedRowCount(const size_t row_count) const;
411 
412  size_t entryCount() const;
413 
414  size_t getBufferSizeBytes(const ExecutorDeviceType device_type) const;
415 
416  bool definitelyHasNoRows() const;
417 
418  const QueryMemoryDescriptor& getQueryMemDesc() const;
419 
420  const std::vector<TargetInfo>& getTargetInfos() const;
421 
422  const std::vector<int64_t>& getTargetInitVals() const;
423 
424  int8_t* getDeviceEstimatorBuffer() const;
425 
426  int8_t* getHostEstimatorBuffer() const;
427 
428  void syncEstimatorBuffer() const;
429 
430  size_t getNDVEstimator() const;
431 
433  // all in ms
434  int64_t executor_queue_time{0};
435  int64_t render_time{0};
436  int64_t compilation_queue_time{0};
437  int64_t kernel_queue_time{0};
438  };
439 
440  void setQueueTime(const int64_t queue_time);
441  void setKernelQueueTime(const int64_t kernel_queue_time);
442  void addCompilationQueueTime(const int64_t compilation_queue_time);
443 
444  int64_t getQueueTime() const;
445  int64_t getRenderTime() const;
446 
447  void moveToBegin() const;
448 
449  bool isTruncated() const;
450 
451  bool isExplain() const;
452 
453  bool isGeoColOnGpu(const size_t col_idx) const;
454  int getDeviceId() const;
455 
456  // Called from the executor because in the new ResultSet we assume the 'padded' field
457  // in SlotSize already contains the padding, whereas in the executor it's computed.
458  // Once the buffer initialization moves to ResultSet we can remove this method.
459  static QueryMemoryDescriptor fixupQueryMemoryDescriptor(const QueryMemoryDescriptor&);
460 
461  void fillOneEntry(const std::vector<int64_t>& entry) {
462  CHECK(storage_);
463  if (storage_->query_mem_desc_.didOutputColumnar()) {
464  storage_->fillOneEntryColWise(entry);
465  } else {
466  storage_->fillOneEntryRowWise(entry);
467  }
468  }
469 
470  void initializeStorage() const;
471 
472  void holdChunks(const std::list<std::shared_ptr<Chunk_NS::Chunk>>& chunks) {
473  chunks_ = chunks;
474  }
475  void holdChunkIterators(const std::shared_ptr<std::list<ChunkIter>> chunk_iters) {
476  chunk_iters_.push_back(chunk_iters);
477  }
478  void holdLiterals(std::vector<int8_t>& literal_buff) {
479  literal_buffers_.push_back(std::move(literal_buff));
480  }
481 
482  std::shared_ptr<RowSetMemoryOwner> getRowSetMemOwner() const {
483  return row_set_mem_owner_;
484  }
485 
486  const std::vector<uint32_t>& getPermutationBuffer() const;
487  const bool isPermutationBufferEmpty() const { return permutation_.empty(); };
488 
489  void serialize(TSerializedRows& serialized_rows) const;
490 
491  static std::unique_ptr<ResultSet> unserialize(const TSerializedRows& serialized_rows,
492  const Executor*);
493 
494  size_t getLimit() const;
495 
499  enum class GeoReturnType {
502  WktString,
505  GeoTargetValueGpuPtr
507  };
508  GeoReturnType getGeoReturnType() const { return geo_return_type_; }
509  void setGeoReturnType(const GeoReturnType val) { geo_return_type_ = val; }
510 
511  void copyColumnIntoBuffer(const size_t column_idx,
512  int8_t* output_buffer,
513  const size_t output_buffer_size) const;
514 
515  bool isDirectColumnarConversionPossible() const;
516 
517  bool didOutputColumnar() const { return this->query_mem_desc_.didOutputColumnar(); }
518 
519  bool isZeroCopyColumnarConversionPossible(size_t column_idx) const;
520  const int8_t* getColumnarBuffer(size_t column_idx) const;
521 
524  }
525 
526  const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const {
527  return query_mem_desc_.getPaddedSlotWidthBytes(slot_idx);
528  }
529 
530  // returns a bitmap of all single-slot targets, as well as its count
531  std::tuple<std::vector<bool>, size_t> getSingleSlotTargetBitmap() const;
532 
533  std::tuple<std::vector<bool>, size_t> getSupportedSingleSlotTargetBitmap() const;
534 
535  std::vector<size_t> getSlotIndicesForTargetIndices() const;
536 
537  const std::vector<ColumnLazyFetchInfo>& getLazyFetchInfo() const {
538  return lazy_fetch_info_;
539  }
540 
541  void setSeparateVarlenStorageValid(const bool val) {
542  separate_varlen_storage_valid_ = val;
543  }
544 
545  std::shared_ptr<const std::vector<std::string>> getStringDictionaryPayloadCopy(
546  const int dict_id) const;
547 
548  template <typename ENTRY_TYPE, QueryDescriptionType QUERY_TYPE, bool COLUMNAR_FORMAT>
549  ENTRY_TYPE getEntryAt(const size_t row_idx,
550  const size_t target_idx,
551  const size_t slot_idx) const;
552 
553  private:
554  void advanceCursorToNextEntry(ResultSetRowIterator& iter) const;
555 
556  std::vector<TargetValue> getNextRowImpl(const bool translate_strings,
557  const bool decimal_to_double) const;
558 
559  std::vector<TargetValue> getNextRowUnlocked(const bool translate_strings,
560  const bool decimal_to_double) const;
561 
562  std::vector<TargetValue> getRowAt(const size_t index,
563  const bool translate_strings,
564  const bool decimal_to_double,
565  const bool fixup_count_distinct_pointers,
566  const std::vector<bool>& targets_to_skip = {}) const;
567 
568  // NOTE: just for direct columnarization use at the moment
569  template <typename ENTRY_TYPE>
570  ENTRY_TYPE getColumnarPerfectHashEntryAt(const size_t row_idx,
571  const size_t target_idx,
572  const size_t slot_idx) const;
573 
574  template <typename ENTRY_TYPE>
575  ENTRY_TYPE getRowWisePerfectHashEntryAt(const size_t row_idx,
576  const size_t target_idx,
577  const size_t slot_idx) const;
578 
579  template <typename ENTRY_TYPE>
580  ENTRY_TYPE getRowWiseBaselineEntryAt(const size_t row_idx,
581  const size_t target_idx,
582  const size_t slot_idx) const;
583 
584  template <typename ENTRY_TYPE>
585  ENTRY_TYPE getColumnarBaselineEntryAt(const size_t row_idx,
586  const size_t target_idx,
587  const size_t slot_idx) const;
588 
589  size_t binSearchRowCount() const;
590 
591  size_t parallelRowCount() const;
592 
593  size_t advanceCursorToNextEntry() const;
594 
595  void radixSortOnGpu(const std::list<Analyzer::OrderEntry>& order_entries) const;
596 
597  void radixSortOnCpu(const std::list<Analyzer::OrderEntry>& order_entries) const;
598 
599  static bool isNull(const SQLTypeInfo& ti,
600  const InternalTargetValue& val,
601  const bool float_argument_input);
602 
603  TargetValue getTargetValueFromBufferRowwise(
604  int8_t* rowwise_target_ptr,
605  int8_t* keys_ptr,
606  const size_t entry_buff_idx,
607  const TargetInfo& target_info,
608  const size_t target_logical_idx,
609  const size_t slot_idx,
610  const bool translate_strings,
611  const bool decimal_to_double,
612  const bool fixup_count_distinct_pointers) const;
613 
614  TargetValue getTargetValueFromBufferColwise(const int8_t* col_ptr,
615  const int8_t* keys_ptr,
616  const QueryMemoryDescriptor& query_mem_desc,
617  const size_t local_entry_idx,
618  const size_t global_entry_idx,
619  const TargetInfo& target_info,
620  const size_t target_logical_idx,
621  const size_t slot_idx,
622  const bool translate_strings,
623  const bool decimal_to_double) const;
624 
625  TargetValue makeTargetValue(const int8_t* ptr,
626  const int8_t compact_sz,
627  const TargetInfo& target_info,
628  const size_t target_logical_idx,
629  const bool translate_strings,
630  const bool decimal_to_double,
631  const size_t entry_buff_idx) const;
632 
633  TargetValue makeVarlenTargetValue(const int8_t* ptr1,
634  const int8_t compact_sz1,
635  const int8_t* ptr2,
636  const int8_t compact_sz2,
637  const TargetInfo& target_info,
638  const size_t target_logical_idx,
639  const bool translate_strings,
640  const size_t entry_buff_idx) const;
641 
643  int8_t* ptr1;
644  int8_t compact_sz1;
645  int8_t* ptr2;
646  int8_t compact_sz2;
647 
649  : ptr1(nullptr), compact_sz1(0), ptr2(nullptr), compact_sz2(0) {}
650  };
651  TargetValue makeGeoTargetValue(const int8_t* geo_target_ptr,
652  const size_t slot_idx,
653  const TargetInfo& target_info,
654  const size_t target_logical_idx,
655  const size_t entry_buff_idx) const;
656 
659  const size_t fixedup_entry_idx;
660  const size_t storage_idx;
661  };
662 
663  InternalTargetValue getColumnInternal(
664  const int8_t* buff,
665  const size_t entry_idx,
666  const size_t target_logical_idx,
667  const StorageLookupResult& storage_lookup_result) const;
668 
669  InternalTargetValue getVarlenOrderEntry(const int64_t str_ptr,
670  const size_t str_len) const;
671 
672  int64_t lazyReadInt(const int64_t ival,
673  const size_t target_logical_idx,
674  const StorageLookupResult& storage_lookup_result) const;
675 
679  std::pair<size_t, size_t> getStorageIndex(const size_t entry_idx) const;
680 
681  const std::vector<const int8_t*>& getColumnFrag(const size_t storge_idx,
682  const size_t col_logical_idx,
683  int64_t& global_idx) const;
684 
685  StorageLookupResult findStorage(const size_t entry_idx) const;
686 
687  struct TargetOffsets {
688  const int8_t* ptr1;
689  const size_t compact_sz1;
690  const int8_t* ptr2;
691  const size_t compact_sz2;
692  };
693 
695  RowWiseTargetAccessor(const ResultSet* result_set)
696  : result_set_(result_set)
697  , row_bytes_(get_row_bytes(result_set->query_mem_desc_))
698  , key_width_(result_set_->query_mem_desc_.getEffectiveKeyWidth())
699  , key_bytes_with_padding_(
701  initializeOffsetsForStorage();
702  }
703 
704  InternalTargetValue getColumnInternal(
705  const int8_t* buff,
706  const size_t entry_idx,
707  const size_t target_logical_idx,
708  const StorageLookupResult& storage_lookup_result) const;
709 
710  void initializeOffsetsForStorage();
711 
712  inline const int8_t* get_rowwise_ptr(const int8_t* buff,
713  const size_t entry_idx) const {
714  return buff + entry_idx * row_bytes_;
715  }
716 
717  std::vector<std::vector<TargetOffsets>> offsets_for_storage_;
718 
720 
721  // Row-wise iteration
722  const size_t row_bytes_;
723  const size_t key_width_;
725  };
726 
728  ColumnWiseTargetAccessor(const ResultSet* result_set) : result_set_(result_set) {
729  initializeOffsetsForStorage();
730  }
731 
732  void initializeOffsetsForStorage();
733 
734  InternalTargetValue getColumnInternal(
735  const int8_t* buff,
736  const size_t entry_idx,
737  const size_t target_logical_idx,
738  const StorageLookupResult& storage_lookup_result) const;
739 
740  std::vector<std::vector<TargetOffsets>> offsets_for_storage_;
741 
743  };
744 
745  template <typename BUFFER_ITERATOR_TYPE>
747  using BufferIteratorType = BUFFER_ITERATOR_TYPE;
748 
749  ResultSetComparator(const std::list<Analyzer::OrderEntry>& order_entries,
750  const bool use_heap,
751  const ResultSet* result_set)
752  : order_entries_(order_entries)
753  , use_heap_(use_heap)
754  , result_set_(result_set)
755  , buffer_itr_(result_set) {
756  materializeCountDistinctColumns();
757  }
758 
759  void materializeCountDistinctColumns();
760 
761  std::vector<int64_t> materializeCountDistinctColumn(
762  const Analyzer::OrderEntry& order_entry) const;
763 
764  bool operator()(const uint32_t lhs, const uint32_t rhs) const;
765 
766  // TODO(adb): make order_entries_ a pointer
767  const std::list<Analyzer::OrderEntry> order_entries_;
768  const bool use_heap_;
771  std::vector<std::vector<int64_t>> count_distinct_materialized_buffers_;
772  };
773 
774  std::function<bool(const uint32_t, const uint32_t)> createComparator(
775  const std::list<Analyzer::OrderEntry>& order_entries,
776  const bool use_heap) {
777  auto timer = DEBUG_TIMER(__func__);
779  column_wise_comparator_ =
780  std::make_unique<ResultSetComparator<ColumnWiseTargetAccessor>>(
781  order_entries, use_heap, this);
782  return [this](const uint32_t lhs, const uint32_t rhs) -> bool {
783  return (*this->column_wise_comparator_)(lhs, rhs);
784  };
785  } else {
786  row_wise_comparator_ = std::make_unique<ResultSetComparator<RowWiseTargetAccessor>>(
787  order_entries, use_heap, this);
788  return [this](const uint32_t lhs, const uint32_t rhs) -> bool {
789  return (*this->row_wise_comparator_)(lhs, rhs);
790  };
791  }
792  }
793 
794  static void topPermutation(
795  std::vector<uint32_t>& to_sort,
796  const size_t n,
797  const std::function<bool(const uint32_t, const uint32_t)> compare);
798 
799  void sortPermutation(const std::function<bool(const uint32_t, const uint32_t)> compare);
800 
801  std::vector<uint32_t> initPermutationBuffer(const size_t start, const size_t step);
802 
803  void parallelTop(const std::list<Analyzer::OrderEntry>& order_entries,
804  const size_t top_n);
805 
806  void baselineSort(const std::list<Analyzer::OrderEntry>& order_entries,
807  const size_t top_n);
808 
809  void doBaselineSort(const ExecutorDeviceType device_type,
810  const std::list<Analyzer::OrderEntry>& order_entries,
811  const size_t top_n);
812 
813  bool canUseFastBaselineSort(const std::list<Analyzer::OrderEntry>& order_entries,
814  const size_t top_n);
815 
816  Data_Namespace::DataMgr* getDataManager() const;
817 
818  int getGpuCount() const;
819 
820  void serializeProjection(TSerializedRows& serialized_rows) const;
821  void serializeVarlenAggColumn(int8_t* buf,
822  std::vector<std::string>& varlen_bufer) const;
823 
824  void serializeCountDistinctColumns(TSerializedRows&) const;
825 
826  void unserializeCountDistinctColumns(const TSerializedRows&);
827 
828  void fixupCountDistinctPointers();
829 
830  using BufferSet = std::set<int64_t>;
831  void create_active_buffer_set(BufferSet& count_distinct_active_buffer_set) const;
832 
833  int64_t getDistinctBufferRefFromBufferRowwise(int8_t* rowwise_target_ptr,
834  const TargetInfo& target_info) const;
835 
836  const std::vector<TargetInfo> targets_;
838  const int device_id_;
840  mutable std::unique_ptr<ResultSetStorage> storage_;
842  mutable size_t crt_row_buff_idx_;
843  mutable size_t fetched_so_far_;
844  size_t drop_first_;
845  size_t keep_first_;
846  std::shared_ptr<RowSetMemoryOwner> row_set_mem_owner_;
847  std::vector<uint32_t> permutation_;
848 
850  const Executor* executor_; // TODO(alex): remove
851 
852  std::list<std::shared_ptr<Chunk_NS::Chunk>> chunks_;
853  std::vector<std::shared_ptr<std::list<ChunkIter>>> chunk_iters_;
854  // TODO(miyu): refine by using one buffer and
855  // setting offset instead of ptr in group by buffer.
856  std::vector<std::vector<int8_t>> literal_buffers_;
857  const std::vector<ColumnLazyFetchInfo> lazy_fetch_info_;
858  std::vector<std::vector<std::vector<const int8_t*>>> col_buffers_;
859  std::vector<std::vector<std::vector<int64_t>>> frag_offsets_;
860  std::vector<std::vector<int64_t>> consistent_frag_sizes_;
861 
862  const std::shared_ptr<const Analyzer::Estimator> estimator_;
863  Data_Namespace::AbstractBuffer* device_estimator_buffer_{nullptr};
864  mutable int8_t* host_estimator_buffer_{nullptr};
866 
867  // only used by serialization
868  using SerializedVarlenBufferStorage = std::vector<std::string>;
869 
870  std::vector<SerializedVarlenBufferStorage> serialized_varlen_buffer_;
872  std::string explanation_;
873  const bool just_explain_;
874  mutable std::atomic<ssize_t> cached_row_count_;
875  mutable std::mutex row_iteration_mutex_;
876 
877  // only used by geo
879 
880  // comparators used for sorting (note that the actual compare function is accessed using
881  // the createComparator method)
882  std::unique_ptr<ResultSetComparator<RowWiseTargetAccessor>> row_wise_comparator_;
883  std::unique_ptr<ResultSetComparator<ColumnWiseTargetAccessor>> column_wise_comparator_;
884 
885  friend class ResultSetManager;
886  friend class ResultSetRowIterator;
887  friend class ColumnarResults;
888 };
889 
891  if (!global_entry_idx_valid_) {
892  return {};
893  }
894 
895  if (result_set_->just_explain_) {
896  return {result_set_->explanation_};
897  }
898 
899  return result_set_->getRowAt(
900  global_entry_idx_, translate_strings_, decimal_to_double_, false);
901 }
902 
904  if (!result_set_->storage_ && !result_set_->just_explain_) {
905  global_entry_idx_valid_ = false;
906  } else if (result_set_->just_explain_) {
907  global_entry_idx_valid_ = 0 == fetched_so_far_;
908  fetched_so_far_ = 1;
909  } else {
910  result_set_->advanceCursorToNextEntry(*this);
911  }
912  return *this;
913 }
914 
916  public:
917  ResultSet* reduce(std::vector<ResultSet*>&);
918 
919  std::shared_ptr<ResultSet> getOwnResultSet();
920 
921  void rewriteVarlenAggregates(ResultSet*);
922 
923  private:
924  std::shared_ptr<ResultSet> rs_;
925 };
926 
927 class RowSortException : public std::runtime_error {
928  public:
929  RowSortException(const std::string& cause) : std::runtime_error(cause) {}
930 };
931 
932 int64_t lazy_decode(const ColumnLazyFetchInfo& col_lazy_fetch,
933  const int8_t* byte_stream,
934  const int64_t pos);
935 
936 void fill_empty_key(void* key_ptr, const size_t key_count, const size_t key_width);
937 
938 bool can_use_parallel_algorithms(const ResultSet& rows);
939 
940 bool use_parallel_algorithms(const ResultSet& rows);
941 
942 int8_t get_width_for_slot(const size_t target_slot_idx,
943  const bool float_argument_input,
944  const QueryMemoryDescriptor& query_mem_desc);
945 
946 size_t get_byteoff_of_slot(const size_t slot_idx,
947  const QueryMemoryDescriptor& query_mem_desc);
948 
949 using GroupValueInfo = std::pair<int64_t*, bool>;
950 
951 GroupValueInfo get_group_value_reduction(int64_t* groups_buffer,
952  const uint32_t groups_buffer_entry_count,
953  const int64_t* key,
954  const uint32_t key_count,
955  const size_t key_width,
956  const QueryMemoryDescriptor& query_mem_desc,
957  const int64_t* that_buff_i64,
958  const size_t that_entry_idx,
959  const size_t that_entry_count,
960  const uint32_t row_size_quad);
961 
962 std::vector<int64_t> initialize_target_values_for_storage(
963  const std::vector<TargetInfo>& targets);
964 #endif // QUERYENGINE_RESULTSET_H
std::pair< int64_t *, bool > GroupValueInfo
Definition: ResultSet.h:949
void setSeparateVarlenStorageValid(const bool val)
Definition: ResultSet.h:541
const std::list< Analyzer::OrderEntry > order_entries_
Definition: ResultSet.h:767
void setGeoReturnType(const GeoReturnType val)
Definition: ResultSet.h:509
const SQLTypeInfo type
Definition: ResultSet.h:236
void copyKeyColWise(const size_t entry_idx, int8_t *this_buff, const int8_t *that_buff) const
std::mutex row_iteration_mutex_
Definition: ResultSet.h:875
const int8_t * ptr1
Definition: ResultSet.h:688
const size_t compact_sz2
Definition: ResultSet.h:691
int64_t lazy_decode(const ColumnLazyFetchInfo &col_lazy_fetch, const int8_t *byte_stream, const int64_t pos)
void holdChunks(const std::list< std::shared_ptr< Chunk_NS::Chunk >> &chunks)
Definition: ResultSet.h:472
GeoReturnType getGeoReturnType() const
Definition: ResultSet.h:508
ResultSetRowIterator rowIterator(bool translate_strings, bool decimal_to_double) const
Definition: ResultSet.h:351
std::unique_ptr< ResultSetComparator< ColumnWiseTargetAccessor > > column_wise_comparator_
Definition: ResultSet.h:883
std::ptrdiff_t difference_type
Definition: ResultSet.h:249
const std::vector< TargetInfo > targets_
Definition: ResultSet.h:207
double decimal_to_double(const SQLTypeInfo &otype, int64_t oval)
void setEntryCount(const size_t val)
std::vector< int64_t > target_init_vals_
Definition: ResultSet.h:211
AppendedStorage appended_storage_
Definition: ResultSet.h:841
void reduceOneEntryBaseline(int8_t *this_buff, const int8_t *that_buff, const size_t i, const size_t that_entry_count, const ResultSetStorage &that) const
GeoReturnType geo_return_type_
Definition: ResultSet.h:878
ExecutorDeviceType
const BufferIteratorType buffer_itr_
Definition: ResultSet.h:770
void fill_empty_key(void *key_ptr, const size_t key_count, const size_t key_width)
bool operator==(const ResultSetRowIterator &other) const
Definition: ResultSet.h:254
boost::optional< boost::variant< GeoPointTargetValue, GeoLineStringTargetValue, GeoPolyTargetValue, GeoMultiPolyTargetValue > > GeoTargetValue
Definition: TargetValue.h:161
void moveEntriesToBuffer(int8_t *new_buff, const size_t new_entry_count) const
Utility functions for easy access to the result set buffers.
void reduce(const ResultSetStorage &that, const std::vector< std::string > &serialized_varlen_buffer, const ReductionCode &reduction_code) const
std::shared_ptr< ResultSet > rs_
Definition: ResultSet.h:924
std::vector< std::string > SerializedVarlenBufferStorage
Definition: ResultSet.h:868
ResultSetRowIterator(const ResultSet *rs, bool translate_strings, bool decimal_to_double)
Definition: ResultSet.h:284
const Executor * executor_
Definition: ResultSet.h:850
size_t get_byteoff_of_slot(const size_t slot_idx, const QueryMemoryDescriptor &query_mem_desc)
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:839
void addCountDistinctSetPointerMapping(const int64_t remote_ptr, const int64_t ptr)
Definition: ResultSet.cpp:975
ResultSetStorage(const std::vector< TargetInfo > &targets, const QueryMemoryDescriptor &query_mem_desc, int8_t *buff, const bool buff_is_provided)
Definition: ResultSet.cpp:80
std::unique_ptr< ResultSetStorage > storage_
Definition: ResultSet.h:840
ResultSetRowIterator(const ResultSet *rs)
Definition: ResultSet.h:295
size_t keep_first_
Definition: ResultSet.h:845
std::vector< std::shared_ptr< std::list< ChunkIter > > > chunk_iters_
Definition: ResultSet.h:853
const int64_t const uint32_t groups_buffer_entry_count
std::vector< SerializedVarlenBufferStorage > serialized_varlen_buffer_
Definition: ResultSet.h:870
const size_t compact_sz1
Definition: ResultSet.h:689
size_t getEntryCount() const
Definition: ResultSet.h:96
void initializeColWise() const
int8_t get_width_for_slot(const size_t target_slot_idx, const bool float_argument_input, const QueryMemoryDescriptor &query_mem_desc)
bool use_parallel_algorithms(const ResultSet &rows)
Definition: ResultSet.cpp:1007
friend class ResultSet
Definition: ResultSet.h:219
const bool just_explain_
Definition: ResultSet.h:873
std::vector< uint32_t > permutation_
Definition: ResultSet.h:847
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
std::unordered_map< int64_t, int64_t > count_distinct_sets_mapping_
Definition: ResultSet.h:217
const int local_col_id
Definition: ResultSet.h:235
const size_t key_bytes_with_padding_
Definition: ResultSet.h:724
void moveOneEntryToBuffer(const size_t entry_index, int64_t *new_buff_i64, const size_t new_entry_count, const size_t key_count, const size_t row_qw_count, const int64_t *src_buff, const size_t key_byte_width) const
bool isEmptyEntry(const size_t entry_idx, const int8_t *buff) const
const ResultSet * result_set_
Definition: ResultSet.h:719
const ResultSet * result_set_
Definition: ResultSet.h:276
std::unique_ptr< ResultSetComparator< RowWiseTargetAccessor > > row_wise_comparator_
Definition: ResultSet.h:882
QueryDescriptionType getQueryDescriptionType() const
Definition: ResultSet.h:522
ColumnWiseTargetAccessor(const ResultSet *result_set)
Definition: ResultSet.h:728
std::input_iterator_tag iterator_category
Definition: ResultSet.h:252
size_t global_entry_idx_
Definition: ResultSet.h:278
const bool buff_is_provided_
Definition: ResultSet.h:210
const std::vector< TargetInfo > targets_
Definition: ResultSet.h:836
std::shared_ptr< RowSetMemoryOwner > row_set_mem_owner_
Definition: ResultSet.h:846
bool operator!=(const ResultSetRowIterator &other) const
Definition: ResultSet.h:258
ResultSetRowIterator rowIterator(size_t from_logical_index, bool translate_strings, bool decimal_to_double) const
Definition: ResultSet.h:336
size_t drop_first_
Definition: ResultSet.h:844
void reduceOneEntrySlotsBaseline(int64_t *this_entry_slots, const int64_t *that_buff, const size_t that_entry_idx, const size_t that_entry_count, const ResultSetStorage &that) const
ALWAYS_INLINE void reduceOneSlotSingleValue(int8_t *this_ptr1, const TargetInfo &target_info, const size_t target_slot_idx, const size_t init_agg_val_idx, const int8_t *that_ptr1) const
const int8_t * ptr2
Definition: ResultSet.h:690
std::list< std::shared_ptr< Chunk_NS::Chunk > > chunks_
Definition: ResultSet.h:852
QueryExecutionTimings timings_
Definition: ResultSet.h:849
const ResultSet * result_set_
Definition: ResultSet.h:769
std::vector< std::vector< int8_t > > literal_buffers_
Definition: ResultSet.h:856
std::vector< std::vector< TargetOffsets > > offsets_for_storage_
Definition: ResultSet.h:740
GroupValueInfo get_group_value_reduction(int64_t *groups_buffer, const uint32_t groups_buffer_entry_count, const int64_t *key, const uint32_t key_count, const size_t key_width, const QueryMemoryDescriptor &query_mem_desc, const int64_t *that_buff_i64, const size_t that_entry_idx, const size_t that_entry_count, const uint32_t row_size_quad)
void updateEntryCount(const size_t new_entry_count)
Definition: ResultSet.h:110
void rewriteAggregateBufferOffsets(const std::vector< std::string > &serialized_varlen_buffer) const
void reduceOneSlotBaseline(int64_t *this_buff, const size_t this_slot, const int64_t *that_buff, const size_t that_entry_count, const size_t that_slot, const TargetInfo &target_info, const size_t target_logical_idx, const size_t target_slot_idx, const size_t init_agg_val_idx, const ResultSetStorage &that) const
std::vector< TargetValue > & reference
Definition: ResultSet.h:251
ResultSetRowIterator & operator++(void)
Definition: ResultSet.h:903
void fillOneEntryColWise(const std::vector< int64_t > &entry)
An AbstractBuffer is a unit of data management for a data manager.
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
Definition: ResultSet.h:526
size_t append(FILE *f, const size_t size, int8_t *buf)
Appends the specified number of bytes to the end of the file f from buf.
Definition: File.cpp:140
std::atomic< ssize_t > cached_row_count_
Definition: ResultSet.h:874
const std::vector< ColumnLazyFetchInfo > lazy_fetch_info_
Definition: ResultSet.h:857
RowWiseTargetAccessor(const ResultSet *result_set)
Definition: ResultSet.h:695
RowSortException(const std::string &cause)
Definition: ResultSet.h:929
Data_Namespace::DataMgr * data_mgr_
Definition: ResultSet.h:865
size_t binSearchRowCount() const
void fillOneEntry(const std::vector< int64_t > &entry)
Definition: ResultSet.h:461
const int64_t value
Definition: ResultSet.h:240
void initializeBaselineValueSlots(int64_t *this_entry_slots) const
void reduceOneCountDistinctSlot(int8_t *this_ptr1, const int8_t *that_ptr1, const size_t target_logical_idx, const ResultSetStorage &that) const
void updateStorageEntryCount(const size_t new_entry_count)
Definition: ResultSet.h:364
ResultSetRowIterator operator++(int)
Definition: ResultSet.h:262
const std::shared_ptr< const Analyzer::Estimator > estimator_
Definition: ResultSet.h:862
ALWAYS_INLINE void reduceOneSlot(int8_t *this_ptr1, int8_t *this_ptr2, const int8_t *that_ptr1, const int8_t *that_ptr2, const TargetInfo &target_info, const size_t target_logical_idx, const size_t target_slot_idx, const size_t init_agg_val_idx, const ResultSetStorage &that, const size_t first_slot_idx_for_target, const std::vector< std::string > &serialized_varlen_buffer) const
size_t getCurrentRowBufferIndex() const
Definition: ResultSet.h:268
void holdChunkIterators(const std::shared_ptr< std::list< ChunkIter >> chunk_iters)
Definition: ResultSet.h:475
size_t get_row_bytes(const QueryMemoryDescriptor &query_mem_desc)
int8_t * buff_
Definition: ResultSet.h:209
ResultSetComparator(const std::list< Analyzer::OrderEntry > &order_entries, const bool use_heap, const ResultSet *result_set)
Definition: ResultSet.h:749
std::vector< TargetValue > value_type
Definition: ResultSet.h:248
std::vector< std::vector< std::vector< const int8_t * > > > col_buffers_
Definition: ResultSet.h:858
const bool valid
Definition: ResultSet.h:241
std::string explanation_
Definition: ResultSet.h:872
const bool is_lazily_fetched
Definition: ResultSet.h:234
std::vector< std::vector< int64_t > > consistent_frag_sizes_
Definition: ResultSet.h:860
bool can_use_parallel_algorithms(const ResultSet &rows)
Definition: ResultSet.cpp:1003
const ExecutorDeviceType device_type_
Definition: ResultSet.h:837
void holdLiterals(std::vector< int8_t > &literal_buff)
Definition: ResultSet.h:478
const int8_t * get_rowwise_ptr(const int8_t *buff, const size_t entry_idx) const
Definition: ResultSet.h:712
#define CHECK(condition)
Definition: Logger.h:197
#define DEBUG_TIMER(name)
Definition: Logger.h:313
std::vector< std::unique_ptr< ResultSetStorage > > AppendedStorage
Definition: ResultSet.h:302
size_t fetched_so_far_
Definition: ResultSet.h:843
bool isEmptyEntryColumnar(const size_t entry_idx, const int8_t *buff) const
size_t crt_row_buff_idx_
Definition: ResultSet.h:842
Estimators to be used when precise cardinality isn&#39;t useful.
QueryDescriptionType
Definition: Types.h:26
void fillOneEntryRowWise(const std::vector< int64_t > &entry)
std::vector< std::vector< std::vector< int64_t > > > frag_offsets_
Definition: ResultSet.h:859
void reduceEntriesNoCollisionsColWise(int8_t *this_buff, const int8_t *that_buff, const ResultSetStorage &that, const size_t start_index, const size_t end_index, const std::vector< std::string > &serialized_varlen_buffer) const
bool separate_varlen_storage_valid_
Definition: ResultSet.h:871
const std::vector< ColumnLazyFetchInfo > & getLazyFetchInfo() const
Definition: ResultSet.h:537
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:129
void initializeRowWise() const
std::vector< TargetValue > * pointer
Definition: ResultSet.h:250
int8_t * getUnderlyingBuffer() const
Definition: ResultSet.cpp:90
const bool isPermutationBufferEmpty() const
Definition: ResultSet.h:487
bool didOutputColumnar() const
Definition: ResultSet.h:517
std::shared_ptr< RowSetMemoryOwner > getRowSetMemOwner() const
Definition: ResultSet.h:482
std::set< int64_t > BufferSet
Definition: ResultSet.h:830
std::function< bool(const uint32_t, const uint32_t)> createComparator(const std::list< Analyzer::OrderEntry > &order_entries, const bool use_heap)
Definition: ResultSet.h:774
Definition: Analyzer.h:1414
BUFFER_ITERATOR_TYPE BufferIteratorType
Definition: ResultSet.h:747
QueryDescriptionType getQueryDescriptionType() const
#define ALWAYS_INLINE
size_t crt_row_buff_idx_
Definition: ResultSet.h:277
std::vector< std::vector< int64_t > > count_distinct_materialized_buffers_
Definition: ResultSet.h:771
std::vector< std::vector< TargetOffsets > > offsets_for_storage_
Definition: ResultSet.h:717
static bool reduceSingleRow(const int8_t *row_ptr, const int8_t warp_count, const bool is_columnar, const bool replace_bitmap_ptr_with_bitmap_sz, std::vector< int64_t > &agg_vals, const QueryMemoryDescriptor &query_mem_desc, const std::vector< TargetInfo > &targets, const std::vector< int64_t > &agg_init_vals)
bool global_entry_idx_valid_
Definition: ResultSet.h:279
size_t get_key_bytes_rowwise(const QueryMemoryDescriptor &query_mem_desc)
int64_t mappedPtr(const int64_t) const
Definition: ResultSet.cpp:981
FORCE_INLINE HOST DEVICE T align_to_int64(T addr)
std::vector< int64_t > initialize_target_values_for_storage(const std::vector< TargetInfo > &targets)
Definition: ResultSet.cpp:47
const ResultSetStorage * storage_ptr
Definition: ResultSet.h:658
value_type operator*() const
Definition: ResultSet.h:890
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:208
boost::variant< GeoPointTargetValuePtr, GeoLineStringTargetValuePtr, GeoPolyTargetValuePtr, GeoMultiPolyTargetValuePtr > GeoTargetValuePtr
Definition: TargetValue.h:165
const int device_id_
Definition: ResultSet.h:838