OmniSciDB  c1a53651b2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ResultSetBufferAccessors.h
Go to the documentation of this file.
1 /*
2  * Copyright 2022 HEAVY.AI, 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 
23 #ifndef QUERYENGINE_RESULTSETBUFFERACCESSORS_H
24 #define QUERYENGINE_RESULTSETBUFFERACCESSORS_H
25 
26 #include "BufferCompaction.h"
27 #include "Shared/SqlTypesLayout.h"
28 #include "Shared/misc.h"
29 #include "TypePunning.h"
30 
31 #ifndef __CUDACC__
32 
34 
35 #include <algorithm>
36 
37 inline bool is_real_str_or_array(const TargetInfo& target_info) {
38  return (!target_info.is_agg || target_info.agg_kind == kSAMPLE) &&
39  (target_info.sql_type.is_array() ||
40  (target_info.sql_type.is_string() &&
41  target_info.sql_type.get_compression() == kENCODING_NONE));
42 }
43 
44 inline size_t get_slots_for_geo_target(const TargetInfo& target_info,
45  const bool separate_varlen_storage) {
46  // Aggregates on geospatial types are serialized directly by rewriting the underlying
47  // buffer. Even if separate varlen storage is valid, treat aggregates the same on
48  // distributed and single node
49  if (target_info.is_varlen_projection ||
50  (separate_varlen_storage && !target_info.is_agg)) {
51  return 1;
52  } else {
53  return 2 * target_info.sql_type.get_physical_coord_cols();
54  }
55 }
56 
57 inline size_t get_slots_for_target(const TargetInfo& target_info,
58  const bool separate_varlen_storage) {
59  if (target_info.is_agg) {
60  if (target_info.agg_kind == kAVG || is_real_str_or_array(target_info)) {
61  return 2;
62  } else {
63  return 1;
64  }
65  } else {
66  if (is_real_str_or_array(target_info) && !separate_varlen_storage) {
67  return 2;
68  } else {
69  return 1;
70  }
71  }
72 }
73 
74 inline size_t advance_slot(const size_t j,
75  const TargetInfo& target_info,
76  const bool separate_varlen_storage) {
77  if (target_info.sql_type.is_geometry()) {
78  return j + get_slots_for_geo_target(target_info, separate_varlen_storage);
79  }
80  return j + get_slots_for_target(target_info, separate_varlen_storage);
81 }
82 
83 inline size_t slot_offset_rowwise(const size_t entry_idx,
84  const size_t slot_idx,
85  const size_t key_count,
86  const size_t slot_count) {
87  return (key_count + slot_count) * entry_idx + (key_count + slot_idx);
88 }
89 
90 inline size_t slot_offset_colwise(const size_t entry_idx,
91  const size_t slot_idx,
92  const size_t key_count,
93  const size_t entry_count) {
94  return (key_count + slot_idx) * entry_count + entry_idx;
95 }
96 
97 inline size_t key_offset_rowwise(const size_t entry_idx,
98  const size_t key_count,
99  const size_t slot_count) {
100  return (key_count + slot_count) * entry_idx;
101 }
102 
103 inline size_t key_offset_colwise(const size_t entry_idx,
104  const size_t key_idx,
105  const size_t entry_count) {
106  return key_idx * entry_count + entry_idx;
107 }
108 
109 template <class T>
112  const size_t target_slot_idx) {
113  auto new_target_ptr = target_ptr;
114  const auto column_size = query_mem_desc.getEntryCount() *
115  query_mem_desc.getPaddedSlotWidthBytes(target_slot_idx);
116  new_target_ptr += align_to_int64(column_size);
117 
118  return new_target_ptr;
119 }
120 
121 template <class T>
123  CHECK(query_mem_desc.didOutputColumnar());
124  return buff + query_mem_desc.getColOffInBytes(0);
125 }
126 
128  if (query_mem_desc.hasKeylessHash()) {
129  return 0;
130  }
131  auto consist_key_width = query_mem_desc.getEffectiveKeyWidth();
132  CHECK(consist_key_width);
133  return consist_key_width * query_mem_desc.getGroupbyColCount();
134 }
135 
137  size_t result = align_to_int64(get_key_bytes_rowwise(query_mem_desc)); // plus padding
138  return result + query_mem_desc.getRowWidth();
139 }
140 
141 template <class T>
142 inline T row_ptr_rowwise(T buff,
144  const size_t entry_idx) {
145  const auto row_bytes = get_row_bytes(query_mem_desc);
146  return buff + entry_idx * row_bytes;
147 }
148 
149 template <class T>
150 inline T advance_target_ptr_row_wise(T target_ptr,
151  const TargetInfo& target_info,
152  const size_t slot_idx,
154  const bool separate_varlen_storage) {
155  auto result = target_ptr + query_mem_desc.getPaddedSlotWidthBytes(slot_idx);
156  if ((target_info.is_agg && target_info.agg_kind == kAVG) ||
157  ((!separate_varlen_storage || target_info.is_agg) &&
158  is_real_str_or_array(target_info))) {
159  return result + query_mem_desc.getPaddedSlotWidthBytes(slot_idx + 1);
160  }
161  const bool is_varlen_output_slot = query_mem_desc.slotIsVarlenOutput(slot_idx);
162  if (target_info.sql_type.is_geometry() &&
163  (!separate_varlen_storage || target_info.is_agg) && !is_varlen_output_slot) {
164  for (auto i = 1; i < 2 * target_info.sql_type.get_physical_coord_cols(); ++i) {
165  result += query_mem_desc.getPaddedSlotWidthBytes(slot_idx + i);
166  }
167  }
168  return result;
169 }
170 
171 template <class T>
172 inline T advance_target_ptr_col_wise(T target_ptr,
173  const TargetInfo& target_info,
174  const size_t slot_idx,
176  const bool separate_varlen_storage) {
177  auto result =
178  advance_to_next_columnar_target_buff(target_ptr, query_mem_desc, slot_idx);
179  if ((target_info.is_agg && target_info.agg_kind == kAVG) ||
180  (is_real_str_or_array(target_info) && !separate_varlen_storage)) {
181  return advance_to_next_columnar_target_buff(result, query_mem_desc, slot_idx + 1);
182  } else if (target_info.sql_type.is_geometry() && !separate_varlen_storage) {
183  // TODO: handle varlen projection
184  for (auto i = 1; i < 2 * target_info.sql_type.get_physical_coord_cols(); ++i) {
185  result = advance_to_next_columnar_target_buff(result, query_mem_desc, slot_idx + i);
186  }
187  return result;
188  } else {
189  return result;
190  }
191 }
192 
194  return align_to_int64(get_key_bytes_rowwise(query_mem_desc)) / sizeof(int64_t);
195 }
196 
197 #endif // __CUDACC__
198 
199 inline double pair_to_double(const std::pair<int64_t, int64_t>& fp_pair,
200  const SQLTypeInfo& ti,
201  const bool float_argument_input) {
202  if (fp_pair.second == 0) {
203  return NULL_DOUBLE;
204  }
205  double dividend{0.0};
206  switch (ti.get_type()) {
207  case kFLOAT:
208  if (float_argument_input) {
209  dividend = shared::reinterpret_bits<float>(fp_pair.first);
210  break;
211  }
212  case kDOUBLE:
213  dividend = shared::reinterpret_bits<double>(fp_pair.first);
214  break;
215  default:
216 #ifndef __CUDACC__
217  LOG_IF(FATAL, !(ti.is_integer() || ti.is_decimal()))
218  << "Unsupported type for pair to double conversion: " << ti.get_type_name();
219 #else
220  CHECK(ti.is_integer() || ti.is_decimal());
221 #endif
222  dividend = static_cast<double>(fp_pair.first);
223  break;
224  }
225  return ti.is_decimal() && ti.get_scale()
226  ? dividend /
227  (static_cast<double>(fp_pair.second) * exp_to_scale(ti.get_scale()))
228  : dividend / static_cast<double>(fp_pair.second);
229 }
230 
231 inline int64_t null_val_bit_pattern(const SQLTypeInfo& ti,
232  const bool float_argument_input) {
233  if (ti.is_fp()) {
234  if (float_argument_input && ti.get_type() == kFLOAT) {
235  return shared::reinterpret_bits<int64_t>(NULL_FLOAT); // 1<<23
236  }
237  const auto double_null_val = inline_fp_null_val(ti);
238  return shared::reinterpret_bits<int64_t>(double_null_val); // 0x381<<52 or 1<<52
239  }
240  if ((ti.is_string() && ti.get_compression() == kENCODING_NONE) || ti.is_array() ||
241  ti.is_geometry()) {
242  return 0;
243  }
244  return inline_int_null_val(ti);
245 }
246 
247 // Interprets ptr as an integer of compact_sz byte width and reads it.
248 inline int64_t read_int_from_buff(const int8_t* ptr, const int8_t compact_sz) {
249  switch (compact_sz) {
250  case 8: {
251  return *reinterpret_cast<const int64_t*>(ptr);
252  }
253  case 4: {
254  return *reinterpret_cast<const int32_t*>(ptr);
255  }
256  case 2: {
257  return *reinterpret_cast<const int16_t*>(ptr);
258  }
259  case 1: {
260  return *reinterpret_cast<const int8_t*>(ptr);
261  }
262  default:
263  UNREACHABLE();
264  }
265  UNREACHABLE();
266  return 0;
267 }
268 
269 #endif // QUERYENGINE_RESULTSETBUFFERACCESSORS_H
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)
bool slotIsVarlenOutput(const size_t slot_idx) const
#define NULL_DOUBLE
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)
#define NULL_FLOAT
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:52
bool is_fp() const
Definition: sqltypes.h:584
HOST DEVICE int get_scale() const
Definition: sqltypes.h:386
#define UNREACHABLE()
Definition: Logger.h:337
Macros and functions for groupby buffer compaction.
size_t get_slot_off_quad(const QueryMemoryDescriptor &query_mem_desc)
size_t getEffectiveKeyWidth() const
int64_t read_int_from_buff(const int8_t *ptr, const int8_t compact_sz)
double pair_to_double(const std::pair< int64_t, int64_t > &fp_pair, const SQLTypeInfo &ti, const bool float_argument_input)
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:381
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)
int64_t null_val_bit_pattern(const SQLTypeInfo &ti, const bool float_argument_input)
double inline_fp_null_val(const SQL_TYPE_INFO &ti)
size_t get_slots_for_geo_target(const TargetInfo &target_info, const bool separate_varlen_storage)
#define LOG_IF(severity, condition)
Definition: Logger.h:383
bool is_varlen_projection
Definition: TargetInfo.h:56
bool is_agg
Definition: TargetInfo.h:50
size_t advance_slot(const size_t j, const TargetInfo &target_info, const bool separate_varlen_storage)
size_t getGroupbyColCount() const
bool is_integer() const
Definition: sqltypes.h:582
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
T row_ptr_rowwise(T buff, const QueryMemoryDescriptor &query_mem_desc, const size_t entry_idx)
SQLAgg agg_kind
Definition: TargetInfo.h:51
size_t key_offset_colwise(const size_t entry_idx, const size_t key_idx, const size_t entry_count)
bool is_real_str_or_array(const TargetInfo &target_info)
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:389
size_t get_row_bytes(const QueryMemoryDescriptor &query_mem_desc)
std::string get_type_name() const
Definition: sqltypes.h:507
size_t key_offset_rowwise(const size_t entry_idx, const size_t key_count, const size_t slot_count)
Descriptor for the result set buffer layout.
#define CHECK(condition)
Definition: Logger.h:291
bool is_geometry() const
Definition: sqltypes.h:592
uint64_t exp_to_scale(const unsigned exp)
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
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)
bool is_string() const
Definition: sqltypes.h:580
size_t get_slots_for_target(const TargetInfo &target_info, const bool separate_varlen_storage)
bool is_decimal() const
Definition: sqltypes.h:583
T get_cols_ptr(T buff, const QueryMemoryDescriptor &query_mem_desc)
int get_physical_coord_cols() const
Definition: sqltypes.h:433
Definition: sqldefs.h:74
size_t getColOffInBytes(const size_t col_idx) const
size_t get_key_bytes_rowwise(const QueryMemoryDescriptor &query_mem_desc)
FORCE_INLINE HOST DEVICE T align_to_int64(T addr)
bool is_array() const
Definition: sqltypes.h:588