OmniSciDB  04ee39c94c
ResultSetTestUtils.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 
17 #include "ResultSetTestUtils.h"
18 #include "../QueryEngine/ResultSetBufferAccessors.h"
19 
20 // TODO: move this into the ResultSet
21 int8_t* advance_to_next_columnar_key_buff(int8_t* key_ptr,
22  const QueryMemoryDescriptor& query_mem_desc,
23  const size_t key_idx) {
24  CHECK(!query_mem_desc.hasKeylessHash());
25  CHECK_LT(key_idx, query_mem_desc.groupColWidthsSize());
26  const auto column_offset =
27  query_mem_desc.getEntryCount() * query_mem_desc.groupColWidth(key_idx);
28  auto new_key_ptr = align_to_int64(key_ptr + column_offset);
29  return new_key_ptr;
30 }
31 
32 int64_t get_empty_key_sentinel(int8_t key_bytes) {
33  switch (key_bytes) {
34  case 8:
35  return EMPTY_KEY_64;
36  case 4:
37  return EMPTY_KEY_32;
38  case 2:
39  return EMPTY_KEY_16;
40  case 1:
41  return EMPTY_KEY_8;
42  default:
43  break;
44  }
45  UNREACHABLE();
46  return 0;
47 }
48 
49 void write_key(const int64_t k, int8_t* ptr, const int8_t key_bytes) {
50  switch (key_bytes) {
51  case 8: {
52  *reinterpret_cast<int64_t*>(ptr) = k;
53  break;
54  }
55  case 4: {
56  *reinterpret_cast<int32_t*>(ptr) = k;
57  break;
58  }
59  case 2: {
60  *reinterpret_cast<int16_t*>(ptr) = k;
61  break;
62  }
63  case 1: {
64  *reinterpret_cast<int8_t*>(ptr) = k;
65  break;
66  }
67  default:
68  CHECK(false);
69  }
70 }
71 
72 void write_int(int8_t* slot_ptr, const int64_t v, const size_t slot_bytes) {
73  switch (slot_bytes) {
74  case 4:
75  *reinterpret_cast<int32_t*>(slot_ptr) = v;
76  break;
77  case 8:
78  *reinterpret_cast<int64_t*>(slot_ptr) = v;
79  break;
80  default:
81  CHECK(false);
82  }
83 }
84 
85 void write_fp(int8_t* slot_ptr, const int64_t v, const size_t slot_bytes) {
86  switch (slot_bytes) {
87  case 4: {
88  float fi = v;
89  *reinterpret_cast<int32_t*>(slot_ptr) =
90  *reinterpret_cast<const int32_t*>(may_alias_ptr(&fi));
91  break;
92  }
93  case 8: {
94  double di = v;
95  *reinterpret_cast<int64_t*>(slot_ptr) =
96  *reinterpret_cast<const int64_t*>(may_alias_ptr(&di));
97  break;
98  }
99  default:
100  CHECK(false);
101  }
102 }
103 
104 int8_t* fill_one_entry_no_collisions(int8_t* buff,
105  const QueryMemoryDescriptor& query_mem_desc,
106  const int64_t v,
107  const std::vector<TargetInfo>& target_infos,
108  const bool empty,
109  const bool null_val /* = false */) {
110  size_t target_idx = 0;
111  int8_t* slot_ptr = buff;
112  int64_t vv = 0;
113  for (const auto& target_info : target_infos) {
114  const auto slot_bytes = query_mem_desc.getLogicalSlotWidthBytes(target_idx);
115  CHECK_LE(target_info.sql_type.get_size(), slot_bytes);
116  bool isNullable = !target_info.sql_type.get_notnull();
117  if (target_info.agg_kind == kCOUNT) {
118  if (empty || null_val) {
119  vv = 0;
120  } else {
121  vv = v;
122  }
123  } else {
124  if (isNullable && target_info.skip_null_val && null_val) {
125  vv = inline_int_null_val(target_info.sql_type);
126  } else {
127  vv = v;
128  }
129  }
130  if (empty) {
131  write_int(slot_ptr, query_mem_desc.hasKeylessHash() ? 0 : vv, slot_bytes);
132  } else {
133  if (target_info.sql_type.is_integer()) {
134  write_int(slot_ptr, vv, slot_bytes);
135  } else if (target_info.sql_type.is_string()) {
136  write_int(slot_ptr, -(vv + 2), slot_bytes);
137  } else {
138  CHECK(target_info.sql_type.is_fp());
139  write_fp(slot_ptr, vv, slot_bytes);
140  }
141  }
142  slot_ptr += slot_bytes;
143  if (target_info.agg_kind == kAVG) {
144  const auto count_slot_bytes =
145  query_mem_desc.getLogicalSlotWidthBytes(target_idx + 1);
146  if (empty) {
147  write_int(slot_ptr, query_mem_desc.hasKeylessHash() ? 0 : 0, count_slot_bytes);
148  } else {
149  if (isNullable && target_info.skip_null_val && null_val) {
150  write_int(slot_ptr, 0, count_slot_bytes); // count of elements should be set to
151  // 0 for elements with null_val
152  } else {
153  write_int(slot_ptr, 1, count_slot_bytes); // count of elements in the group is
154  // 1 - good enough for testing
155  }
156  }
157  slot_ptr += count_slot_bytes;
158  }
159  target_idx = advance_slot(target_idx, target_info, false);
160  }
161  return slot_ptr;
162 }
163 
164 void fill_one_entry_one_col(int8_t* ptr1,
165  const int8_t compact_sz1,
166  int8_t* ptr2,
167  const int8_t compact_sz2,
168  int64_t v,
169  const TargetInfo& target_info,
170  const bool empty_entry,
171  const bool null_val /* = false */) {
172  int64_t vv = 0;
173  if (target_info.agg_kind == kCOUNT) {
174  if (empty_entry || null_val) {
175  vv = 0;
176  } else {
177  vv = v;
178  }
179  } else {
180  bool isNullable = !target_info.sql_type.get_notnull();
181  if (isNullable && target_info.skip_null_val && null_val) {
182  vv = inline_int_null_val(target_info.sql_type);
183  } else {
184  if (empty_entry && (target_info.agg_kind == kAVG)) {
185  vv = 0;
186  } else {
187  vv = v;
188  }
189  }
190  }
191  CHECK(ptr1);
192  switch (compact_sz1) {
193  case 8:
194  if (target_info.sql_type.is_fp()) {
195  double di = vv;
196  *reinterpret_cast<int64_t*>(ptr1) =
197  *reinterpret_cast<const int64_t*>(may_alias_ptr(&di));
198  } else {
199  *reinterpret_cast<int64_t*>(ptr1) = vv;
200  }
201  break;
202  case 4:
203  if (target_info.sql_type.is_fp()) {
204  float fi = vv;
205  *reinterpret_cast<int32_t*>(ptr1) =
206  *reinterpret_cast<const int32_t*>(may_alias_ptr(&fi));
207  } else {
208  *reinterpret_cast<int32_t*>(ptr1) = vv;
209  }
210  break;
211  case 2:
212  CHECK(!target_info.sql_type.is_fp());
213  *reinterpret_cast<int16_t*>(ptr1) = vv;
214  break;
215  case 1:
216  CHECK(!target_info.sql_type.is_fp());
217  *reinterpret_cast<int8_t*>(ptr1) = vv;
218  break;
219  default:
220  CHECK(false);
221  }
222  if (target_info.is_agg && target_info.agg_kind == kAVG) {
223  CHECK(ptr2);
224  switch (compact_sz2) {
225  case 8:
226  *reinterpret_cast<int64_t*>(ptr2) = (empty_entry ? *ptr1 : 1);
227  break;
228  case 4:
229  *reinterpret_cast<int32_t*>(ptr2) = (empty_entry ? *ptr1 : 1);
230  break;
231  default:
232  CHECK(false);
233  }
234  }
235 }
236 
237 void fill_one_entry_one_col(int64_t* value_slot,
238  const int64_t v,
239  const TargetInfo& target_info,
240  const size_t entry_count,
241  const bool empty_entry /* = false */,
242  const bool null_val /* = false */) {
243  auto ptr1 = reinterpret_cast<int8_t*>(value_slot);
244  int8_t* ptr2{nullptr};
245  if (target_info.agg_kind == kAVG) {
246  ptr2 = reinterpret_cast<int8_t*>(&value_slot[entry_count]);
247  }
248  fill_one_entry_one_col(ptr1, 8, ptr2, 8, v, target_info, empty_entry, null_val);
249 }
250 
252  const std::vector<TargetInfo>& target_infos,
253  const QueryMemoryDescriptor& query_mem_desc,
254  NumberGenerator& generator,
255  const size_t step) {
256  const auto key_component_count = query_mem_desc.getKeyCount();
257  CHECK(query_mem_desc.didOutputColumnar());
258  // initialize the key buffer(s)
259  auto col_ptr = buff;
260  for (size_t key_idx = 0; key_idx < key_component_count; ++key_idx) {
261  auto key_entry_ptr = col_ptr;
262  const auto key_bytes = query_mem_desc.groupColWidth(key_idx);
263 
264  for (size_t i = 0; i < query_mem_desc.getEntryCount(); ++i) {
265  if (i % step == 0) {
266  const auto v = generator.getNextValue();
267  write_key(v, key_entry_ptr, key_bytes);
268  } else {
269  write_key(get_empty_key_sentinel(key_bytes), key_entry_ptr, key_bytes);
270  }
271  key_entry_ptr += key_bytes;
272  }
273  col_ptr = advance_to_next_columnar_key_buff(col_ptr, query_mem_desc, key_idx);
274  generator.reset();
275  }
276  // initialize the value buffer(s)
277  size_t slot_idx = 0;
278  for (const auto& target_info : target_infos) {
279  auto col_entry_ptr = col_ptr;
280  const auto col_bytes = query_mem_desc.getPaddedSlotWidthBytes(slot_idx);
281  for (size_t i = 0; i < query_mem_desc.getEntryCount(); ++i) {
282  int8_t* ptr2{nullptr};
283  const bool read_secondary_buffer{target_info.is_agg &&
284  target_info.agg_kind == kAVG};
285  if (read_secondary_buffer) {
286  ptr2 = col_entry_ptr + query_mem_desc.getEntryCount() * col_bytes;
287  }
288  if (i % step == 0) {
289  const auto gen_val = generator.getNextValue();
290  const auto val = target_info.sql_type.is_string() ? -(gen_val + 2) : gen_val;
291  fill_one_entry_one_col(col_entry_ptr,
292  col_bytes,
293  ptr2,
294  read_secondary_buffer
295  ? query_mem_desc.getPaddedSlotWidthBytes(slot_idx + 1)
296  : -1,
297  val,
298  target_info,
299  false);
300  } else {
301  fill_one_entry_one_col(col_entry_ptr,
302  col_bytes,
303  ptr2,
304  read_secondary_buffer
305  ? query_mem_desc.getPaddedSlotWidthBytes(slot_idx + 1)
306  : -1,
307  query_mem_desc.hasKeylessHash() ? 0 : 0xdeadbeef,
308  target_info,
309  true);
310  }
311  col_entry_ptr += col_bytes;
312  }
313  col_ptr = advance_to_next_columnar_target_buff(col_ptr, query_mem_desc, slot_idx);
314  if (target_info.is_agg && target_info.agg_kind == kAVG) {
315  col_ptr =
316  advance_to_next_columnar_target_buff(col_ptr, query_mem_desc, slot_idx + 1);
317  }
318  slot_idx = advance_slot(slot_idx, target_info, false);
319  generator.reset();
320  }
321 }
322 
324  const std::vector<TargetInfo>& target_infos,
325  const QueryMemoryDescriptor& query_mem_desc,
326  NumberGenerator& generator,
327  const size_t step) {
328  const auto key_component_count = query_mem_desc.getKeyCount();
329  CHECK(!query_mem_desc.didOutputColumnar());
330  auto key_buff = buff;
331  for (size_t i = 0; i < query_mem_desc.getEntryCount(); ++i) {
332  if (i % step == 0) {
333  const auto v = generator.getNextValue();
334  auto key_buff_i64 = reinterpret_cast<int64_t*>(key_buff);
335  for (size_t key_comp_idx = 0; key_comp_idx < key_component_count; ++key_comp_idx) {
336  *key_buff_i64++ = v;
337  }
338  auto entries_buff = reinterpret_cast<int8_t*>(key_buff_i64);
339  key_buff = fill_one_entry_no_collisions(
340  entries_buff, query_mem_desc, v, target_infos, false);
341  } else {
342  auto key_buff_i64 = reinterpret_cast<int64_t*>(key_buff);
343  for (size_t key_comp_idx = 0; key_comp_idx < key_component_count; ++key_comp_idx) {
344  *key_buff_i64++ = EMPTY_KEY_64;
345  }
346  auto entries_buff = reinterpret_cast<int8_t*>(key_buff_i64);
347  key_buff = fill_one_entry_no_collisions(
348  entries_buff, query_mem_desc, 0xdeadbeef, target_infos, true);
349  }
350  }
351 }
352 
354  const std::vector<TargetInfo>& target_infos,
355  const QueryMemoryDescriptor& query_mem_desc,
356  NumberGenerator& generator,
357  const size_t step) {
358  CHECK(query_mem_desc.didOutputColumnar());
359  const auto key_component_count = query_mem_desc.getKeyCount();
360  const auto i64_buff = reinterpret_cast<int64_t*>(buff);
361  const auto target_slot_count = get_slot_count(target_infos);
362  const auto slot_to_target = get_slot_to_target_mapping(target_infos);
363  for (size_t i = 0; i < query_mem_desc.getEntryCount(); ++i) {
364  for (size_t key_comp_idx = 0; key_comp_idx < key_component_count; ++key_comp_idx) {
365  i64_buff[key_offset_colwise(i, key_comp_idx, query_mem_desc.getEntryCount())] =
366  EMPTY_KEY_64;
367  }
368  for (size_t target_slot = 0; target_slot < target_slot_count; ++target_slot) {
369  auto target_it = slot_to_target.find(target_slot);
370  CHECK(target_it != slot_to_target.end());
371  const auto& target_info = target_infos[target_it->second];
372  i64_buff[slot_offset_colwise(
373  i, target_slot, key_component_count, query_mem_desc.getEntryCount())] =
374  (target_info.agg_kind == kCOUNT ? 0 : 0xdeadbeef);
375  }
376  }
377  for (size_t i = 0; i < query_mem_desc.getEntryCount(); i += step) {
378  const auto gen_val = generator.getNextValue();
379  std::vector<int64_t> key(key_component_count, gen_val);
380  auto value_slots = get_group_value_columnar(
381  i64_buff, query_mem_desc.getEntryCount(), &key[0], key.size());
382  CHECK(value_slots);
383  for (const auto& target_info : target_infos) {
384  const auto val = target_info.sql_type.is_string() ? -(gen_val + step) : gen_val;
386  value_slots, val, target_info, query_mem_desc.getEntryCount());
387  value_slots += query_mem_desc.getEntryCount();
388  if (target_info.agg_kind == kAVG) {
389  value_slots += query_mem_desc.getEntryCount();
390  }
391  }
392  }
393 }
394 
396  const std::vector<TargetInfo>& target_infos,
397  const QueryMemoryDescriptor& query_mem_desc,
398  NumberGenerator& generator,
399  const size_t step) {
400  const auto key_component_count = query_mem_desc.getKeyCount();
401  const auto i64_buff = reinterpret_cast<int64_t*>(buff);
402  const auto target_slot_count = get_slot_count(target_infos);
403  const auto slot_to_target = get_slot_to_target_mapping(target_infos);
404  for (size_t i = 0; i < query_mem_desc.getEntryCount(); ++i) {
405  const auto first_key_comp_offset =
406  key_offset_rowwise(i, key_component_count, target_slot_count);
407  for (size_t key_comp_idx = 0; key_comp_idx < key_component_count; ++key_comp_idx) {
408  i64_buff[first_key_comp_offset + key_comp_idx] = EMPTY_KEY_64;
409  }
410  for (size_t target_slot = 0; target_slot < target_slot_count; ++target_slot) {
411  auto target_it = slot_to_target.find(target_slot);
412  CHECK(target_it != slot_to_target.end());
413  const auto& target_info = target_infos[target_it->second];
414  i64_buff[slot_offset_rowwise(
415  i, target_slot, key_component_count, target_slot_count)] =
416  (target_info.agg_kind == kCOUNT ? 0 : 0xdeadbeef);
417  }
418  }
419  for (size_t i = 0; i < query_mem_desc.getEntryCount(); i += step) {
420  const auto v = generator.getNextValue();
421  std::vector<int64_t> key(key_component_count, v);
422  auto value_slots = get_group_value(i64_buff,
423  query_mem_desc.getEntryCount(),
424  &key[0],
425  key.size(),
426  sizeof(int64_t),
427  key_component_count + target_slot_count,
428  nullptr);
429  CHECK(value_slots);
430  fill_one_entry_baseline(value_slots, v, target_infos);
431  }
432 }
433 
434 void fill_storage_buffer(int8_t* buff,
435  const std::vector<TargetInfo>& target_infos,
436  const QueryMemoryDescriptor& query_mem_desc,
437  NumberGenerator& generator,
438  const size_t step) {
439  switch (query_mem_desc.getQueryDescriptionType()) {
441  if (query_mem_desc.didOutputColumnar()) {
443  buff, target_infos, query_mem_desc, generator, step);
444  } else {
446  buff, target_infos, query_mem_desc, generator, step);
447  }
448  break;
449  }
451  if (query_mem_desc.didOutputColumnar()) {
453  buff, target_infos, query_mem_desc, generator, step);
454  } else {
456  buff, target_infos, query_mem_desc, generator, step);
457  }
458  break;
459  }
460  default:
461  CHECK(false);
462  }
463  CHECK(buff);
464 }
465 
466 // TODO(alex): allow 4 byte keys
467 
468 /* descriptor with small entry_count to simplify testing and debugging */
470  const std::vector<TargetInfo>& target_infos,
471  const int8_t num_bytes) {
472  QueryMemoryDescriptor query_mem_desc(
473  QueryDescriptionType::GroupByPerfectHash, 0, 19, false, {8});
474  for (const auto& target_info : target_infos) {
475  const auto slot_bytes =
476  std::max(num_bytes, static_cast<int8_t>(target_info.sql_type.get_size()));
477  std::vector<std::tuple<int8_t, int8_t>> slots_for_target;
478  if (target_info.agg_kind == kAVG) {
479  CHECK(target_info.is_agg);
480  slots_for_target.emplace_back(std::make_tuple(slot_bytes, slot_bytes));
481  }
482  slots_for_target.emplace_back(std::make_tuple(slot_bytes, slot_bytes));
483  query_mem_desc.addColSlotInfo(slots_for_target);
484  }
485  query_mem_desc.setEntryCount(query_mem_desc.getMaxVal() - query_mem_desc.getMinVal() +
486  1);
487  return query_mem_desc;
488 }
489 
491  const std::vector<TargetInfo>& target_infos,
492  const int8_t num_bytes,
493  const size_t min_val,
494  const size_t max_val,
495  std::vector<int8_t> group_column_widths) {
497  min_val,
498  max_val,
499  false,
500  group_column_widths);
501  for (const auto& target_info : target_infos) {
502  const auto slot_bytes =
503  std::max(num_bytes, static_cast<int8_t>(target_info.sql_type.get_size()));
504  std::vector<std::tuple<int8_t, int8_t>> slots_for_target;
505  if (target_info.agg_kind == kAVG) {
506  CHECK(target_info.is_agg);
507  slots_for_target.emplace_back(std::make_tuple(slot_bytes, slot_bytes));
508  }
509  slots_for_target.emplace_back(std::make_tuple(slot_bytes, slot_bytes));
510  if (target_info.sql_type.is_geometry()) {
511  for (int i = 1; i < 2 * target_info.sql_type.get_physical_coord_cols(); i++) {
512  slots_for_target.emplace_back(std::make_tuple(slot_bytes, slot_bytes));
513  }
514  } else if (target_info.sql_type.is_varlen()) {
515  slots_for_target.emplace_back(std::make_tuple(slot_bytes, slot_bytes));
516  }
517  query_mem_desc.addColSlotInfo(slots_for_target);
518  }
519  query_mem_desc.setEntryCount(query_mem_desc.getMaxVal() - query_mem_desc.getMinVal() +
520  1);
521  return query_mem_desc;
522 }
523 
525  const std::vector<TargetInfo>& target_infos,
526  const int8_t num_bytes) {
527  QueryMemoryDescriptor query_mem_desc(
528  QueryDescriptionType::GroupByPerfectHash, 0, 36, false, {8, 8});
529  for (const auto& target_info : target_infos) {
530  const auto slot_bytes =
531  std::max(num_bytes, static_cast<int8_t>(target_info.sql_type.get_size()));
532  std::vector<std::tuple<int8_t, int8_t>> slots_for_target;
533  if (target_info.agg_kind == kAVG) {
534  CHECK(target_info.is_agg);
535  slots_for_target.emplace_back(std::make_tuple(slot_bytes, slot_bytes));
536  }
537  slots_for_target.emplace_back(std::make_tuple(slot_bytes, slot_bytes));
538  query_mem_desc.addColSlotInfo(slots_for_target);
539  }
540  query_mem_desc.setEntryCount(query_mem_desc.getMaxVal());
541  return query_mem_desc;
542 }
543 
545  const std::vector<TargetInfo>& target_infos,
546  const int8_t num_bytes) {
547  QueryMemoryDescriptor query_mem_desc(
548  QueryDescriptionType::GroupByBaselineHash, 0, 19, false, {8, 8});
549  for (const auto& target_info : target_infos) {
550  const auto slot_bytes =
551  std::max(num_bytes, static_cast<int8_t>(target_info.sql_type.get_size()));
552  std::vector<std::tuple<int8_t, int8_t>> slots_for_target;
553  if (target_info.agg_kind == kAVG) {
554  CHECK(target_info.is_agg);
555  slots_for_target.emplace_back(std::make_tuple(slot_bytes, slot_bytes));
556  }
557  slots_for_target.emplace_back(std::make_tuple(slot_bytes, slot_bytes));
558  query_mem_desc.addColSlotInfo(slots_for_target);
559  }
560  query_mem_desc.setEntryCount(query_mem_desc.getMaxVal() - query_mem_desc.getMinVal() +
561  1);
562  return query_mem_desc;
563 }
564 
566  const std::vector<TargetInfo>& target_infos,
567  const int8_t num_bytes) {
568  QueryMemoryDescriptor query_mem_desc(
569  QueryDescriptionType::GroupByBaselineHash, 0, 3, false, {8, 8});
570  for (const auto& target_info : target_infos) {
571  const auto slot_bytes =
572  std::max(num_bytes, static_cast<int8_t>(target_info.sql_type.get_size()));
573  std::vector<std::tuple<int8_t, int8_t>> slots_for_target;
574  if (target_info.agg_kind == kAVG) {
575  CHECK(target_info.is_agg);
576  slots_for_target.emplace_back(std::make_tuple(slot_bytes, slot_bytes));
577  }
578  slots_for_target.emplace_back(std::make_tuple(slot_bytes, slot_bytes));
579  query_mem_desc.addColSlotInfo(slots_for_target);
580  }
581  query_mem_desc.setEntryCount(query_mem_desc.getMaxVal() - query_mem_desc.getMinVal() +
582  1);
583  return query_mem_desc;
584 }
585 
586 void fill_one_entry_baseline(int64_t* value_slots,
587  const int64_t v,
588  const std::vector<TargetInfo>& target_infos,
589  const bool empty /* = false */,
590  const bool null_val /* = false */) {
591  size_t target_slot = 0;
592  int64_t vv = 0;
593  for (const auto& target_info : target_infos) {
594  const bool float_argument_input = takes_float_argument(target_info);
595  if (target_info.agg_kind == kCOUNT) {
596  if (empty || null_val) {
597  vv = 0;
598  } else {
599  vv = v;
600  }
601  } else {
602  bool isNullable = !target_info.sql_type.get_notnull();
603  if ((isNullable && target_info.skip_null_val && null_val) || empty) {
604  vv = null_val_bit_pattern(target_info.sql_type, float_argument_input);
605  } else {
606  vv = v;
607  }
608  }
609 
610  switch (target_info.sql_type.get_type()) {
611  case kSMALLINT:
612  case kINT:
613  case kBIGINT:
614  value_slots[target_slot] = vv;
615  break;
616  case kFLOAT:
617  if (float_argument_input) {
618  float fi = vv;
619  int64_t fi_bin = *reinterpret_cast<const int32_t*>(may_alias_ptr(&fi));
620  value_slots[target_slot] = null_val ? vv : fi_bin;
621  break;
622  }
623  case kDOUBLE: {
624  double di = vv;
625  value_slots[target_slot] =
626  null_val ? vv : *reinterpret_cast<const int64_t*>(may_alias_ptr(&di));
627  break;
628  }
629  case kTEXT:
630  value_slots[target_slot] = -(vv + 2);
631  break;
632  default:
633  CHECK(false);
634  }
635  if (target_info.agg_kind == kAVG) {
636  value_slots[target_slot + 1] = 1;
637  }
638  target_slot = advance_slot(target_slot, target_info, false);
639  }
640 }
641 
642 size_t get_slot_count(const std::vector<TargetInfo>& target_infos) {
643  size_t count = 0;
644  for (const auto& target_info : target_infos) {
645  count = advance_slot(count, target_info, false);
646  }
647  return count;
648 }
649 
650 std::vector<TargetInfo> generate_custom_agg_target_infos(
651  std::vector<int8_t> group_columns,
652  std::vector<SQLAgg> sql_aggs,
653  std::vector<SQLTypes> agg_types,
654  std::vector<SQLTypes> arg_types) {
655  const auto num_targets = sql_aggs.size();
656  CHECK_EQ(agg_types.size(), num_targets);
657  CHECK_EQ(arg_types.size(), num_targets);
658  std::vector<TargetInfo> target_infos;
659  target_infos.reserve(group_columns.size() + num_targets);
660  auto find_group_col_type = [](int8_t group_width) {
661  switch (group_width) {
662  case 8:
663  return kBIGINT;
664  case 4:
665  return kINT;
666  case 2:
667  return kSMALLINT;
668  case 1:
669  return kTINYINT;
670  default:
671  UNREACHABLE();
672  }
673  UNREACHABLE();
674  return kINT;
675  };
676  // creating proper TargetInfo to represent group columns:
677  for (auto group_size : group_columns) {
678  target_infos.push_back(TargetInfo{false,
679  kMIN,
680  SQLTypeInfo{find_group_col_type(group_size), false},
681  SQLTypeInfo{kNULLT, false},
682  true,
683  false});
684  }
685  // creating proper TargetInfo for aggregate columns:
686  for (size_t i = 0; i < num_targets; i++) {
687  target_infos.push_back(TargetInfo{true,
688  sql_aggs[i],
689  SQLTypeInfo{agg_types[i], false},
690  SQLTypeInfo{arg_types[i], false},
691  true,
692  false});
693  }
694  return target_infos;
695 }
696 
697 std::unordered_map<size_t, size_t> get_slot_to_target_mapping(
698  const std::vector<TargetInfo>& target_infos) {
699  std::unordered_map<size_t, size_t> mapping;
700  size_t target_index = 0;
701  size_t slot_index = 0;
702  for (const auto& target_info : target_infos) {
703  mapping.insert(std::make_pair(slot_index, target_index));
704  auto old_slot_index = slot_index;
705  slot_index = advance_slot(slot_index, target_info, false);
706  if (slot_index == old_slot_index + 2) {
707  mapping.insert(std::make_pair(old_slot_index + 1, target_index));
708  }
709  target_index++;
710  }
711  return mapping;
712 }
size_t slot_offset_rowwise(const size_t entry_idx, const size_t slot_idx, const size_t key_count, const size_t slot_count)
#define CHECK_EQ(x, y)
Definition: Logger.h:195
NEVER_INLINE DEVICE int64_t * get_group_value_columnar(int64_t *groups_buffer, const uint32_t groups_buffer_entry_count, const int64_t *key, const uint32_t key_qw_count)
#define EMPTY_KEY_64
bool is_fp() const
Definition: sqltypes.h:454
void setEntryCount(const size_t val)
QueryMemoryDescriptor perfect_hash_one_col_desc_small(const std::vector< TargetInfo > &target_infos, const int8_t num_bytes)
size_t slot_offset_colwise(const size_t entry_idx, const size_t slot_idx, const size_t key_count, const size_t entry_count)
void fill_one_entry_one_col(int8_t *ptr1, const int8_t compact_sz1, int8_t *ptr2, const int8_t compact_sz2, int64_t v, const TargetInfo &target_info, const bool empty_entry, const bool null_val)
void fill_storage_buffer_perfect_hash_colwise(int8_t *buff, const std::vector< TargetInfo > &target_infos, const QueryMemoryDescriptor &query_mem_desc, NumberGenerator &generator, const size_t step)
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
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:330
std::unordered_map< size_t, size_t > get_slot_to_target_mapping(const std::vector< TargetInfo > &target_infos)
#define UNREACHABLE()
Definition: Logger.h:231
void write_fp(int8_t *slot_ptr, const int64_t v, const size_t slot_bytes)
int8_t * advance_to_next_columnar_key_buff(int8_t *key_ptr, const QueryMemoryDescriptor &query_mem_desc, const size_t key_idx)
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:120
QueryMemoryDescriptor baseline_hash_two_col_desc_large(const std::vector< TargetInfo > &target_infos, const int8_t num_bytes)
bool skip_null_val
Definition: TargetInfo.h:44
int64_t null_val_bit_pattern(const SQLTypeInfo &ti, const bool float_argument_input)
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
size_t get_slot_count(const std::vector< TargetInfo > &target_infos)
Definition: sqldefs.h:71
QueryMemoryDescriptor perfect_hash_one_col_desc(const std::vector< TargetInfo > &target_infos, const int8_t num_bytes, const size_t min_val, const size_t max_val, std::vector< int8_t > group_column_widths)
bool is_agg
Definition: TargetInfo.h:40
size_t advance_slot(const size_t j, const TargetInfo &target_info, const bool separate_varlen_storage)
T v(const TargetValue &r)
void fill_storage_buffer_baseline_rowwise(int8_t *buff, const std::vector< TargetInfo > &target_infos, const QueryMemoryDescriptor &query_mem_desc, NumberGenerator &generator, const size_t step)
void fill_storage_buffer_baseline_colwise(int8_t *buff, const std::vector< TargetInfo > &target_infos, const QueryMemoryDescriptor &query_mem_desc, NumberGenerator &generator, const size_t step)
int64_t get_empty_key_sentinel(int8_t key_bytes)
NEVER_INLINE DEVICE int64_t * get_group_value(int64_t *groups_buffer, const uint32_t groups_buffer_entry_count, const int64_t *key, const uint32_t key_count, const uint32_t key_width, const uint32_t row_size_quad, const int64_t *init_vals)
#define EMPTY_KEY_8
virtual void reset()=0
SQLAgg agg_kind
Definition: TargetInfo.h:41
size_t key_offset_colwise(const size_t entry_idx, const size_t key_idx, const size_t entry_count)
int8_t groupColWidth(const size_t key_idx) const
int8_t * fill_one_entry_no_collisions(int8_t *buff, const QueryMemoryDescriptor &query_mem_desc, const int64_t v, const std::vector< TargetInfo > &target_infos, const bool empty, const bool null_val)
#define CHECK_LT(x, y)
Definition: Logger.h:197
Definition: sqltypes.h:54
#define CHECK_LE(x, y)
Definition: Logger.h:198
void write_int(int8_t *slot_ptr, const int64_t v, const size_t slot_bytes)
Definition: sqldefs.h:71
#define EMPTY_KEY_16
size_t key_offset_rowwise(const size_t entry_idx, const size_t key_count, const size_t slot_count)
QueryMemoryDescriptor perfect_hash_two_col_desc(const std::vector< TargetInfo > &target_infos, const int8_t num_bytes)
#define CHECK(condition)
Definition: Logger.h:187
void fill_one_entry_baseline(int64_t *value_slots, const int64_t v, const std::vector< TargetInfo > &target_infos, const bool empty, const bool null_val)
#define EMPTY_KEY_32
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
const int8_t getLogicalSlotWidthBytes(const size_t slot_idx) const
Definition: sqltypes.h:47
virtual int64_t getNextValue()=0
void addColSlotInfo(const std::vector< std::tuple< int8_t, int8_t >> &slots_for_col)
QueryDescriptionType getQueryDescriptionType() const
Definition: sqldefs.h:71
FORCE_INLINE HOST DEVICE T align_to_int64(T addr)
std::vector< TargetInfo > generate_custom_agg_target_infos(std::vector< int8_t > group_columns, std::vector< SQLAgg > sql_aggs, std::vector< SQLTypes > agg_types, std::vector< SQLTypes > arg_types)
void write_key(const int64_t k, int8_t *ptr, const int8_t key_bytes)
QueryMemoryDescriptor baseline_hash_two_col_desc(const std::vector< TargetInfo > &target_infos, const int8_t num_bytes)
void fill_storage_buffer(int8_t *buff, const std::vector< TargetInfo > &target_infos, const QueryMemoryDescriptor &query_mem_desc, NumberGenerator &generator, const size_t step)
void fill_storage_buffer_perfect_hash_rowwise(int8_t *buff, const std::vector< TargetInfo > &target_infos, const QueryMemoryDescriptor &query_mem_desc, NumberGenerator &generator, const size_t step)