OmniSciDB  1dac507f6e
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ResultSetIteration.cpp
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 #include "../Shared/geo_types.h"
26 #include "../Shared/likely.h"
27 #include "Execute.h"
28 #include "ParserNode.h"
30 #include "ResultSet.h"
32 #include "RuntimeFunctions.h"
33 #include "Shared/SqlTypesLayout.h"
34 #include "Shared/sqltypes.h"
35 #include "TypePunning.h"
36 
37 #include <memory>
38 #include <utility>
39 
40 namespace {
41 
42 // Interprets ptr1, ptr2 as the sum and count pair used for AVG.
44  const int8_t compact_sz1,
45  const int8_t* ptr2,
46  const int8_t compact_sz2,
47  const TargetInfo& target_info) {
48  int64_t sum{0};
49  CHECK(target_info.agg_kind == kAVG);
50  const bool float_argument_input = takes_float_argument(target_info);
51  const auto actual_compact_sz1 = float_argument_input ? sizeof(float) : compact_sz1;
52  if (target_info.agg_arg_type.is_integer() || target_info.agg_arg_type.is_decimal()) {
53  sum = read_int_from_buff(ptr1, actual_compact_sz1);
54  } else if (target_info.agg_arg_type.is_fp()) {
55  switch (actual_compact_sz1) {
56  case 8: {
57  double d = *reinterpret_cast<const double*>(ptr1);
58  sum = *reinterpret_cast<const int64_t*>(may_alias_ptr(&d));
59  break;
60  }
61  case 4: {
62  double d = *reinterpret_cast<const float*>(ptr1);
63  sum = *reinterpret_cast<const int64_t*>(may_alias_ptr(&d));
64  break;
65  }
66  default:
67  CHECK(false);
68  }
69  } else {
70  CHECK(false);
71  }
72  const auto count = read_int_from_buff(ptr2, compact_sz2);
73  return pair_to_double({sum, count}, target_info.sql_type, false);
74 }
75 
76 // Given the entire buffer for the result set, buff, finds the beginning of the
77 // column for slot_idx. Only makes sense for column-wise representation.
78 const int8_t* advance_col_buff_to_slot(const int8_t* buff,
80  const std::vector<TargetInfo>& targets,
81  const size_t slot_idx,
82  const bool separate_varlen_storage) {
83  auto crt_col_ptr = get_cols_ptr(buff, query_mem_desc);
84  const auto buffer_col_count = query_mem_desc.getBufferColSlotCount();
85  size_t agg_col_idx{0};
86  for (size_t target_idx = 0; target_idx < targets.size(); ++target_idx) {
87  if (agg_col_idx == slot_idx) {
88  return crt_col_ptr;
89  }
90  CHECK_LT(agg_col_idx, buffer_col_count);
91  const auto& agg_info = targets[target_idx];
92  crt_col_ptr =
93  advance_to_next_columnar_target_buff(crt_col_ptr, query_mem_desc, agg_col_idx);
94  if (agg_info.is_agg && agg_info.agg_kind == kAVG) {
95  if (agg_col_idx + 1 == slot_idx) {
96  return crt_col_ptr;
97  }
99  crt_col_ptr, query_mem_desc, agg_col_idx + 1);
100  }
101  agg_col_idx = advance_slot(agg_col_idx, agg_info, separate_varlen_storage);
102  }
103  CHECK(false);
104  return nullptr;
105 }
106 } // namespace
107 
108 // Gets the byte offset, starting from the beginning of the row targets buffer, of
109 // the value in position slot_idx (only makes sense for row-wise representation).
110 size_t get_byteoff_of_slot(const size_t slot_idx,
112  return query_mem_desc.getPaddedColWidthForRange(0, slot_idx);
113 }
114 
115 std::vector<TargetValue> ResultSet::getRowAt(
116  const size_t global_entry_idx,
117  const bool translate_strings,
118  const bool decimal_to_double,
119  const bool fixup_count_distinct_pointers,
120  const std::vector<bool>& targets_to_skip /* = {}*/) const {
121  const auto storage_lookup_result =
122  fixup_count_distinct_pointers
123  ? StorageLookupResult{storage_.get(), global_entry_idx, 0}
124  : findStorage(global_entry_idx);
125  const auto storage = storage_lookup_result.storage_ptr;
126  const auto local_entry_idx = storage_lookup_result.fixedup_entry_idx;
127  if (!fixup_count_distinct_pointers && storage->isEmptyEntry(local_entry_idx)) {
128  return {};
129  }
130 
131  const auto buff = storage->buff_;
132  CHECK(buff);
133  std::vector<TargetValue> row;
134  size_t agg_col_idx = 0;
135  int8_t* rowwise_target_ptr{nullptr};
136  int8_t* keys_ptr{nullptr};
137  const int8_t* crt_col_ptr{nullptr};
138  if (query_mem_desc_.didOutputColumnar()) {
139  keys_ptr = buff;
140  crt_col_ptr = get_cols_ptr(buff, storage->query_mem_desc_);
141  } else {
142  keys_ptr = row_ptr_rowwise(buff, query_mem_desc_, local_entry_idx);
143  const auto key_bytes_with_padding =
144  align_to_int64(get_key_bytes_rowwise(query_mem_desc_));
145  rowwise_target_ptr = keys_ptr + key_bytes_with_padding;
146  }
147  for (size_t target_idx = 0; target_idx < storage_->targets_.size(); ++target_idx) {
148  const auto& agg_info = storage_->targets_[target_idx];
149  if (query_mem_desc_.didOutputColumnar()) {
150  if (UNLIKELY(!targets_to_skip.empty())) {
151  row.push_back(!targets_to_skip[target_idx]
152  ? getTargetValueFromBufferColwise(crt_col_ptr,
153  keys_ptr,
154  storage->query_mem_desc_,
155  local_entry_idx,
156  global_entry_idx,
157  agg_info,
158  target_idx,
159  agg_col_idx,
160  translate_strings,
161  decimal_to_double)
162  : nullptr);
163  } else {
164  row.push_back(getTargetValueFromBufferColwise(crt_col_ptr,
165  keys_ptr,
166  storage->query_mem_desc_,
167  local_entry_idx,
168  global_entry_idx,
169  agg_info,
170  target_idx,
171  agg_col_idx,
172  translate_strings,
173  decimal_to_double));
174  }
175  crt_col_ptr = advance_target_ptr_col_wise(crt_col_ptr,
176  agg_info,
177  agg_col_idx,
178  storage->query_mem_desc_,
179  separate_varlen_storage_valid_);
180  } else {
181  if (UNLIKELY(!targets_to_skip.empty())) {
182  row.push_back(!targets_to_skip[target_idx]
183  ? getTargetValueFromBufferRowwise(rowwise_target_ptr,
184  keys_ptr,
185  global_entry_idx,
186  agg_info,
187  target_idx,
188  agg_col_idx,
189  translate_strings,
190  decimal_to_double,
191  fixup_count_distinct_pointers)
192  : nullptr);
193  } else {
194  row.push_back(getTargetValueFromBufferRowwise(rowwise_target_ptr,
195  keys_ptr,
196  global_entry_idx,
197  agg_info,
198  target_idx,
199  agg_col_idx,
200  translate_strings,
201  decimal_to_double,
202  fixup_count_distinct_pointers));
203  }
204  rowwise_target_ptr = advance_target_ptr_row_wise(rowwise_target_ptr,
205  agg_info,
206  agg_col_idx,
207  query_mem_desc_,
208  separate_varlen_storage_valid_);
209  }
210  agg_col_idx = advance_slot(agg_col_idx, agg_info, separate_varlen_storage_valid_);
211  }
212 
213  return row;
214 }
215 
216 TargetValue ResultSet::getRowAt(const size_t row_idx,
217  const size_t col_idx,
218  const bool translate_strings,
219  const bool decimal_to_double /* = true */) const {
220  std::lock_guard<std::mutex> lock(row_iteration_mutex_);
221  moveToBegin();
222  for (size_t i = 0; i < row_idx; ++i) {
223  auto crt_row = getNextRowUnlocked(translate_strings, decimal_to_double);
224  CHECK(!crt_row.empty());
225  }
226  auto crt_row = getNextRowUnlocked(translate_strings, decimal_to_double);
227  CHECK(!crt_row.empty());
228  return crt_row[col_idx];
229 }
230 
231 OneIntegerColumnRow ResultSet::getOneColRow(const size_t global_entry_idx) const {
232  const auto storage_lookup_result = findStorage(global_entry_idx);
233  const auto storage = storage_lookup_result.storage_ptr;
234  const auto local_entry_idx = storage_lookup_result.fixedup_entry_idx;
235  if (storage->isEmptyEntry(local_entry_idx)) {
236  return {0, false};
237  }
238  const auto buff = storage->buff_;
239  CHECK(buff);
240  CHECK(!query_mem_desc_.didOutputColumnar());
241  const auto keys_ptr = row_ptr_rowwise(buff, query_mem_desc_, local_entry_idx);
242  const auto key_bytes_with_padding =
243  align_to_int64(get_key_bytes_rowwise(query_mem_desc_));
244  const auto rowwise_target_ptr = keys_ptr + key_bytes_with_padding;
245  const auto tv = getTargetValueFromBufferRowwise(rowwise_target_ptr,
246  keys_ptr,
247  global_entry_idx,
248  targets_.front(),
249  0,
250  0,
251  false,
252  false,
253  false);
254  const auto scalar_tv = boost::get<ScalarTargetValue>(&tv);
255  CHECK(scalar_tv);
256  const auto ival_ptr = boost::get<int64_t>(scalar_tv);
257  CHECK(ival_ptr);
258  return {*ival_ptr, true};
259 }
260 
261 std::vector<TargetValue> ResultSet::getRowAt(const size_t logical_index) const {
262  if (logical_index >= entryCount()) {
263  return {};
264  }
265  const auto entry_idx =
266  permutation_.empty() ? logical_index : permutation_[logical_index];
267  return getRowAt(entry_idx, true, false, false);
268 }
269 
270 std::vector<TargetValue> ResultSet::getRowAtNoTranslations(
271  const size_t logical_index,
272  const std::vector<bool>& targets_to_skip /* = {}*/) const {
273  if (logical_index >= entryCount()) {
274  return {};
275  }
276  const auto entry_idx =
277  permutation_.empty() ? logical_index : permutation_[logical_index];
278  return getRowAt(entry_idx, false, false, false, targets_to_skip);
279 }
280 
281 bool ResultSet::isRowAtEmpty(const size_t logical_index) const {
282  if (logical_index >= entryCount()) {
283  return true;
284  }
285  const auto entry_idx =
286  permutation_.empty() ? logical_index : permutation_[logical_index];
287  const auto storage_lookup_result = findStorage(entry_idx);
288  const auto storage = storage_lookup_result.storage_ptr;
289  const auto local_entry_idx = storage_lookup_result.fixedup_entry_idx;
290  return storage->isEmptyEntry(local_entry_idx);
291 }
292 
293 std::vector<TargetValue> ResultSet::getNextRow(const bool translate_strings,
294  const bool decimal_to_double) const {
295  std::lock_guard<std::mutex> lock(row_iteration_mutex_);
296  if (!storage_ && !just_explain_) {
297  return {};
298  }
299  return getNextRowUnlocked(translate_strings, decimal_to_double);
300 }
301 
302 std::vector<TargetValue> ResultSet::getNextRowUnlocked(
303  const bool translate_strings,
304  const bool decimal_to_double) const {
305  if (just_explain_) {
306  if (fetched_so_far_) {
307  return {};
308  }
309  fetched_so_far_ = 1;
310  return {explanation_};
311  }
312  while (fetched_so_far_ < drop_first_) {
313  const auto row = getNextRowImpl(translate_strings, decimal_to_double);
314  if (row.empty()) {
315  return row;
316  }
317  }
318  return getNextRowImpl(translate_strings, decimal_to_double);
319 }
320 
321 std::vector<TargetValue> ResultSet::getNextRowImpl(const bool translate_strings,
322  const bool decimal_to_double) const {
323  auto entry_buff_idx = advanceCursorToNextEntry();
324  if (keep_first_ && fetched_so_far_ >= drop_first_ + keep_first_) {
325  return {};
326  }
327 
328  if (crt_row_buff_idx_ >= entryCount()) {
329  CHECK_EQ(entryCount(), crt_row_buff_idx_);
330  return {};
331  }
332  auto row = getRowAt(entry_buff_idx, translate_strings, decimal_to_double, false);
333  CHECK(!row.empty());
334  ++crt_row_buff_idx_;
335  ++fetched_so_far_;
336 
337  return row;
338 }
339 
340 namespace {
341 
342 const int8_t* columnar_elem_ptr(const size_t entry_idx,
343  const int8_t* col1_ptr,
344  const int8_t compact_sz1) {
345  return col1_ptr + compact_sz1 * entry_idx;
346 }
347 
348 int64_t int_resize_cast(const int64_t ival, const size_t sz) {
349  switch (sz) {
350  case 8:
351  return ival;
352  case 4:
353  return static_cast<int32_t>(ival);
354  case 2:
355  return static_cast<int16_t>(ival);
356  case 1:
357  return static_cast<int8_t>(ival);
358  default:
359  UNREACHABLE();
360  }
361  UNREACHABLE();
362  return 0;
363 }
364 
365 } // namespace
366 
368  // Compute offsets for base storage and all appended storage
369  for (size_t storage_idx = 0; storage_idx < result_set_->appended_storage_.size() + 1;
370  ++storage_idx) {
371  offsets_for_storage_.emplace_back();
372 
373  const int8_t* rowwise_target_ptr{0};
374 
375  size_t agg_col_idx = 0;
376  for (size_t target_idx = 0; target_idx < result_set_->storage_->targets_.size();
377  ++target_idx) {
378  const auto& agg_info = result_set_->storage_->targets_[target_idx];
379 
380  auto ptr1 = rowwise_target_ptr;
381  const auto compact_sz1 =
382  result_set_->query_mem_desc_.getPaddedSlotWidthBytes(agg_col_idx)
383  ? result_set_->query_mem_desc_.getPaddedSlotWidthBytes(agg_col_idx)
384  : key_width_;
385 
386  const int8_t* ptr2{nullptr};
387  int8_t compact_sz2{0};
388  if ((agg_info.is_agg && agg_info.agg_kind == kAVG)) {
389  ptr2 = ptr1 + compact_sz1;
390  compact_sz2 =
391  result_set_->query_mem_desc_.getPaddedSlotWidthBytes(agg_col_idx + 1);
392  } else if (is_real_str_or_array(agg_info)) {
393  ptr2 = ptr1 + compact_sz1;
394  if (!result_set_->separate_varlen_storage_valid_) {
395  // None encoded strings explicitly attached to ResultSetStorage do not have a
396  // second slot in the QueryMemoryDescriptor col width vector
397  compact_sz2 =
398  result_set_->query_mem_desc_.getPaddedSlotWidthBytes(agg_col_idx + 1);
399  }
400  }
401  offsets_for_storage_[storage_idx].push_back(
402  TargetOffsets{ptr1,
403  static_cast<size_t>(compact_sz1),
404  ptr2,
405  static_cast<size_t>(compact_sz2)});
406  rowwise_target_ptr =
407  advance_target_ptr_row_wise(rowwise_target_ptr,
408  agg_info,
409  agg_col_idx,
410  result_set_->query_mem_desc_,
411  result_set_->separate_varlen_storage_valid_);
412 
413  agg_col_idx = advance_slot(
414  agg_col_idx, agg_info, result_set_->separate_varlen_storage_valid_);
415  }
416  CHECK_EQ(offsets_for_storage_[storage_idx].size(),
417  result_set_->storage_->targets_.size());
418  }
419 }
420 
422  const int8_t* buff,
423  const size_t entry_idx,
424  const size_t target_logical_idx,
425  const StorageLookupResult& storage_lookup_result) const {
426  CHECK(buff);
427  const int8_t* rowwise_target_ptr{nullptr};
428  const int8_t* keys_ptr{nullptr};
429 
430  const size_t storage_idx = storage_lookup_result.storage_idx;
431 
432  CHECK_LT(storage_idx, offsets_for_storage_.size());
433  CHECK_LT(target_logical_idx, offsets_for_storage_[storage_idx].size());
434 
435  const auto& offsets_for_target = offsets_for_storage_[storage_idx][target_logical_idx];
436  const auto& agg_info = result_set_->storage_->targets_[target_logical_idx];
437 
438  keys_ptr = get_rowwise_ptr(buff, entry_idx);
439  rowwise_target_ptr = keys_ptr + key_bytes_with_padding_;
440  auto ptr1 = rowwise_target_ptr + reinterpret_cast<size_t>(offsets_for_target.ptr1);
441  if (result_set_->query_mem_desc_.targetGroupbyIndicesSize() > 0) {
442  if (result_set_->query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) >= 0) {
443  ptr1 = keys_ptr +
444  result_set_->query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) *
445  key_width_;
446  }
447  }
448  const auto i1 =
449  result_set_->lazyReadInt(read_int_from_buff(ptr1, offsets_for_target.compact_sz1),
450  target_logical_idx,
451  storage_lookup_result);
452 
453  if (agg_info.is_agg && agg_info.agg_kind == kAVG) {
454  CHECK(offsets_for_target.ptr2);
455  const auto ptr2 =
456  rowwise_target_ptr + reinterpret_cast<size_t>(offsets_for_target.ptr2);
457  const auto i2 = read_int_from_buff(ptr2, offsets_for_target.compact_sz2);
458  return InternalTargetValue(i1, i2);
459  } else {
460  if (agg_info.sql_type.is_string() &&
461  agg_info.sql_type.get_compression() == kENCODING_NONE) {
462  CHECK(!agg_info.is_agg);
463  if (!result_set_->lazy_fetch_info_.empty()) {
464  CHECK_LT(target_logical_idx, result_set_->lazy_fetch_info_.size());
465  const auto& col_lazy_fetch = result_set_->lazy_fetch_info_[target_logical_idx];
466  if (col_lazy_fetch.is_lazily_fetched) {
467  return InternalTargetValue(reinterpret_cast<const std::string*>(i1));
468  }
469  }
470  if (result_set_->separate_varlen_storage_valid_) {
471  if (i1 < 0) {
472  CHECK_EQ(-1, i1);
473  return InternalTargetValue(static_cast<const std::string*>(nullptr));
474  }
475  CHECK_LT(storage_lookup_result.storage_idx,
476  result_set_->serialized_varlen_buffer_.size());
477  const auto& varlen_buffer_for_fragment =
478  result_set_->serialized_varlen_buffer_[storage_lookup_result.storage_idx];
479  CHECK_LT(static_cast<size_t>(i1), varlen_buffer_for_fragment.size());
480  return InternalTargetValue(&varlen_buffer_for_fragment[i1]);
481  }
482  CHECK(offsets_for_target.ptr2);
483  const auto ptr2 =
484  rowwise_target_ptr + reinterpret_cast<size_t>(offsets_for_target.ptr2);
485  const auto str_len = read_int_from_buff(ptr2, offsets_for_target.compact_sz2);
486  CHECK_GE(str_len, 0);
487  return result_set_->getVarlenOrderEntry(i1, str_len);
488  }
489  return InternalTargetValue(
490  agg_info.sql_type.is_fp()
491  ? i1
492  : int_resize_cast(i1, agg_info.sql_type.get_logical_size()));
493  }
494 }
495 
497  // Compute offsets for base storage and all appended storage
498  const auto key_width = result_set_->query_mem_desc_.getEffectiveKeyWidth();
499  for (size_t storage_idx = 0; storage_idx < result_set_->appended_storage_.size() + 1;
500  ++storage_idx) {
501  offsets_for_storage_.emplace_back();
502 
503  const int8_t* buff = storage_idx == 0
504  ? result_set_->storage_->buff_
505  : result_set_->appended_storage_[storage_idx - 1]->buff_;
506  CHECK(buff);
507 
508  const auto& crt_query_mem_desc =
509  storage_idx == 0
510  ? result_set_->storage_->query_mem_desc_
511  : result_set_->appended_storage_[storage_idx - 1]->query_mem_desc_;
512  const int8_t* crt_col_ptr = get_cols_ptr(buff, crt_query_mem_desc);
513 
514  size_t agg_col_idx = 0;
515  for (size_t target_idx = 0; target_idx < result_set_->storage_->targets_.size();
516  ++target_idx) {
517  const auto& agg_info = result_set_->storage_->targets_[target_idx];
518 
519  const auto compact_sz1 =
520  crt_query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx)
521  ? crt_query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx)
522  : key_width;
523 
524  const auto next_col_ptr = advance_to_next_columnar_target_buff(
525  crt_col_ptr, crt_query_mem_desc, agg_col_idx);
526  const bool uses_two_slots = (agg_info.is_agg && agg_info.agg_kind == kAVG) ||
527  is_real_str_or_array(agg_info);
528  const auto col2_ptr = uses_two_slots ? next_col_ptr : nullptr;
529  const auto compact_sz2 =
530  (agg_info.is_agg && agg_info.agg_kind == kAVG) || is_real_str_or_array(agg_info)
531  ? crt_query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx + 1)
532  : 0;
533 
534  offsets_for_storage_[storage_idx].push_back(
535  TargetOffsets{crt_col_ptr,
536  static_cast<size_t>(compact_sz1),
537  col2_ptr,
538  static_cast<size_t>(compact_sz2)});
539 
540  crt_col_ptr = next_col_ptr;
541  if (uses_two_slots) {
543  crt_col_ptr, crt_query_mem_desc, agg_col_idx + 1);
544  }
545  agg_col_idx = advance_slot(
546  agg_col_idx, agg_info, result_set_->separate_varlen_storage_valid_);
547  }
548  CHECK_EQ(offsets_for_storage_[storage_idx].size(),
549  result_set_->storage_->targets_.size());
550  }
551 }
552 
554  const int8_t* buff,
555  const size_t entry_idx,
556  const size_t target_logical_idx,
557  const StorageLookupResult& storage_lookup_result) const {
558  const size_t storage_idx = storage_lookup_result.storage_idx;
559 
560  CHECK_LT(storage_idx, offsets_for_storage_.size());
561  CHECK_LT(target_logical_idx, offsets_for_storage_[storage_idx].size());
562 
563  const auto& offsets_for_target = offsets_for_storage_[storage_idx][target_logical_idx];
564  const auto& agg_info = result_set_->storage_->targets_[target_logical_idx];
565  auto ptr1 = offsets_for_target.ptr1;
566  if (result_set_->query_mem_desc_.targetGroupbyIndicesSize() > 0) {
567  if (result_set_->query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) >= 0) {
568  ptr1 =
569  buff + result_set_->query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) *
570  result_set_->query_mem_desc_.getEffectiveKeyWidth() *
571  result_set_->query_mem_desc_.entry_count_;
572  }
573  }
574 
575  const auto i1 = result_set_->lazyReadInt(
577  columnar_elem_ptr(entry_idx, ptr1, offsets_for_target.compact_sz1),
578  offsets_for_target.compact_sz1),
579  target_logical_idx,
580  storage_lookup_result);
581  if (agg_info.is_agg && agg_info.agg_kind == kAVG) {
582  CHECK(offsets_for_target.ptr2);
583  const auto i2 = read_int_from_buff(
585  entry_idx, offsets_for_target.ptr2, offsets_for_target.compact_sz2),
586  offsets_for_target.compact_sz2);
587  return InternalTargetValue(i1, i2);
588  } else {
589  // for TEXT ENCODING NONE:
590  if (agg_info.sql_type.is_string() &&
591  agg_info.sql_type.get_compression() == kENCODING_NONE) {
592  CHECK(!agg_info.is_agg);
593  if (!result_set_->lazy_fetch_info_.empty()) {
594  CHECK_LT(target_logical_idx, result_set_->lazy_fetch_info_.size());
595  const auto& col_lazy_fetch = result_set_->lazy_fetch_info_[target_logical_idx];
596  if (col_lazy_fetch.is_lazily_fetched) {
597  return InternalTargetValue(reinterpret_cast<const std::string*>(i1));
598  }
599  }
600  if (result_set_->separate_varlen_storage_valid_) {
601  if (i1 < 0) {
602  CHECK_EQ(-1, i1);
603  return InternalTargetValue(static_cast<const std::string*>(nullptr));
604  }
605  CHECK_LT(storage_lookup_result.storage_idx,
606  result_set_->serialized_varlen_buffer_.size());
607  const auto& varlen_buffer_for_fragment =
608  result_set_->serialized_varlen_buffer_[storage_lookup_result.storage_idx];
609  CHECK_LT(static_cast<size_t>(i1), varlen_buffer_for_fragment.size());
610  return InternalTargetValue(&varlen_buffer_for_fragment[i1]);
611  }
612  CHECK(offsets_for_target.ptr2);
613  const auto i2 = read_int_from_buff(
615  entry_idx, offsets_for_target.ptr2, offsets_for_target.compact_sz2),
616  offsets_for_target.compact_sz2);
617  CHECK_GE(i2, 0);
618  return result_set_->getVarlenOrderEntry(i1, i2);
619  }
620  return InternalTargetValue(
621  agg_info.sql_type.is_fp()
622  ? i1
623  : int_resize_cast(i1, agg_info.sql_type.get_logical_size()));
624  }
625 }
626 
628  const size_t str_len) const {
629  char* host_str_ptr{nullptr};
630  std::vector<int8_t> cpu_buffer;
632  cpu_buffer.resize(str_len);
633  const auto executor = query_mem_desc_.getExecutor();
634  CHECK(executor);
635  auto& data_mgr = executor->catalog_->getDataMgr();
636  copy_from_gpu(&data_mgr,
637  &cpu_buffer[0],
638  static_cast<CUdeviceptr>(str_ptr),
639  str_len,
640  device_id_);
641  host_str_ptr = reinterpret_cast<char*>(&cpu_buffer[0]);
642  } else {
644  host_str_ptr = reinterpret_cast<char*>(str_ptr);
645  }
646  std::string str(host_str_ptr, str_len);
647  return InternalTargetValue(row_set_mem_owner_->addString(str));
648 }
649 
650 int64_t ResultSet::lazyReadInt(const int64_t ival,
651  const size_t target_logical_idx,
652  const StorageLookupResult& storage_lookup_result) const {
653  if (!lazy_fetch_info_.empty()) {
654  CHECK_LT(target_logical_idx, lazy_fetch_info_.size());
655  const auto& col_lazy_fetch = lazy_fetch_info_[target_logical_idx];
656  if (col_lazy_fetch.is_lazily_fetched) {
657  CHECK_LT(static_cast<size_t>(storage_lookup_result.storage_idx),
658  col_buffers_.size());
659  int64_t ival_copy = ival;
660  auto& frag_col_buffers =
661  getColumnFrag(static_cast<size_t>(storage_lookup_result.storage_idx),
662  target_logical_idx,
663  ival_copy);
664  auto& frag_col_buffer = frag_col_buffers[col_lazy_fetch.local_col_id];
665  CHECK_LT(target_logical_idx, targets_.size());
666  const TargetInfo& target_info = targets_[target_logical_idx];
667  CHECK(!target_info.is_agg);
668  if (target_info.sql_type.is_string() &&
669  target_info.sql_type.get_compression() == kENCODING_NONE) {
670  VarlenDatum vd;
671  bool is_end{false};
673  reinterpret_cast<ChunkIter*>(const_cast<int8_t*>(frag_col_buffer)),
674  storage_lookup_result.fixedup_entry_idx,
675  false,
676  &vd,
677  &is_end);
678  CHECK(!is_end);
679  if (vd.is_null) {
680  return 0;
681  }
682  std::string fetched_str(reinterpret_cast<char*>(vd.pointer), vd.length);
683  return reinterpret_cast<int64_t>(row_set_mem_owner_->addString(fetched_str));
684  }
685  return lazy_decode(col_lazy_fetch, frag_col_buffer, ival_copy);
686  }
687  }
688  return ival;
689 }
690 
691 // Not all entries in the buffer represent a valid row. Advance the internal cursor
692 // used for the getNextRow method to the next row which is valid.
695  iter.global_entry_idx_valid_ = false;
696  return;
697  }
698 
699  while (iter.crt_row_buff_idx_ < entryCount()) {
700  const auto entry_idx = permutation_.empty() ? iter.crt_row_buff_idx_
702  const auto storage_lookup_result = findStorage(entry_idx);
703  const auto storage = storage_lookup_result.storage_ptr;
704  const auto fixedup_entry_idx = storage_lookup_result.fixedup_entry_idx;
705  if (!storage->isEmptyEntry(fixedup_entry_idx)) {
706  if (iter.fetched_so_far_ < drop_first_) {
707  ++iter.fetched_so_far_;
708  } else {
709  break;
710  }
711  }
712  ++iter.crt_row_buff_idx_;
713  }
714  if (permutation_.empty()) {
716  } else {
718  iter.global_entry_idx_ = iter.crt_row_buff_idx_ == permutation_.size()
719  ? iter.crt_row_buff_idx_
721  }
722 
724 
725  if (iter.global_entry_idx_valid_) {
726  ++iter.crt_row_buff_idx_;
727  ++iter.fetched_so_far_;
728  }
729 }
730 
731 // Not all entries in the buffer represent a valid row. Advance the internal cursor
732 // used for the getNextRow method to the next row which is valid.
734  while (crt_row_buff_idx_ < entryCount()) {
735  const auto entry_idx =
737  const auto storage_lookup_result = findStorage(entry_idx);
738  const auto storage = storage_lookup_result.storage_ptr;
739  const auto fixedup_entry_idx = storage_lookup_result.fixedup_entry_idx;
740  if (!storage->isEmptyEntry(fixedup_entry_idx)) {
741  break;
742  }
744  }
745  if (permutation_.empty()) {
746  return crt_row_buff_idx_;
747  }
749  return crt_row_buff_idx_ == permutation_.size() ? crt_row_buff_idx_
751 }
752 
753 size_t ResultSet::entryCount() const {
754  return permutation_.empty() ? query_mem_desc_.getEntryCount() : permutation_.size();
755 }
756 
757 size_t ResultSet::getBufferSizeBytes(const ExecutorDeviceType device_type) const {
758  CHECK(storage_);
759  return storage_->query_mem_desc_.getBufferSizeBytes(device_type);
760 }
761 
762 int64_t lazy_decode(const ColumnLazyFetchInfo& col_lazy_fetch,
763  const int8_t* byte_stream,
764  const int64_t pos) {
765  CHECK(col_lazy_fetch.is_lazily_fetched);
766  const auto& type_info = col_lazy_fetch.type;
767  if (type_info.is_fp()) {
768  if (type_info.get_type() == kFLOAT) {
769  double fval = fixed_width_float_decode_noinline(byte_stream, pos);
770  return *reinterpret_cast<const int64_t*>(may_alias_ptr(&fval));
771  } else {
772  double fval = fixed_width_double_decode_noinline(byte_stream, pos);
773  return *reinterpret_cast<const int64_t*>(may_alias_ptr(&fval));
774  }
775  }
776  CHECK(type_info.is_integer() || type_info.is_decimal() || type_info.is_time() ||
777  type_info.is_timeinterval() || type_info.is_boolean() || type_info.is_string() ||
778  type_info.is_array());
779  size_t type_bitwidth = get_bit_width(type_info);
780  if (type_info.get_compression() == kENCODING_FIXED) {
781  type_bitwidth = type_info.get_comp_param();
782  } else if (type_info.get_compression() == kENCODING_DICT) {
783  type_bitwidth = 8 * type_info.get_size();
784  }
785  CHECK_EQ(size_t(0), type_bitwidth % 8);
786  int64_t val;
787  if (type_info.is_date_in_days()) {
788  val = type_info.get_comp_param() == 16
790  byte_stream, 2, NULL_SMALLINT, NULL_BIGINT, pos)
792  byte_stream, 4, NULL_INT, NULL_BIGINT, pos);
793  } else {
794  val = (type_info.get_compression() == kENCODING_DICT &&
795  type_info.get_size() < type_info.get_logical_size() &&
796  type_info.get_comp_param())
797  ? fixed_width_unsigned_decode_noinline(byte_stream, type_bitwidth / 8, pos)
798  : fixed_width_int_decode_noinline(byte_stream, type_bitwidth / 8, pos);
799  }
800  if (type_info.get_compression() != kENCODING_NONE &&
801  type_info.get_compression() != kENCODING_DATE_IN_DAYS) {
802  CHECK(type_info.get_compression() == kENCODING_FIXED ||
803  type_info.get_compression() == kENCODING_DICT);
804  auto encoding = type_info.get_compression();
805  if (encoding == kENCODING_FIXED) {
806  encoding = kENCODING_NONE;
807  }
808  SQLTypeInfo col_logical_ti(type_info.get_type(),
809  type_info.get_dimension(),
810  type_info.get_scale(),
811  false,
812  encoding,
813  0,
814  type_info.get_subtype());
815  if (val == inline_fixed_encoding_null_val(type_info)) {
816  return inline_int_null_val(col_logical_ti);
817  }
818  }
819  return val;
820 }
821 
822 namespace {
823 
824 template <class T>
826  return ScalarTargetValue(static_cast<int64_t>(val));
827 }
828 
829 template <>
831  return ScalarTargetValue(val);
832 }
833 
834 template <>
836  return ScalarTargetValue(val);
837 }
838 
839 template <class T>
841  const int8_t* buff,
842  const size_t buff_sz,
843  std::shared_ptr<RowSetMemoryOwner> row_set_mem_owner) {
844  std::vector<ScalarTargetValue> values;
845  auto buff_elems = reinterpret_cast<const T*>(buff);
846  CHECK_EQ(size_t(0), buff_sz % sizeof(T));
847  const size_t num_elems = buff_sz / sizeof(T);
848  for (size_t i = 0; i < num_elems; ++i) {
849  values.push_back(make_scalar_tv<T>(buff_elems[i]));
850  }
851  return ArrayTargetValue(values);
852 }
853 
855  const int32_t* buff,
856  const size_t buff_sz,
857  const int dict_id,
858  const bool translate_strings,
859  std::shared_ptr<RowSetMemoryOwner> row_set_mem_owner,
860  const Executor* executor) {
861  std::vector<ScalarTargetValue> values;
862  CHECK_EQ(size_t(0), buff_sz % sizeof(int32_t));
863  const size_t num_elems = buff_sz / sizeof(int32_t);
864  if (translate_strings) {
865  for (size_t i = 0; i < num_elems; ++i) {
866  const auto string_id = buff[i];
867 
868  if (string_id == NULL_INT) {
869  values.emplace_back(NullableString(nullptr));
870  } else {
871  if (dict_id == 0) {
872  StringDictionaryProxy* sdp = row_set_mem_owner->getLiteralStringDictProxy();
873  values.emplace_back(sdp->getString(string_id));
874  } else {
875  values.emplace_back(NullableString(
876  executor->getStringDictionaryProxy(dict_id, row_set_mem_owner, false)
877  ->getString(string_id)));
878  }
879  }
880  }
881  } else {
882  for (size_t i = 0; i < num_elems; i++) {
883  values.emplace_back(static_cast<int64_t>(buff[i]));
884  }
885  }
886  return ArrayTargetValue(values);
887 }
888 
890  const int8_t* buff,
891  const size_t buff_sz,
892  const bool translate_strings,
893  std::shared_ptr<RowSetMemoryOwner> row_set_mem_owner,
894  const Executor* executor) {
895  CHECK(array_ti.is_array());
896  const auto& elem_ti = array_ti.get_elem_type();
897  if (elem_ti.is_string()) {
898  return build_string_array_target_value(reinterpret_cast<const int32_t*>(buff),
899  buff_sz,
900  elem_ti.get_comp_param(),
901  translate_strings,
902  row_set_mem_owner,
903  executor);
904  }
905  switch (elem_ti.get_size()) {
906  case 1:
907  return build_array_target_value<int8_t>(buff, buff_sz, row_set_mem_owner);
908  case 2:
909  return build_array_target_value<int16_t>(buff, buff_sz, row_set_mem_owner);
910  case 4:
911  if (elem_ti.is_fp()) {
912  return build_array_target_value<float>(buff, buff_sz, row_set_mem_owner);
913  } else {
914  return build_array_target_value<int32_t>(buff, buff_sz, row_set_mem_owner);
915  }
916  case 8:
917  if (elem_ti.is_fp()) {
918  return build_array_target_value<double>(buff, buff_sz, row_set_mem_owner);
919  } else {
920  return build_array_target_value<int64_t>(buff, buff_sz, row_set_mem_owner);
921  }
922  default:
923  CHECK(false);
924  }
925  CHECK(false);
926  return TargetValue(nullptr);
927 }
928 
929 template <class Tuple, size_t... indices>
930 inline std::vector<std::pair<const int8_t*, const int64_t>> make_vals_vector(
931  std::index_sequence<indices...>,
932  const Tuple& tuple) {
933  return std::vector<std::pair<const int8_t*, const int64_t>>{
934  std::make_pair(std::get<2 * indices>(tuple), std::get<2 * indices + 1>(tuple))...};
935 }
936 
937 inline std::unique_ptr<ArrayDatum> lazy_fetch_chunk(const int8_t* ptr,
938  const int64_t varlen_ptr) {
939  auto ad = std::make_unique<ArrayDatum>();
940  bool is_end;
941  ChunkIter_get_nth(reinterpret_cast<ChunkIter*>(const_cast<int8_t*>(ptr)),
942  varlen_ptr,
943  ad.get(),
944  &is_end);
945  CHECK(!is_end);
946  return ad;
947 }
948 
950  template <typename... T>
951  static inline auto fetch(const ResultSet::GeoReturnType return_type, T&&... vals) {
952  constexpr int num_vals = sizeof...(vals);
953  static_assert(
954  num_vals % 2 == 0,
955  "Must have consistent pointer/size pairs for lazy fetch of geo target values.");
956  const auto vals_vector = make_vals_vector(std::make_index_sequence<num_vals / 2>{},
957  std::make_tuple(vals...));
958  std::array<VarlenDatumPtr, num_vals / 2> ad_arr;
959  size_t ctr = 0;
960  for (const auto& col_pair : vals_vector) {
961  ad_arr[ctr++] = lazy_fetch_chunk(col_pair.first, col_pair.second);
962  }
963  return ad_arr;
964  }
965 };
966 
967 inline std::unique_ptr<ArrayDatum> fetch_data_from_gpu(int64_t varlen_ptr,
968  const int64_t length,
969  Data_Namespace::DataMgr* data_mgr,
970  const int device_id) {
971  auto cpu_buf = std::shared_ptr<int8_t>(new int8_t[length], FreeDeleter());
973  data_mgr, cpu_buf.get(), static_cast<CUdeviceptr>(varlen_ptr), length, device_id);
974  return std::make_unique<ArrayDatum>(length, cpu_buf, false);
975 }
976 
978  static inline auto yieldGpuPtrFetcher() {
979  return [](const int64_t ptr, const int64_t length) -> VarlenDatumPtr {
980  return std::make_unique<VarlenDatum>(length, reinterpret_cast<int8_t*>(ptr), false);
981  };
982  }
983 
984  static inline auto yieldGpuDatumFetcher(Data_Namespace::DataMgr* data_mgr_ptr,
985  const int device_id) {
986  return [data_mgr_ptr, device_id](const int64_t ptr,
987  const int64_t length) -> VarlenDatumPtr {
988  return fetch_data_from_gpu(ptr, length, data_mgr_ptr, device_id);
989  };
990  }
991 
992  static inline auto yieldCpuDatumFetcher() {
993  return [](const int64_t ptr, const int64_t length) -> VarlenDatumPtr {
994  return std::make_unique<VarlenDatum>(length, reinterpret_cast<int8_t*>(ptr), false);
995  };
996  }
997 
998  template <typename... T>
999  static inline auto fetch(const ResultSet::GeoReturnType return_type,
1000  Data_Namespace::DataMgr* data_mgr,
1001  const bool fetch_data_from_gpu,
1002  const int device_id,
1003  T&&... vals) {
1004  auto ad_arr_generator = [&](auto datum_fetcher) {
1005  constexpr int num_vals = sizeof...(vals);
1006  static_assert(
1007  num_vals % 2 == 0,
1008  "Must have consistent pointer/size pairs for lazy fetch of geo target values.");
1009  const auto vals_vector = std::vector<int64_t>{vals...};
1010 
1011  std::array<VarlenDatumPtr, num_vals / 2> ad_arr;
1012  size_t ctr = 0;
1013  for (size_t i = 0; i < vals_vector.size(); i += 2) {
1014  ad_arr[ctr++] = datum_fetcher(vals_vector[i], vals_vector[i + 1]);
1015  }
1016  return ad_arr;
1017  };
1018 
1019  if (fetch_data_from_gpu) {
1021  return ad_arr_generator(yieldGpuPtrFetcher());
1022  } else {
1023  return ad_arr_generator(yieldGpuDatumFetcher(data_mgr, device_id));
1024  }
1025  } else {
1026  return ad_arr_generator(yieldCpuDatumFetcher());
1027  }
1028  }
1029 };
1030 
1031 template <SQLTypes GEO_SOURCE_TYPE, typename GeoTargetFetcher>
1033  template <typename... T>
1034  static inline TargetValue build(const SQLTypeInfo& geo_ti,
1035  const ResultSet::GeoReturnType return_type,
1036  T&&... vals) {
1037  auto ad_arr = GeoTargetFetcher::fetch(return_type, std::forward<T>(vals)...);
1038  static_assert(std::tuple_size<decltype(ad_arr)>::value > 0,
1039  "ArrayDatum array for Geo Target must contain at least one value.");
1040 
1041  switch (return_type) {
1043  // Removing errant NULL check: default ChunkIter accessor may mistake POINT coords
1044  // fixlen array for a NULL, plus it is not needed currently - there is no NULL geo
1045  // in existing tables, all NULL/empty geo is currently discarded on import.
1046  // TODO: add custom ChunkIter accessor able to properly recognize NULL coords
1047  // TODO: once NULL geo support is in, resurrect coords NULL check under !notnull
1048  // if (!geo_ti.get_notnull() && ad_arr[0]->is_null) {
1049  // return GeoTargetValue();
1050  // }
1052  GEO_SOURCE_TYPE>::GeoSerializerType::serialize(geo_ti,
1053  ad_arr);
1054  }
1057  GEO_SOURCE_TYPE>::GeoSerializerType::serialize(geo_ti,
1058  ad_arr);
1059  }
1062  // See the comment above.
1063  // if (!geo_ti.get_notnull() && ad_arr[0]->is_null) {
1064  // return GeoTargetValuePtr();
1065  // }
1067  GEO_SOURCE_TYPE>::GeoSerializerType::serialize(geo_ti,
1068  ad_arr);
1069  }
1070  default: {
1071  UNREACHABLE();
1072  return TargetValue(nullptr);
1073  }
1074  }
1075  }
1076 };
1077 
1078 template <typename T>
1079 inline std::pair<int64_t, int64_t> get_frag_id_and_local_idx(
1080  const std::vector<std::vector<T>>& frag_offsets,
1081  const size_t tab_or_col_idx,
1082  const int64_t global_idx) {
1083  CHECK_GE(global_idx, int64_t(0));
1084  for (int64_t frag_id = frag_offsets.size() - 1; frag_id > 0; --frag_id) {
1085  CHECK_LT(tab_or_col_idx, frag_offsets[frag_id].size());
1086  const auto frag_off = static_cast<int64_t>(frag_offsets[frag_id][tab_or_col_idx]);
1087  if (frag_off < global_idx) {
1088  return {frag_id, global_idx - frag_off};
1089  }
1090  }
1091  return {-1, -1};
1092 }
1093 
1094 } // namespace
1095 
1096 const std::vector<const int8_t*>& ResultSet::getColumnFrag(const size_t storage_idx,
1097  const size_t col_logical_idx,
1098  int64_t& global_idx) const {
1099  CHECK_LT(static_cast<size_t>(storage_idx), col_buffers_.size());
1100  if (col_buffers_[storage_idx].size() > 1) {
1101  int64_t frag_id = 0;
1102  int64_t local_idx = global_idx;
1103  if (consistent_frag_sizes_[storage_idx][col_logical_idx] != -1) {
1104  frag_id = global_idx / consistent_frag_sizes_[storage_idx][col_logical_idx];
1105  local_idx = global_idx % consistent_frag_sizes_[storage_idx][col_logical_idx];
1106  } else {
1107  std::tie(frag_id, local_idx) = get_frag_id_and_local_idx(
1108  frag_offsets_[storage_idx], col_logical_idx, global_idx);
1109  CHECK_LE(local_idx, global_idx);
1110  }
1111  CHECK_GE(frag_id, int64_t(0));
1112  CHECK_LT(static_cast<size_t>(frag_id), col_buffers_[storage_idx].size());
1113  global_idx = local_idx;
1114  return col_buffers_[storage_idx][frag_id];
1115  } else {
1116  CHECK_EQ(size_t(1), col_buffers_[storage_idx].size());
1117  return col_buffers_[storage_idx][0];
1118  }
1119 }
1120 
1125 void ResultSet::copyColumnIntoBuffer(const size_t column_idx,
1126  int8_t* output_buffer,
1127  const size_t output_buffer_size) const {
1129  CHECK_LT(column_idx, query_mem_desc_.getSlotCount());
1130  CHECK(output_buffer_size > 0);
1131  CHECK(output_buffer);
1132  const auto column_width_size = query_mem_desc_.getPaddedSlotWidthBytes(column_idx);
1133  size_t out_buff_offset = 0;
1134 
1135  // the main storage:
1136  const size_t crt_storage_row_count = storage_->query_mem_desc_.getEntryCount();
1137  const size_t crt_buffer_size = crt_storage_row_count * column_width_size;
1138  const size_t column_offset = storage_->query_mem_desc_.getColOffInBytes(column_idx);
1139  const int8_t* storage_buffer = storage_->getUnderlyingBuffer() + column_offset;
1140  CHECK(crt_buffer_size <= output_buffer_size);
1141  std::memcpy(output_buffer, storage_buffer, crt_buffer_size);
1142 
1143  out_buff_offset += crt_buffer_size;
1144 
1145  // the appended storages:
1146  for (size_t i = 0; i < appended_storage_.size(); i++) {
1147  CHECK_LT(out_buff_offset, output_buffer_size);
1148  const size_t crt_storage_row_count =
1149  appended_storage_[i]->query_mem_desc_.getEntryCount();
1150  const size_t crt_buffer_size = crt_storage_row_count * column_width_size;
1151  const size_t column_offset =
1152  appended_storage_[i]->query_mem_desc_.getColOffInBytes(column_idx);
1153  const int8_t* storage_buffer =
1154  appended_storage_[i]->getUnderlyingBuffer() + column_offset;
1155  CHECK(out_buff_offset + crt_buffer_size <= output_buffer_size);
1156  std::memcpy(output_buffer + out_buff_offset, storage_buffer, crt_buffer_size);
1157 
1158  out_buff_offset += crt_buffer_size;
1159  }
1160 }
1161 
1162 template <typename ENTRY_TYPE, QueryDescriptionType QUERY_TYPE, bool COLUMNAR_FORMAT>
1163 ENTRY_TYPE ResultSet::getEntryAt(const size_t row_idx,
1164  const size_t target_idx,
1165  const size_t slot_idx) const {
1166  if constexpr (QUERY_TYPE == QueryDescriptionType::GroupByPerfectHash) { // NOLINT
1167  if constexpr (COLUMNAR_FORMAT) { // NOLINT
1168  return getColumnarPerfectHashEntryAt<ENTRY_TYPE>(row_idx, target_idx, slot_idx);
1169  } else {
1170  return getRowWisePerfectHashEntryAt<ENTRY_TYPE>(row_idx, target_idx, slot_idx);
1171  }
1172  } else if constexpr (QUERY_TYPE == QueryDescriptionType::GroupByBaselineHash) {
1173  if constexpr (COLUMNAR_FORMAT) { // NOLINT
1174  return getColumnarBaselineEntryAt<ENTRY_TYPE>(row_idx, target_idx, slot_idx);
1175  } else {
1176  return getRowWiseBaselineEntryAt<ENTRY_TYPE>(row_idx, target_idx, slot_idx);
1177  }
1178  } else {
1179  UNREACHABLE() << "Invalid query type is used";
1180  return 0;
1181  }
1182 }
1183 
1184 #define DEF_GET_ENTRY_AT(query_type, columnar_output) \
1185  template DATA_T ResultSet::getEntryAt<DATA_T, query_type, columnar_output>( \
1186  const size_t row_idx, const size_t target_idx, const size_t slot_idx) const;
1187 
1188 #define DATA_T int64_t
1192 DEF_GET_ENTRY_AT(QueryDescriptionType::GroupByBaselineHash, false)
1193 #undef DATA_T
1194 
1195 #define DATA_T int32_t
1197 DEF_GET_ENTRY_AT(QueryDescriptionType::GroupByPerfectHash, false)
1198 DEF_GET_ENTRY_AT(QueryDescriptionType::GroupByBaselineHash, true)
1199 DEF_GET_ENTRY_AT(QueryDescriptionType::GroupByBaselineHash, false)
1200 #undef DATA_T
1201 
1202 #define DATA_T int16_t
1204 DEF_GET_ENTRY_AT(QueryDescriptionType::GroupByPerfectHash, false)
1205 DEF_GET_ENTRY_AT(QueryDescriptionType::GroupByBaselineHash, true)
1206 DEF_GET_ENTRY_AT(QueryDescriptionType::GroupByBaselineHash, false)
1207 #undef DATA_T
1208 
1209 #define DATA_T int8_t
1211 DEF_GET_ENTRY_AT(QueryDescriptionType::GroupByPerfectHash, false)
1212 DEF_GET_ENTRY_AT(QueryDescriptionType::GroupByBaselineHash, true)
1213 DEF_GET_ENTRY_AT(QueryDescriptionType::GroupByBaselineHash, false)
1214 #undef DATA_T
1215 
1216 #define DATA_T float
1218 DEF_GET_ENTRY_AT(QueryDescriptionType::GroupByPerfectHash, false)
1219 DEF_GET_ENTRY_AT(QueryDescriptionType::GroupByBaselineHash, true)
1220 DEF_GET_ENTRY_AT(QueryDescriptionType::GroupByBaselineHash, false)
1221 #undef DATA_T
1222 
1223 #define DATA_T double
1225 DEF_GET_ENTRY_AT(QueryDescriptionType::GroupByPerfectHash, false)
1226 DEF_GET_ENTRY_AT(QueryDescriptionType::GroupByBaselineHash, true)
1227 DEF_GET_ENTRY_AT(QueryDescriptionType::GroupByBaselineHash, false)
1228 #undef DATA_T
1229 
1230 #undef DEF_GET_ENTRY_AT
1231 
1238 template <typename ENTRY_TYPE>
1239 ENTRY_TYPE ResultSet::getColumnarPerfectHashEntryAt(const size_t row_idx,
1240  const size_t target_idx,
1241  const size_t slot_idx) const {
1242  const size_t column_offset = storage_->query_mem_desc_.getColOffInBytes(slot_idx);
1243  const int8_t* storage_buffer = storage_->getUnderlyingBuffer() + column_offset;
1244  return reinterpret_cast<const ENTRY_TYPE*>(storage_buffer)[row_idx];
1245 }
1246 
1253 template <typename ENTRY_TYPE>
1254 ENTRY_TYPE ResultSet::getRowWisePerfectHashEntryAt(const size_t row_idx,
1255  const size_t target_idx,
1256  const size_t slot_idx) const {
1257  const size_t row_offset = storage_->query_mem_desc_.getRowSize() * row_idx;
1258  const size_t column_offset = storage_->query_mem_desc_.getColOffInBytes(slot_idx);
1259  const int8_t* storage_buffer =
1260  storage_->getUnderlyingBuffer() + row_offset + column_offset;
1261  return *reinterpret_cast<const ENTRY_TYPE*>(storage_buffer);
1262 }
1263 
1270 template <typename ENTRY_TYPE>
1271 ENTRY_TYPE ResultSet::getRowWiseBaselineEntryAt(const size_t row_idx,
1272  const size_t target_idx,
1273  const size_t slot_idx) const {
1274  CHECK_NE(storage_->query_mem_desc_.targetGroupbyIndicesSize(), size_t(0));
1275  const auto key_width = storage_->query_mem_desc_.getEffectiveKeyWidth();
1276  auto keys_ptr = row_ptr_rowwise(
1277  storage_->getUnderlyingBuffer(), storage_->query_mem_desc_, row_idx);
1278  const auto column_offset =
1279  (storage_->query_mem_desc_.getTargetGroupbyIndex(target_idx) < 0)
1280  ? storage_->query_mem_desc_.getColOffInBytes(slot_idx)
1281  : storage_->query_mem_desc_.getTargetGroupbyIndex(target_idx) * key_width;
1282  const auto storage_buffer = keys_ptr + column_offset;
1283  return *reinterpret_cast<const ENTRY_TYPE*>(storage_buffer);
1284 }
1285 
1292 template <typename ENTRY_TYPE>
1293 ENTRY_TYPE ResultSet::getColumnarBaselineEntryAt(const size_t row_idx,
1294  const size_t target_idx,
1295  const size_t slot_idx) const {
1296  CHECK_NE(storage_->query_mem_desc_.targetGroupbyIndicesSize(), size_t(0));
1297  const auto key_width = storage_->query_mem_desc_.getEffectiveKeyWidth();
1298  const auto column_offset =
1299  (storage_->query_mem_desc_.getTargetGroupbyIndex(target_idx) < 0)
1300  ? storage_->query_mem_desc_.getColOffInBytes(slot_idx)
1301  : storage_->query_mem_desc_.getTargetGroupbyIndex(target_idx) * key_width *
1302  storage_->query_mem_desc_.getEntryCount();
1303  const auto column_buffer = storage_->getUnderlyingBuffer() + column_offset;
1304  return reinterpret_cast<const ENTRY_TYPE*>(column_buffer)[row_idx];
1305 }
1306 
1307 // Interprets ptr1, ptr2 as the ptr and len pair used for variable length data.
1309  const int8_t compact_sz1,
1310  const int8_t* ptr2,
1311  const int8_t compact_sz2,
1312  const TargetInfo& target_info,
1313  const size_t target_logical_idx,
1314  const bool translate_strings,
1315  const size_t entry_buff_idx) const {
1316  auto varlen_ptr = read_int_from_buff(ptr1, compact_sz1);
1317  if (separate_varlen_storage_valid_ && !target_info.is_agg) {
1318  if (varlen_ptr < 0) {
1319  CHECK_EQ(-1, varlen_ptr);
1320  if (target_info.sql_type.get_type() == kARRAY) {
1321  return ArrayTargetValue(boost::optional<std::vector<ScalarTargetValue>>{});
1322  }
1323  return TargetValue(nullptr);
1324  }
1325  const auto storage_idx = getStorageIndex(entry_buff_idx);
1326  if (target_info.sql_type.is_string()) {
1327  CHECK(target_info.sql_type.get_compression() == kENCODING_NONE);
1328  CHECK_LT(storage_idx.first, serialized_varlen_buffer_.size());
1329  const auto& varlen_buffer_for_storage =
1330  serialized_varlen_buffer_[storage_idx.first];
1331  CHECK_LT(static_cast<size_t>(varlen_ptr), varlen_buffer_for_storage.size());
1332  return varlen_buffer_for_storage[varlen_ptr];
1333  } else if (target_info.sql_type.get_type() == kARRAY) {
1334  CHECK_LT(storage_idx.first, serialized_varlen_buffer_.size());
1335  const auto& varlen_buffer = serialized_varlen_buffer_[storage_idx.first];
1336  CHECK_LT(static_cast<size_t>(varlen_ptr), varlen_buffer.size());
1337 
1338  return build_array_target_value(
1339  target_info.sql_type,
1340  reinterpret_cast<const int8_t*>(varlen_buffer[varlen_ptr].data()),
1341  varlen_buffer[varlen_ptr].size(),
1342  translate_strings,
1344  executor_);
1345  } else {
1346  CHECK(false);
1347  }
1348  }
1349  if (!lazy_fetch_info_.empty()) {
1350  CHECK_LT(target_logical_idx, lazy_fetch_info_.size());
1351  const auto& col_lazy_fetch = lazy_fetch_info_[target_logical_idx];
1352  if (col_lazy_fetch.is_lazily_fetched) {
1353  const auto storage_idx = getStorageIndex(entry_buff_idx);
1354  CHECK_LT(storage_idx.first, col_buffers_.size());
1355  auto& frag_col_buffers =
1356  getColumnFrag(storage_idx.first, target_logical_idx, varlen_ptr);
1357  bool is_end{false};
1358  if (target_info.sql_type.is_string()) {
1359  VarlenDatum vd;
1360  ChunkIter_get_nth(reinterpret_cast<ChunkIter*>(const_cast<int8_t*>(
1361  frag_col_buffers[col_lazy_fetch.local_col_id])),
1362  varlen_ptr,
1363  false,
1364  &vd,
1365  &is_end);
1366  CHECK(!is_end);
1367  if (vd.is_null) {
1368  return TargetValue(nullptr);
1369  }
1370  CHECK(vd.pointer);
1371  CHECK_GT(vd.length, 0u);
1372  std::string fetched_str(reinterpret_cast<char*>(vd.pointer), vd.length);
1373  return fetched_str;
1374  } else {
1375  CHECK(target_info.sql_type.is_array());
1376  ArrayDatum ad;
1377  ChunkIter_get_nth(reinterpret_cast<ChunkIter*>(const_cast<int8_t*>(
1378  frag_col_buffers[col_lazy_fetch.local_col_id])),
1379  varlen_ptr,
1380  &ad,
1381  &is_end);
1382  CHECK(!is_end);
1383  if (ad.is_null) {
1384  return ArrayTargetValue(boost::optional<std::vector<ScalarTargetValue>>{});
1385  }
1386  CHECK_GE(ad.length, 0u);
1387  if (ad.length > 0) {
1388  CHECK(ad.pointer);
1389  }
1390  return build_array_target_value(target_info.sql_type,
1391  ad.pointer,
1392  ad.length,
1393  translate_strings,
1395  executor_);
1396  }
1397  }
1398  }
1399  if (!varlen_ptr) {
1400  if (target_info.sql_type.is_array()) {
1401  return ArrayTargetValue(boost::optional<std::vector<ScalarTargetValue>>{});
1402  }
1403  return TargetValue(nullptr);
1404  }
1405  auto length = read_int_from_buff(ptr2, compact_sz2);
1406  if (target_info.sql_type.is_array()) {
1407  const auto& elem_ti = target_info.sql_type.get_elem_type();
1408  length *= elem_ti.get_array_context_logical_size();
1409  }
1410  std::vector<int8_t> cpu_buffer;
1411  if (varlen_ptr && device_type_ == ExecutorDeviceType::GPU) {
1412  cpu_buffer.resize(length);
1413  const auto executor = query_mem_desc_.getExecutor();
1414  CHECK(executor);
1415  auto& data_mgr = executor->catalog_->getDataMgr();
1416  copy_from_gpu(&data_mgr,
1417  &cpu_buffer[0],
1418  static_cast<CUdeviceptr>(varlen_ptr),
1419  length,
1420  device_id_);
1421  varlen_ptr = reinterpret_cast<int64_t>(&cpu_buffer[0]);
1422  }
1423  if (target_info.sql_type.is_array()) {
1424  return build_array_target_value(target_info.sql_type,
1425  reinterpret_cast<const int8_t*>(varlen_ptr),
1426  length,
1427  translate_strings,
1429  executor_);
1430  }
1431  return std::string(reinterpret_cast<char*>(varlen_ptr), length);
1432 }
1433 
1434 bool ResultSet::isGeoColOnGpu(const size_t col_idx) const {
1435  // This should match the logic in makeGeoTargetValue which ultimately calls
1436  // fetch_data_from_gpu when the geo column is on the device.
1437  // TODO(croot): somehow find a way to refactor this and makeGeoTargetValue to use a
1438  // utility function that handles this logic in one place
1439  CHECK_LT(col_idx, targets_.size());
1440  if (!IS_GEO(targets_[col_idx].sql_type.get_type())) {
1441  throw std::runtime_error("Column target at index " + std::to_string(col_idx) +
1442  " is not a geo column. It is of type " +
1443  targets_[col_idx].sql_type.get_type_name() + ".");
1444  }
1445 
1446  const auto& target_info = targets_[col_idx];
1447  if (separate_varlen_storage_valid_ && !target_info.is_agg) {
1448  return false;
1449  }
1450 
1451  if (!lazy_fetch_info_.empty()) {
1452  CHECK_LT(col_idx, lazy_fetch_info_.size());
1453  if (lazy_fetch_info_[col_idx].is_lazily_fetched) {
1454  return false;
1455  }
1456  }
1457 
1459 }
1460 
1461 // Reads a geo value from a series of ptrs to var len types
1462 // In Columnar format, geo_target_ptr is the geo column ptr (a pointer to the beginning
1463 // of that specific geo column) and should be appropriately adjusted with the
1464 // entry_buff_idx
1465 TargetValue ResultSet::makeGeoTargetValue(const int8_t* geo_target_ptr,
1466  const size_t slot_idx,
1467  const TargetInfo& target_info,
1468  const size_t target_logical_idx,
1469  const size_t entry_buff_idx) const {
1470  CHECK(target_info.sql_type.is_geometry());
1471 
1472  auto getNextTargetBufferRowWise = [&](const size_t slot_idx, const size_t range) {
1473  return geo_target_ptr + query_mem_desc_.getPaddedColWidthForRange(slot_idx, range);
1474  };
1475 
1476  auto getNextTargetBufferColWise = [&](const size_t slot_idx, const size_t range) {
1477  const auto storage_info = findStorage(entry_buff_idx);
1478  auto crt_geo_col_ptr = geo_target_ptr;
1479  for (size_t i = slot_idx; i < slot_idx + range; i++) {
1480  crt_geo_col_ptr = advance_to_next_columnar_target_buff(
1481  crt_geo_col_ptr, storage_info.storage_ptr->query_mem_desc_, i);
1482  }
1483  // adjusting the column pointer to represent a pointer to the geo target value
1484  return crt_geo_col_ptr +
1485  storage_info.fixedup_entry_idx *
1486  storage_info.storage_ptr->query_mem_desc_.getPaddedSlotWidthBytes(
1487  slot_idx + range);
1488  };
1489 
1490  auto getNextTargetBuffer = [&](const size_t slot_idx, const size_t range) {
1492  ? getNextTargetBufferColWise(slot_idx, range)
1493  : getNextTargetBufferRowWise(slot_idx, range);
1494  };
1495 
1496  auto getCoordsDataPtr = [&](const int8_t* geo_target_ptr) {
1497  return read_int_from_buff(getNextTargetBuffer(slot_idx, 0),
1499  };
1500 
1501  auto getCoordsLength = [&](const int8_t* geo_target_ptr) {
1502  return read_int_from_buff(getNextTargetBuffer(slot_idx, 1),
1504  };
1505 
1506  auto getRingSizesPtr = [&](const int8_t* geo_target_ptr) {
1507  return read_int_from_buff(getNextTargetBuffer(slot_idx, 2),
1509  };
1510 
1511  auto getRingSizesLength = [&](const int8_t* geo_target_ptr) {
1512  return read_int_from_buff(getNextTargetBuffer(slot_idx, 3),
1514  };
1515 
1516  auto getPolyRingsPtr = [&](const int8_t* geo_target_ptr) {
1517  return read_int_from_buff(getNextTargetBuffer(slot_idx, 4),
1519  };
1520 
1521  auto getPolyRingsLength = [&](const int8_t* geo_target_ptr) {
1522  return read_int_from_buff(getNextTargetBuffer(slot_idx, 5),
1524  };
1525 
1526  auto getFragColBuffers = [&]() -> decltype(auto) {
1527  const auto storage_idx = getStorageIndex(entry_buff_idx);
1528  CHECK_LT(storage_idx.first, col_buffers_.size());
1529  auto global_idx = getCoordsDataPtr(geo_target_ptr);
1530  return getColumnFrag(storage_idx.first, target_logical_idx, global_idx);
1531  };
1532 
1533  const bool is_gpu_fetch = device_type_ == ExecutorDeviceType::GPU;
1534 
1535  auto getDataMgr = [&]() {
1536  auto executor = query_mem_desc_.getExecutor();
1537  CHECK(executor);
1538  auto& data_mgr = executor->catalog_->getDataMgr();
1539  return &data_mgr;
1540  };
1541 
1542  auto getSeparateVarlenStorage = [&]() -> decltype(auto) {
1543  const auto storage_idx = getStorageIndex(entry_buff_idx);
1544  CHECK_LT(storage_idx.first, serialized_varlen_buffer_.size());
1545  const auto& varlen_buffer = serialized_varlen_buffer_[storage_idx.first];
1546  return varlen_buffer;
1547  };
1548 
1549  if (separate_varlen_storage_valid_ && getCoordsDataPtr(geo_target_ptr) < 0) {
1550  CHECK_EQ(-1, getCoordsDataPtr(geo_target_ptr));
1551  return TargetValue(nullptr);
1552  }
1553 
1554  const ColumnLazyFetchInfo* col_lazy_fetch = nullptr;
1555  if (!lazy_fetch_info_.empty()) {
1556  CHECK_LT(target_logical_idx, lazy_fetch_info_.size());
1557  col_lazy_fetch = &lazy_fetch_info_[target_logical_idx];
1558  }
1559 
1560  switch (target_info.sql_type.get_type()) {
1561  case kPOINT: {
1562  if (separate_varlen_storage_valid_ && !target_info.is_agg) {
1563  const auto& varlen_buffer = getSeparateVarlenStorage();
1564  CHECK_LT(static_cast<size_t>(getCoordsDataPtr(geo_target_ptr)),
1565  varlen_buffer.size());
1566 
1567  return GeoTargetValueBuilder<kPOINT, GeoQueryOutputFetchHandler>::build(
1568  target_info.sql_type,
1570  nullptr,
1571  false,
1572  device_id_,
1573  reinterpret_cast<int64_t>(
1574  varlen_buffer[getCoordsDataPtr(geo_target_ptr)].data()),
1575  static_cast<int64_t>(varlen_buffer[getCoordsDataPtr(geo_target_ptr)].size()));
1576  } else if (col_lazy_fetch && col_lazy_fetch->is_lazily_fetched) {
1577  const auto& frag_col_buffers = getFragColBuffers();
1578  return GeoTargetValueBuilder<kPOINT, GeoLazyFetchHandler>::build(
1579  target_info.sql_type,
1581  frag_col_buffers[col_lazy_fetch->local_col_id],
1582  getCoordsDataPtr(geo_target_ptr));
1583  } else {
1584  return GeoTargetValueBuilder<kPOINT, GeoQueryOutputFetchHandler>::build(
1585  target_info.sql_type,
1587  is_gpu_fetch ? getDataMgr() : nullptr,
1588  is_gpu_fetch,
1589  device_id_,
1590  getCoordsDataPtr(geo_target_ptr),
1591  getCoordsLength(geo_target_ptr));
1592  }
1593  break;
1594  }
1595  case kLINESTRING: {
1596  if (separate_varlen_storage_valid_ && !target_info.is_agg) {
1597  const auto& varlen_buffer = getSeparateVarlenStorage();
1598  CHECK_LT(static_cast<size_t>(getCoordsDataPtr(geo_target_ptr)),
1599  varlen_buffer.size());
1600 
1601  return GeoTargetValueBuilder<kLINESTRING, GeoQueryOutputFetchHandler>::build(
1602  target_info.sql_type,
1604  nullptr,
1605  false,
1606  device_id_,
1607  reinterpret_cast<int64_t>(
1608  varlen_buffer[getCoordsDataPtr(geo_target_ptr)].data()),
1609  static_cast<int64_t>(varlen_buffer[getCoordsDataPtr(geo_target_ptr)].size()));
1610  } else if (col_lazy_fetch && col_lazy_fetch->is_lazily_fetched) {
1611  const auto& frag_col_buffers = getFragColBuffers();
1612  return GeoTargetValueBuilder<kLINESTRING, GeoLazyFetchHandler>::build(
1613  target_info.sql_type,
1615  frag_col_buffers[col_lazy_fetch->local_col_id],
1616  getCoordsDataPtr(geo_target_ptr));
1617  } else {
1618  return GeoTargetValueBuilder<kLINESTRING, GeoQueryOutputFetchHandler>::build(
1619  target_info.sql_type,
1621  is_gpu_fetch ? getDataMgr() : nullptr,
1622  is_gpu_fetch,
1623  device_id_,
1624  getCoordsDataPtr(geo_target_ptr),
1625  getCoordsLength(geo_target_ptr));
1626  }
1627  break;
1628  }
1629  case kPOLYGON: {
1630  if (separate_varlen_storage_valid_ && !target_info.is_agg) {
1631  const auto& varlen_buffer = getSeparateVarlenStorage();
1632  CHECK_LT(static_cast<size_t>(getCoordsDataPtr(geo_target_ptr) + 1),
1633  varlen_buffer.size());
1634 
1635  return GeoTargetValueBuilder<kPOLYGON, GeoQueryOutputFetchHandler>::build(
1636  target_info.sql_type,
1638  nullptr,
1639  false,
1640  device_id_,
1641  reinterpret_cast<int64_t>(
1642  varlen_buffer[getCoordsDataPtr(geo_target_ptr)].data()),
1643  static_cast<int64_t>(varlen_buffer[getCoordsDataPtr(geo_target_ptr)].size()),
1644  reinterpret_cast<int64_t>(
1645  varlen_buffer[getCoordsDataPtr(geo_target_ptr) + 1].data()),
1646  static_cast<int64_t>(
1647  varlen_buffer[getCoordsDataPtr(geo_target_ptr) + 1].size()));
1648  } else if (col_lazy_fetch && col_lazy_fetch->is_lazily_fetched) {
1649  const auto& frag_col_buffers = getFragColBuffers();
1650 
1651  return GeoTargetValueBuilder<kPOLYGON, GeoLazyFetchHandler>::build(
1652  target_info.sql_type,
1654  frag_col_buffers[col_lazy_fetch->local_col_id],
1655  getCoordsDataPtr(geo_target_ptr),
1656  frag_col_buffers[col_lazy_fetch->local_col_id + 1],
1657  getCoordsDataPtr(geo_target_ptr));
1658  } else {
1659  return GeoTargetValueBuilder<kPOLYGON, GeoQueryOutputFetchHandler>::build(
1660  target_info.sql_type,
1662  is_gpu_fetch ? getDataMgr() : nullptr,
1663  is_gpu_fetch,
1664  device_id_,
1665  getCoordsDataPtr(geo_target_ptr),
1666  getCoordsLength(geo_target_ptr),
1667  getRingSizesPtr(geo_target_ptr),
1668  getRingSizesLength(geo_target_ptr) * 4);
1669  }
1670  break;
1671  }
1672  case kMULTIPOLYGON: {
1673  if (separate_varlen_storage_valid_ && !target_info.is_agg) {
1674  const auto& varlen_buffer = getSeparateVarlenStorage();
1675  CHECK_LT(static_cast<size_t>(getCoordsDataPtr(geo_target_ptr) + 2),
1676  varlen_buffer.size());
1677 
1678  return GeoTargetValueBuilder<kMULTIPOLYGON, GeoQueryOutputFetchHandler>::build(
1679  target_info.sql_type,
1681  nullptr,
1682  false,
1683  device_id_,
1684  reinterpret_cast<int64_t>(
1685  varlen_buffer[getCoordsDataPtr(geo_target_ptr)].data()),
1686  static_cast<int64_t>(varlen_buffer[getCoordsDataPtr(geo_target_ptr)].size()),
1687  reinterpret_cast<int64_t>(
1688  varlen_buffer[getCoordsDataPtr(geo_target_ptr) + 1].data()),
1689  static_cast<int64_t>(
1690  varlen_buffer[getCoordsDataPtr(geo_target_ptr) + 1].size()),
1691  reinterpret_cast<int64_t>(
1692  varlen_buffer[getCoordsDataPtr(geo_target_ptr) + 2].data()),
1693  static_cast<int64_t>(
1694  varlen_buffer[getCoordsDataPtr(geo_target_ptr) + 2].size()));
1695  } else if (col_lazy_fetch && col_lazy_fetch->is_lazily_fetched) {
1696  const auto& frag_col_buffers = getFragColBuffers();
1697 
1698  return GeoTargetValueBuilder<kMULTIPOLYGON, GeoLazyFetchHandler>::build(
1699  target_info.sql_type,
1701  frag_col_buffers[col_lazy_fetch->local_col_id],
1702  getCoordsDataPtr(geo_target_ptr),
1703  frag_col_buffers[col_lazy_fetch->local_col_id + 1],
1704  getCoordsDataPtr(geo_target_ptr),
1705  frag_col_buffers[col_lazy_fetch->local_col_id + 2],
1706  getCoordsDataPtr(geo_target_ptr));
1707  } else {
1708  return GeoTargetValueBuilder<kMULTIPOLYGON, GeoQueryOutputFetchHandler>::build(
1709  target_info.sql_type,
1711  is_gpu_fetch ? getDataMgr() : nullptr,
1712  is_gpu_fetch,
1713  device_id_,
1714  getCoordsDataPtr(geo_target_ptr),
1715  getCoordsLength(geo_target_ptr),
1716  getRingSizesPtr(geo_target_ptr),
1717  getRingSizesLength(geo_target_ptr) * 4,
1718  getPolyRingsPtr(geo_target_ptr),
1719  getPolyRingsLength(geo_target_ptr) * 4);
1720  }
1721  break;
1722  }
1723  default:
1724  throw std::runtime_error("Unknown Geometry type encountered: " +
1725  target_info.sql_type.get_type_name());
1726  }
1727  UNREACHABLE();
1728  return TargetValue(nullptr);
1729 }
1730 
1731 // Reads an integer or a float from ptr based on the type and the byte width.
1733  const int8_t compact_sz,
1734  const TargetInfo& target_info,
1735  const size_t target_logical_idx,
1736  const bool translate_strings,
1737  const bool decimal_to_double,
1738  const size_t entry_buff_idx) const {
1739  auto actual_compact_sz = compact_sz;
1740  if (target_info.sql_type.get_type() == kFLOAT &&
1743  actual_compact_sz = sizeof(float);
1744  } else {
1745  actual_compact_sz = sizeof(double);
1746  }
1747  if (target_info.is_agg &&
1748  (target_info.agg_kind == kAVG || target_info.agg_kind == kSUM ||
1749  target_info.agg_kind == kMIN || target_info.agg_kind == kMAX)) {
1750  // The above listed aggregates use two floats in a single 8-byte slot. Set the
1751  // padded size to 4 bytes to properly read each value.
1752  actual_compact_sz = sizeof(float);
1753  }
1754  }
1755  if (get_compact_type(target_info).is_date_in_days()) {
1756  // Dates encoded in days are converted to 8 byte values on read.
1757  actual_compact_sz = sizeof(int64_t);
1758  }
1759 
1760  // String dictionary keys are read as 32-bit values regardless of encoding
1761  if (target_info.sql_type.is_string() &&
1762  target_info.sql_type.get_compression() == kENCODING_DICT &&
1763  target_info.sql_type.get_comp_param()) {
1764  actual_compact_sz = sizeof(int32_t);
1765  }
1766 
1767  auto ival = read_int_from_buff(ptr, actual_compact_sz);
1768  const auto& chosen_type = get_compact_type(target_info);
1769  if (!lazy_fetch_info_.empty()) {
1770  CHECK_LT(target_logical_idx, lazy_fetch_info_.size());
1771  const auto& col_lazy_fetch = lazy_fetch_info_[target_logical_idx];
1772  if (col_lazy_fetch.is_lazily_fetched) {
1773  CHECK_GE(ival, 0);
1774  const auto storage_idx = getStorageIndex(entry_buff_idx);
1775  CHECK_LT(storage_idx.first, col_buffers_.size());
1776  auto& frag_col_buffers = getColumnFrag(storage_idx.first, target_logical_idx, ival);
1777  ival = lazy_decode(
1778  col_lazy_fetch, frag_col_buffers[col_lazy_fetch.local_col_id], ival);
1779  if (chosen_type.is_fp()) {
1780  const auto dval = *reinterpret_cast<const double*>(may_alias_ptr(&ival));
1781  if (chosen_type.get_type() == kFLOAT) {
1782  return ScalarTargetValue(static_cast<float>(dval));
1783  } else {
1784  return ScalarTargetValue(dval);
1785  }
1786  }
1787  }
1788  }
1789  if (chosen_type.is_fp()) {
1790  switch (actual_compact_sz) {
1791  case 8: {
1792  const auto dval = *reinterpret_cast<const double*>(ptr);
1793  return chosen_type.get_type() == kFLOAT
1794  ? ScalarTargetValue(static_cast<const float>(dval))
1795  : ScalarTargetValue(dval);
1796  }
1797  case 4: {
1798  CHECK_EQ(kFLOAT, chosen_type.get_type());
1799  return *reinterpret_cast<const float*>(ptr);
1800  }
1801  default:
1802  CHECK(false);
1803  }
1804  }
1805  if (chosen_type.is_integer() | chosen_type.is_boolean() || chosen_type.is_time() ||
1806  chosen_type.is_timeinterval()) {
1807  if (is_distinct_target(target_info)) {
1809  ival, query_mem_desc_.getCountDistinctDescriptor(target_logical_idx)));
1810  }
1811  // TODO(alex): remove int_resize_cast, make read_int_from_buff return the
1812  // right type instead
1813  if (inline_int_null_val(chosen_type) ==
1814  int_resize_cast(ival, chosen_type.get_logical_size())) {
1815  return inline_int_null_val(target_info.sql_type);
1816  }
1817  return ival;
1818  }
1819  if (chosen_type.is_string() && chosen_type.get_compression() == kENCODING_DICT) {
1820  if (translate_strings) {
1821  if (static_cast<int32_t>(ival) ==
1822  NULL_INT) { // TODO(alex): this isn't nice, fix it
1823  return NullableString(nullptr);
1824  }
1825  StringDictionaryProxy* sdp{nullptr};
1826  if (!chosen_type.get_comp_param()) {
1827  sdp = row_set_mem_owner_->getLiteralStringDictProxy();
1828  } else {
1829  sdp = executor_
1830  ? executor_->getStringDictionaryProxy(
1831  chosen_type.get_comp_param(), row_set_mem_owner_, false)
1832  : row_set_mem_owner_->getStringDictProxy(chosen_type.get_comp_param());
1833  }
1834  return NullableString(sdp->getString(ival));
1835  } else {
1836  return static_cast<int64_t>(static_cast<int32_t>(ival));
1837  }
1838  }
1839  if (chosen_type.is_decimal()) {
1840  if (decimal_to_double) {
1841  if (target_info.is_agg &&
1842  (target_info.agg_kind == kAVG || target_info.agg_kind == kSUM ||
1843  target_info.agg_kind == kMIN || target_info.agg_kind == kMAX) &&
1844  ival == inline_int_null_val(SQLTypeInfo(kBIGINT, false))) {
1845  return NULL_DOUBLE;
1846  }
1847  if (ival ==
1848  inline_int_null_val(SQLTypeInfo(decimal_to_int_type(chosen_type), false))) {
1849  return NULL_DOUBLE;
1850  }
1851  return static_cast<double>(ival) / exp_to_scale(chosen_type.get_scale());
1852  }
1853  return ival;
1854  }
1855  CHECK(false);
1856  return TargetValue(int64_t(0));
1857 }
1858 
1859 // Gets the TargetValue stored at position local_entry_idx in the col1_ptr and col2_ptr
1860 // column buffers. The second column is only used for AVG.
1861 // the global_entry_idx is passed to makeTargetValue to be used for
1862 // final lazy fetch (if there's any).
1864  const int8_t* col_ptr,
1865  const int8_t* keys_ptr,
1867  const size_t local_entry_idx,
1868  const size_t global_entry_idx,
1869  const TargetInfo& target_info,
1870  const size_t target_logical_idx,
1871  const size_t slot_idx,
1872  const bool translate_strings,
1873  const bool decimal_to_double) const {
1875  const auto col1_ptr = col_ptr;
1876  const auto compact_sz1 = query_mem_desc.getPaddedSlotWidthBytes(slot_idx);
1877  const auto next_col_ptr =
1878  advance_to_next_columnar_target_buff(col1_ptr, query_mem_desc, slot_idx);
1879  const auto col2_ptr = ((target_info.is_agg && target_info.agg_kind == kAVG) ||
1880  is_real_str_or_array(target_info))
1881  ? next_col_ptr
1882  : nullptr;
1883  const auto compact_sz2 = ((target_info.is_agg && target_info.agg_kind == kAVG) ||
1884  is_real_str_or_array(target_info))
1885  ? query_mem_desc.getPaddedSlotWidthBytes(slot_idx + 1)
1886  : 0;
1887 
1888  // TODO(Saman): add required logics for count distinct
1889  // geospatial target values:
1890  if (target_info.sql_type.is_geometry()) {
1891  return makeGeoTargetValue(
1892  col1_ptr, slot_idx, target_info, target_logical_idx, global_entry_idx);
1893  }
1894 
1895  const auto ptr1 = columnar_elem_ptr(local_entry_idx, col1_ptr, compact_sz1);
1896  if (target_info.agg_kind == kAVG || is_real_str_or_array(target_info)) {
1897  CHECK(col2_ptr);
1898  CHECK(compact_sz2);
1899  const auto ptr2 = columnar_elem_ptr(local_entry_idx, col2_ptr, compact_sz2);
1900  return target_info.agg_kind == kAVG
1901  ? make_avg_target_value(ptr1, compact_sz1, ptr2, compact_sz2, target_info)
1902  : makeVarlenTargetValue(ptr1,
1903  compact_sz1,
1904  ptr2,
1905  compact_sz2,
1906  target_info,
1907  target_logical_idx,
1908  translate_strings,
1909  global_entry_idx);
1910  }
1912  query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) < 0) {
1913  return makeTargetValue(ptr1,
1914  compact_sz1,
1915  target_info,
1916  target_logical_idx,
1917  translate_strings,
1918  decimal_to_double,
1919  global_entry_idx);
1920  }
1921  const auto key_width = query_mem_desc_.getEffectiveKeyWidth();
1922  const auto key_idx = query_mem_desc_.getTargetGroupbyIndex(target_logical_idx);
1923  CHECK_GE(key_idx, 0);
1924  auto key_col_ptr = keys_ptr + key_idx * query_mem_desc_.getEntryCount() * key_width;
1925  return makeTargetValue(columnar_elem_ptr(local_entry_idx, key_col_ptr, key_width),
1926  key_width,
1927  target_info,
1928  target_logical_idx,
1929  translate_strings,
1930  decimal_to_double,
1931  global_entry_idx);
1932 }
1933 
1934 // Gets the TargetValue stored in slot_idx (and slot_idx for AVG) of
1935 // rowwise_target_ptr.
1937  int8_t* rowwise_target_ptr,
1938  int8_t* keys_ptr,
1939  const size_t entry_buff_idx,
1940  const TargetInfo& target_info,
1941  const size_t target_logical_idx,
1942  const size_t slot_idx,
1943  const bool translate_strings,
1944  const bool decimal_to_double,
1945  const bool fixup_count_distinct_pointers) const {
1946  if (UNLIKELY(fixup_count_distinct_pointers)) {
1947  if (is_distinct_target(target_info)) {
1948  auto count_distinct_ptr_ptr = reinterpret_cast<int64_t*>(rowwise_target_ptr);
1949  const auto remote_ptr = *count_distinct_ptr_ptr;
1950  if (remote_ptr) {
1951  const auto ptr = storage_->mappedPtr(remote_ptr);
1952  if (ptr) {
1953  *count_distinct_ptr_ptr = ptr;
1954  } else {
1955  // need to create a zero filled buffer for this remote_ptr
1956  const auto& count_distinct_desc =
1957  query_mem_desc_.count_distinct_descriptors_[target_logical_idx];
1958  const auto bitmap_byte_sz = count_distinct_desc.sub_bitmap_count == 1
1959  ? count_distinct_desc.bitmapSizeBytes()
1960  : count_distinct_desc.bitmapPaddedSizeBytes();
1961  auto count_distinct_buffer =
1962  static_cast<int8_t*>(checked_malloc(bitmap_byte_sz));
1963  memset(count_distinct_buffer, 0, bitmap_byte_sz);
1964  row_set_mem_owner_->addCountDistinctBuffer(
1965  count_distinct_buffer, bitmap_byte_sz, true);
1966  *count_distinct_ptr_ptr = reinterpret_cast<int64_t>(count_distinct_buffer);
1967  }
1968  }
1969  }
1970  return int64_t(0);
1971  }
1972  if (target_info.sql_type.is_geometry()) {
1973  return makeGeoTargetValue(
1974  rowwise_target_ptr, slot_idx, target_info, target_logical_idx, entry_buff_idx);
1975  }
1976 
1977  auto ptr1 = rowwise_target_ptr;
1978  int8_t compact_sz1 = query_mem_desc_.getPaddedSlotWidthBytes(slot_idx);
1980  !query_mem_desc_.hasKeylessHash() && !target_info.is_agg) {
1981  // Single column perfect hash group by can utilize one slot for both the key and the
1982  // target value if both values fit in 8 bytes. Use the target value actual size for
1983  // this case. If they don't, the target value should be 8 bytes, so we can still use
1984  // the actual size rather than the compact size.
1985  compact_sz1 = query_mem_desc_.getLogicalSlotWidthBytes(slot_idx);
1986  }
1987 
1988  // logic for deciding width of column
1989  if (target_info.agg_kind == kAVG || is_real_str_or_array(target_info)) {
1990  const auto ptr2 =
1991  rowwise_target_ptr + query_mem_desc_.getPaddedSlotWidthBytes(slot_idx);
1992  int8_t compact_sz2 = 0;
1993  // Skip reading the second slot if we have a none encoded string and are using
1994  // the none encoded strings buffer attached to ResultSetStorage
1996  (target_info.sql_type.is_array() ||
1997  (target_info.sql_type.is_string() &&
1998  target_info.sql_type.get_compression() == kENCODING_NONE)))) {
1999  compact_sz2 = query_mem_desc_.getPaddedSlotWidthBytes(slot_idx + 1);
2000  }
2001  if (separate_varlen_storage_valid_ && target_info.is_agg) {
2002  compact_sz2 = 8; // TODO(adb): is there a better way to do this?
2003  }
2004  CHECK(ptr2);
2005  return target_info.agg_kind == kAVG
2006  ? make_avg_target_value(ptr1, compact_sz1, ptr2, compact_sz2, target_info)
2007  : makeVarlenTargetValue(ptr1,
2008  compact_sz1,
2009  ptr2,
2010  compact_sz2,
2011  target_info,
2012  target_logical_idx,
2013  translate_strings,
2014  entry_buff_idx);
2015  }
2017  query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) < 0) {
2018  return makeTargetValue(ptr1,
2019  compact_sz1,
2020  target_info,
2021  target_logical_idx,
2022  translate_strings,
2023  decimal_to_double,
2024  entry_buff_idx);
2025  }
2026  const auto key_width = query_mem_desc_.getEffectiveKeyWidth();
2027  ptr1 = keys_ptr + query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) * key_width;
2028  return makeTargetValue(ptr1,
2029  key_width,
2030  target_info,
2031  target_logical_idx,
2032  translate_strings,
2033  decimal_to_double,
2034  entry_buff_idx);
2035 }
2036 
2037 // Returns true iff the entry at position entry_idx in buff contains a valid row.
2038 bool ResultSetStorage::isEmptyEntry(const size_t entry_idx, const int8_t* buff) const {
2041  return false;
2042  }
2044  return isEmptyEntryColumnar(entry_idx, buff);
2045  }
2050  CHECK_LT(static_cast<size_t>(query_mem_desc_.getTargetIdxForKey()),
2051  target_init_vals_.size());
2052  const auto rowwise_target_ptr = row_ptr_rowwise(buff, query_mem_desc_, entry_idx);
2053  const auto target_slot_off =
2055  return read_int_from_buff(rowwise_target_ptr + target_slot_off,
2058  target_init_vals_[query_mem_desc_.getTargetIdxForKey()];
2059  } else {
2060  const auto keys_ptr = row_ptr_rowwise(buff, query_mem_desc_, entry_idx);
2062  case 4:
2065  return *reinterpret_cast<const int32_t*>(keys_ptr) == EMPTY_KEY_32;
2066  case 8:
2067  return *reinterpret_cast<const int64_t*>(keys_ptr) == EMPTY_KEY_64;
2068  default:
2069  CHECK(false);
2070  return true;
2071  }
2072  }
2073 }
2074 
2075 /*
2076  * Returns true if the entry contain empty keys
2077  * This function should only be used with columanr format.
2078  */
2079 bool ResultSetStorage::isEmptyEntryColumnar(const size_t entry_idx,
2080  const int8_t* buff) const {
2084  return false;
2085  }
2090  CHECK_LT(static_cast<size_t>(query_mem_desc_.getTargetIdxForKey()),
2091  target_init_vals_.size());
2092  const auto col_buff = advance_col_buff_to_slot(
2094  const auto entry_buff =
2095  col_buff + entry_idx * query_mem_desc_.getPaddedSlotWidthBytes(
2097  return read_int_from_buff(entry_buff,
2100  target_init_vals_[query_mem_desc_.getTargetIdxForKey()];
2101  } else {
2102  // it's enough to find the first group key which is empty
2104  return reinterpret_cast<const int64_t*>(buff)[entry_idx] == EMPTY_KEY_64;
2105  } else {
2107  const auto target_buff = buff + query_mem_desc_.getPrependedGroupColOffInBytes(0);
2108  switch (query_mem_desc_.groupColWidth(0)) {
2109  case 8:
2110  return reinterpret_cast<const int64_t*>(target_buff)[entry_idx] == EMPTY_KEY_64;
2111  case 4:
2112  return reinterpret_cast<const int32_t*>(target_buff)[entry_idx] == EMPTY_KEY_32;
2113  case 2:
2114  return reinterpret_cast<const int16_t*>(target_buff)[entry_idx] == EMPTY_KEY_16;
2115  case 1:
2116  return reinterpret_cast<const int8_t*>(target_buff)[entry_idx] == EMPTY_KEY_8;
2117  default:
2118  CHECK(false);
2119  }
2120  }
2121  return false;
2122  }
2123  return false;
2124 }
2125 
2126 bool ResultSetStorage::isEmptyEntry(const size_t entry_idx) const {
2127  return isEmptyEntry(entry_idx, buff_);
2128 }
2129 
2131  const InternalTargetValue& val,
2132  const bool float_argument_input) {
2133  if (ti.get_notnull()) {
2134  return false;
2135  }
2136  if (val.isInt()) {
2137  return val.i1 == null_val_bit_pattern(ti, float_argument_input);
2138  }
2139  if (val.isPair()) {
2140  return !val.i2 ||
2141  pair_to_double({val.i1, val.i2}, ti, float_argument_input) == NULL_DOUBLE;
2142  }
2143  if (val.isStr()) {
2144  return !val.i1;
2145  }
2146  CHECK(val.isNull());
2147  return true;
2148 }
const SQLTypeInfo type
Definition: ResultSet.h:225
bool is_fp() const
Definition: sqltypes.h:481
InternalTargetValue getColumnInternal(const int8_t *buff, const size_t entry_idx, const size_t target_logical_idx, const StorageLookupResult &storage_lookup_result) const
QueryDescriptionType
Definition: Types.h:26
int64_t lazy_decode(const ColumnLazyFetchInfo &col_lazy_fetch, const int8_t *byte_stream, const int64_t pos)
#define CHECK_EQ(x, y)
Definition: Logger.h:198
std::pair< size_t, size_t > getStorageIndex(const size_t entry_idx) const
Definition: ResultSet.cpp:594
#define NULL_DOUBLE
Definition: sqltypes.h:179
bool isEmptyEntry(const size_t entry_idx, const int8_t *buff) const
#define EMPTY_KEY_64
ENTRY_TYPE getRowWisePerfectHashEntryAt(const size_t row_idx, const size_t target_idx, const size_t slot_idx) const
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:334
HOST DEVICE int get_comp_param() const
Definition: sqltypes.h:335
double decimal_to_double(const SQLTypeInfo &otype, int64_t oval)
bool isPair() const
Definition: TargetValue.h:67
std::vector< std::unique_ptr< ResultSetStorage > > appended_storage_
Definition: ResultSet.h:805
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:842
bool isEmptyEntryColumnar(const size_t entry_idx, const int8_t *buff) const
DEVICE NEVER_INLINE int64_t SUFFIX() fixed_width_int_decode_noinline(const int8_t *byte_stream, const int32_t byte_width, const int64_t pos)
Definition: DecodersImpl.h:83
ExecutorDeviceType
TargetValue build_string_array_target_value(const int32_t *buff, const size_t buff_sz, const int dict_id, const bool translate_strings, std::shared_ptr< RowSetMemoryOwner > row_set_mem_owner, const Executor *executor)
bool isStr() const
Definition: TargetValue.h:71
bool is_null
Definition: sqltypes.h:76
bool isLogicalSizedColumnsAllowed() const
#define NULL_BIGINT
Definition: sqltypes.h:177
T advance_to_next_columnar_target_buff(T target_ptr, const QueryMemoryDescriptor &query_mem_desc, const size_t target_slot_idx)
SQLTypeInfo sql_type
Definition: TargetInfo.h:42
std::unique_ptr< ArrayDatum > lazy_fetch_chunk(const int8_t *ptr, const int64_t varlen_ptr)
const Executor * executor_
Definition: ResultSet.h:814
size_t get_byteoff_of_slot(const size_t slot_idx, const QueryMemoryDescriptor &query_mem_desc)
unsigned long long CUdeviceptr
Definition: nocuda.h:27
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)
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:803
#define UNREACHABLE()
Definition: Logger.h:234
#define CHECK_GE(x, y)
Definition: Logger.h:203
std::unique_ptr< ResultSetStorage > storage_
Definition: ResultSet.h:804
std::string getString(int32_t string_id) const
ENTRY_TYPE getEntryAt(const size_t row_idx, const size_t target_idx, const size_t slot_idx) const
size_t getEffectiveKeyWidth() const
Constants for Builtin SQL Types supported by MapD.
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
int64_t read_int_from_buff(const int8_t *ptr, const int8_t compact_sz)
size_t keep_first_
Definition: ResultSet.h:809
TargetValue make_avg_target_value(const int8_t *ptr1, const int8_t compact_sz1, const int8_t *ptr2, const int8_t compact_sz2, const TargetInfo &target_info)
double pair_to_double(const std::pair< int64_t, int64_t > &fp_pair, const SQLTypeInfo &ti, const bool float_argument_input)
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:120
std::vector< SerializedVarlenBufferStorage > serialized_varlen_buffer_
Definition: ResultSet.h:834
int64_t lazyReadInt(const int64_t ival, const size_t target_logical_idx, const StorageLookupResult &storage_lookup_result) const
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
T advance_target_ptr_row_wise(T target_ptr, const TargetInfo &target_info, const size_t slot_idx, const QueryMemoryDescriptor &query_mem_desc, const bool separate_varlen_storage)
#define CHECK_GT(x, y)
Definition: Logger.h:202
int64_t null_val_bit_pattern(const SQLTypeInfo &ti, const bool float_argument_input)
DEVICE void ChunkIter_get_nth(ChunkIter *it, int n, bool uncompress, VarlenDatum *result, bool *is_end)
Definition: ChunkIter.cpp:181
TargetValue build_array_target_value(const int8_t *buff, const size_t buff_sz, std::shared_ptr< RowSetMemoryOwner > row_set_mem_owner)
std::string to_string(char const *&&v)
std::vector< uint32_t > permutation_
Definition: ResultSet.h:811
SQLTypeInfo agg_arg_type
Definition: TargetInfo.h:43
const int local_col_id
Definition: ResultSet.h:224
int8_t * pointer
Definition: sqltypes.h:75
std::string get_type_name() const
Definition: sqltypes.h:429
const ResultSet * result_set_
Definition: ResultSet.h:692
std::vector< TargetValue > getRowAtNoTranslations(const size_t index, const std::vector< bool > &targets_to_skip={}) const
const int8_t * advance_col_buff_to_slot(const int8_t *buff, const QueryMemoryDescriptor &query_mem_desc, const std::vector< TargetInfo > &targets, const size_t slot_idx, const bool separate_varlen_storage)
Definition: sqldefs.h:71
Serialization routines for geospatial types.
static auto fetch(const ResultSet::GeoReturnType return_type, Data_Namespace::DataMgr *data_mgr, const bool fetch_data_from_gpu, const int device_id, T &&...vals)
const SQLTypeInfo get_compact_type(const TargetInfo &target)
size_t global_entry_idx_
Definition: ResultSet.h:267
InternalTargetValue getVarlenOrderEntry(const int64_t str_ptr, const size_t str_len) const
const std::vector< TargetInfo > targets_
Definition: ResultSet.h:800
int8_t groupColWidth(const size_t key_idx) const
const std::shared_ptr< RowSetMemoryOwner > row_set_mem_owner_
Definition: ResultSet.h:810
size_t get_bit_width(const SQLTypeInfo &ti)
size_t drop_first_
Definition: ResultSet.h:808
bool is_agg
Definition: TargetInfo.h:40
size_t advance_slot(const size_t j, const TargetInfo &target_info, const bool separate_varlen_storage)
CHECK(cgen_state)
bool is_array() const
Definition: sqltypes.h:485
static TargetValue build(const SQLTypeInfo &geo_ti, const ResultSet::GeoReturnType return_type, T &&...vals)
Classes representing a parse tree.
int64_t count_distinct_set_size(const int64_t set_handle, const CountDistinctDescriptor &count_distinct_desc)
Definition: CountDistinct.h:75
size_t getGroupbyColCount() const
void * checked_malloc(const size_t size)
Definition: checked_alloc.h:40
#define CHECK_NE(x, y)
Definition: Logger.h:199
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:326
size_t targetGroupbyIndicesSize() const
void copy_from_gpu(Data_Namespace::DataMgr *data_mgr, void *dst, const CUdeviceptr src, const size_t num_bytes, const int device_id)
boost::optional< std::vector< ScalarTargetValue >> ArrayTargetValue
Definition: TargetValue.h:157
DEVICE NEVER_INLINE int64_t SUFFIX() fixed_width_unsigned_decode_noinline(const int8_t *byte_stream, const int32_t byte_width, const int64_t pos)
Definition: DecodersImpl.h:90
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:333
CountDistinctDescriptors count_distinct_descriptors_
Definition: sqldefs.h:71
size_t getPaddedColWidthForRange(const size_t offset, const size_t range) const
StorageLookupResult findStorage(const size_t entry_idx) const
Definition: ResultSet.cpp:616
bool is_distinct_target(const TargetInfo &target_info)
Definition: TargetInfo.h:116
bool isNull() const
Definition: TargetValue.h:69
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
#define EMPTY_KEY_8
#define NULL_INT
Definition: sqltypes.h:176
const std::vector< ColumnLazyFetchInfo > lazy_fetch_info_
Definition: ResultSet.h:821
void copyColumnIntoBuffer(const size_t column_idx, int8_t *output_buffer, const size_t output_buffer_size) const
bool g_enable_smem_group_by true
SQLTypeInfoCore< ArrayContextTypeSizer, ExecutorTypePackaging, DateTimeFacilities > SQLTypeInfo
Definition: sqltypes.h:852
T row_ptr_rowwise(T buff, const QueryMemoryDescriptor &query_mem_desc, const size_t entry_idx)
SQLAgg agg_kind
Definition: TargetInfo.h:41
bool is_geometry() const
Definition: sqltypes.h:489
ssize_t getTargetGroupbyIndex(const size_t target_idx) const
QueryDescriptionType getQueryDescriptionType() const
SQLTypes decimal_to_int_type(const SQLTypeInfo &ti)
Definition: Datum.cpp:268
#define UNLIKELY(x)
Definition: likely.h:20
std::vector< TargetValue > getRowAt(const size_t index) const
const CountDistinctDescriptor & getCountDistinctDescriptor(const size_t idx) const
#define CHECK_LT(x, y)
Definition: Logger.h:200
bool is_real_str_or_array(const TargetInfo &target_info)
DEVICE NEVER_INLINE int64_t SUFFIX() fixed_width_small_date_decode_noinline(const int8_t *byte_stream, const int32_t byte_width, const int32_t null_val, const int64_t ret_null_val, const int64_t pos)
Definition: DecodersImpl.h:141
bool isSingleColumnGroupByWithPerfectHash() const
#define CHECK_LE(x, y)
Definition: Logger.h:201
int64_t int_resize_cast(const int64_t ival, const size_t sz)
static auto fetch(const ResultSet::GeoReturnType return_type, T &&...vals)
bool isGeoColOnGpu(const size_t col_idx) const
bool is_integer() const
Definition: sqltypes.h:479
#define EMPTY_KEY_16
std::vector< std::vector< std::vector< const int8_t * > > > col_buffers_
Definition: ResultSet.h:822
#define DEF_GET_ENTRY_AT(query_type, columnar_output)
bool isRowAtEmpty(const size_t index) const
size_t entryCount() const
boost::variant< std::string, void * > NullableString
Definition: TargetValue.h:155
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
static auto yieldGpuDatumFetcher(Data_Namespace::DataMgr *data_mgr_ptr, const int device_id)
const bool is_lazily_fetched
Definition: ResultSet.h:223
std::vector< std::vector< int64_t > > consistent_frag_sizes_
Definition: ResultSet.h:824
const ExecutorDeviceType device_type_
Definition: ResultSet.h:801
#define NULL_SMALLINT
Definition: sqltypes.h:175
std::vector< TargetValue > getNextRowImpl(const bool translate_strings, const bool decimal_to_double) const
bool isInt() const
Definition: TargetValue.h:65
bool is_string() const
Definition: sqltypes.h:477
bool g_enable_watchdog false
Definition: Execute.cpp:71
ScalarTargetValue make_scalar_tv(const T val)
size_t getBufferSizeBytes(const ExecutorDeviceType device_type) const
#define EMPTY_KEY_32
uint64_t exp_to_scale(const unsigned exp)
size_t crt_row_buff_idx_
Definition: ResultSet.h:806
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
int64_t inline_fixed_encoding_null_val(const SQL_TYPE_INFO &ti)
DEVICE NEVER_INLINE float SUFFIX() fixed_width_float_decode_noinline(const int8_t *byte_stream, const int64_t pos)
Definition: DecodersImpl.h:113
std::vector< std::vector< std::vector< int64_t > > > frag_offsets_
Definition: ResultSet.h:823
DEVICE NEVER_INLINE double SUFFIX() fixed_width_double_decode_noinline(const int8_t *byte_stream, const int64_t pos)
Definition: DecodersImpl.h:126
Basic constructors and methods of the row set interface.
bool separate_varlen_storage_valid_
Definition: ResultSet.h:835
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< std::pair< const int8_t *, const int64_t > > make_vals_vector(std::index_sequence< indices...>, const Tuple &tuple)
SQLTypeInfoCore get_elem_type() const
Definition: sqltypes.h:659
T advance_target_ptr_col_wise(T target_ptr, const TargetInfo &target_info, const size_t slot_idx, const QueryMemoryDescriptor &query_mem_desc, const bool separate_varlen_storage)
size_t advanceCursorToNextEntry() const
ENTRY_TYPE getColumnarBaselineEntryAt(const size_t row_idx, const size_t target_idx, const size_t slot_idx) const
bool is_decimal() const
Definition: sqltypes.h:480
Definition: sqldefs.h:71
size_t crt_row_buff_idx_
Definition: ResultSet.h:266
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:690
size_t getBufferColSlotCount() const
T get_cols_ptr(T buff, const QueryMemoryDescriptor &query_mem_desc)
const int8_t getLogicalSlotWidthBytes(const size_t slot_idx) const
Definition: sqldefs.h:71
bool global_entry_idx_valid_
Definition: ResultSet.h:268
std::unique_ptr< VarlenDatum > VarlenDatumPtr
#define IS_GEO(T)
Definition: sqltypes.h:167
bool isDirectColumnarConversionPossible() const
Definition: ResultSet.cpp:884
size_t get_key_bytes_rowwise(const QueryMemoryDescriptor &query_mem_desc)
const int8_t * columnar_elem_ptr(const size_t entry_idx, const int8_t *col1_ptr, const int8_t compact_sz1)
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
std::pair< int64_t, int64_t > get_frag_id_and_local_idx(const std::vector< std::vector< T >> &frag_offsets, const size_t tab_or_col_idx, const int64_t global_idx)
const std::vector< const int8_t * > & getColumnFrag(const size_t storge_idx, const size_t col_logical_idx, int64_t &global_idx) const
const Executor * getExecutor() const
std::conditional_t< isCudaCC(), DeviceArrayDatum, HostArrayDatum > ArrayDatum
Definition: sqltypes.h:122
std::unique_ptr< ArrayDatum > fetch_data_from_gpu(int64_t varlen_ptr, const int64_t length, Data_Namespace::DataMgr *data_mgr, const int device_id)
ENTRY_TYPE getRowWiseBaselineEntryAt(const size_t row_idx, const size_t target_idx, const size_t slot_idx) const
boost::variant< int64_t, double, float, NullableString > ScalarTargetValue
Definition: TargetValue.h:156
int32_t getTargetIdxForKey() const
size_t length
Definition: sqltypes.h:74
size_t getPrependedGroupColOffInBytes(const size_t group_idx) const
const int device_id_
Definition: ResultSet.h:802