OmniSciDB  1dac507f6e
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
OutputBufferInitialization.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 
18 #include "BufferCompaction.h"
20 #include "TypePunning.h"
21 
22 #include "../Analyzer/Analyzer.h"
23 
24 extern bool g_bigint_count;
25 namespace {
26 
27 inline std::vector<int64_t> init_agg_val_vec(
28  const std::vector<TargetInfo>& targets,
30  std::vector<int64_t> agg_init_vals;
31  agg_init_vals.reserve(query_mem_desc.getSlotCount());
32  const bool is_group_by{query_mem_desc.isGroupBy()};
33  for (size_t target_idx = 0, agg_col_idx = 0; target_idx < targets.size();
34  ++target_idx, ++agg_col_idx) {
35  CHECK_LT(agg_col_idx, query_mem_desc.getSlotCount());
36  const auto agg_info = targets[target_idx];
37  if (!agg_info.is_agg || agg_info.agg_kind == kSAMPLE) {
38  if (agg_info.agg_kind == kSAMPLE && agg_info.sql_type.is_string() &&
39  agg_info.sql_type.get_compression() != kENCODING_NONE) {
40  agg_init_vals.push_back(
41  get_agg_initial_val(agg_info.agg_kind,
42  agg_info.sql_type,
43  is_group_by,
44  query_mem_desc.getCompactByteWidth()));
45  continue;
46  }
47  if (query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx) > 0) {
48  agg_init_vals.push_back(0);
49  }
50  if (agg_info.sql_type.is_array() ||
51  (agg_info.sql_type.is_string() &&
52  agg_info.sql_type.get_compression() == kENCODING_NONE)) {
53  agg_init_vals.push_back(0);
54  }
55  if (agg_info.sql_type.is_geometry()) {
56  agg_init_vals.push_back(0);
57  for (auto i = 1; i < agg_info.sql_type.get_physical_coord_cols(); ++i) {
58  agg_init_vals.push_back(0);
59  agg_init_vals.push_back(0);
60  }
61  }
62  continue;
63  }
64  CHECK_GT(query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx), 0);
65  const bool float_argument_input = takes_float_argument(agg_info);
66  const auto chosen_bytes = query_mem_desc.isLogicalSizedColumnsAllowed()
67  ? query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx)
68  : query_mem_desc.getCompactByteWidth();
69  auto init_ti = get_compact_type(agg_info);
70  if (!is_group_by) {
71  init_ti.set_notnull(false);
72  }
73  agg_init_vals.push_back(
74  get_agg_initial_val(agg_info.agg_kind,
75  init_ti,
76  is_group_by || float_argument_input,
77  (float_argument_input ? sizeof(float) : chosen_bytes)));
78  if (kAVG == agg_info.agg_kind) {
79  ++agg_col_idx;
80  agg_init_vals.push_back(0);
81  }
82  }
83  return agg_init_vals;
84 }
85 
86 } // namespace
87 
88 std::pair<int64_t, int64_t> inline_int_max_min(const size_t byte_width) {
89  switch (byte_width) {
90  case 1:
91  return std::make_pair(std::numeric_limits<int8_t>::max(),
92  std::numeric_limits<int8_t>::min());
93  case 2:
94  return std::make_pair(std::numeric_limits<int16_t>::max(),
95  std::numeric_limits<int16_t>::min());
96  case 4:
97  return std::make_pair(std::numeric_limits<int32_t>::max(),
98  std::numeric_limits<int32_t>::min());
99  case 8:
100  return std::make_pair(std::numeric_limits<int64_t>::max(),
101  std::numeric_limits<int64_t>::min());
102  default:
103  abort();
104  }
105 }
106 
107 std::pair<uint64_t, uint64_t> inline_uint_max_min(const size_t byte_width) {
108  switch (byte_width) {
109  case 1:
110  return std::make_pair(std::numeric_limits<uint8_t>::max(),
111  std::numeric_limits<uint8_t>::min());
112  case 2:
113  return std::make_pair(std::numeric_limits<uint16_t>::max(),
114  std::numeric_limits<uint16_t>::min());
115  case 4:
116  return std::make_pair(std::numeric_limits<uint32_t>::max(),
117  std::numeric_limits<uint32_t>::min());
118  case 8:
119  return std::make_pair(std::numeric_limits<uint64_t>::max(),
120  std::numeric_limits<uint64_t>::min());
121  default:
122  abort();
123  }
124 }
125 
126 // TODO(alex): proper types for aggregate
127 int64_t get_agg_initial_val(const SQLAgg agg,
128  const SQLTypeInfo& ti,
129  const bool enable_compaction,
130  const unsigned min_byte_width_to_compact) {
131  CHECK(!ti.is_string() || agg == kSAMPLE);
132  const auto byte_width =
133  enable_compaction
134  ? compact_byte_width(static_cast<unsigned>(get_bit_width(ti) >> 3),
135  unsigned(min_byte_width_to_compact))
136  : sizeof(int64_t);
137  CHECK(ti.get_logical_size() < 0 ||
138  byte_width >= static_cast<unsigned>(ti.get_logical_size()));
139  switch (agg) {
140  case kAVG:
141  case kSUM: {
142  if (!ti.get_notnull()) {
143  if (ti.is_fp()) {
144  switch (byte_width) {
145  case 4: {
146  const float null_float = inline_fp_null_val(ti);
147  return *reinterpret_cast<const int32_t*>(may_alias_ptr(&null_float));
148  }
149  case 8: {
150  const double null_double = inline_fp_null_val(ti);
151  return *reinterpret_cast<const int64_t*>(may_alias_ptr(&null_double));
152  }
153  default:
154  CHECK(false);
155  }
156  } else {
157  return inline_int_null_val(ti);
158  }
159  }
160  switch (byte_width) {
161  case 4: {
162  const float zero_float{0.};
163  return ti.is_fp()
164  ? *reinterpret_cast<const int32_t*>(may_alias_ptr(&zero_float))
165  : 0;
166  }
167  case 8: {
168  const double zero_double{0.};
169  return ti.is_fp()
170  ? *reinterpret_cast<const int64_t*>(may_alias_ptr(&zero_double))
171  : 0;
172  }
173  default:
174  CHECK(false);
175  }
176  }
177  case kCOUNT:
179  return 0;
180  case kMIN: {
181  switch (byte_width) {
182  case 1: {
183  CHECK(!ti.is_fp());
184  return ti.get_notnull() ? std::numeric_limits<int8_t>::max()
185  : inline_int_null_val(ti);
186  }
187  case 2: {
188  CHECK(!ti.is_fp());
189  return ti.get_notnull() ? std::numeric_limits<int16_t>::max()
190  : inline_int_null_val(ti);
191  }
192  case 4: {
193  const float max_float = std::numeric_limits<float>::max();
194  const float null_float =
195  ti.is_fp() ? static_cast<float>(inline_fp_null_val(ti)) : 0.;
196  return ti.is_fp()
197  ? (ti.get_notnull()
198  ? *reinterpret_cast<const int32_t*>(may_alias_ptr(&max_float))
199  : *reinterpret_cast<const int32_t*>(
200  may_alias_ptr(&null_float)))
201  : (ti.get_notnull() ? std::numeric_limits<int32_t>::max()
202  : inline_int_null_val(ti));
203  }
204  case 8: {
205  const double max_double = std::numeric_limits<double>::max();
206  const double null_double{ti.is_fp() ? inline_fp_null_val(ti) : 0.};
207  return ti.is_fp() ? (ti.get_notnull() ? *reinterpret_cast<const int64_t*>(
208  may_alias_ptr(&max_double))
209  : *reinterpret_cast<const int64_t*>(
210  may_alias_ptr(&null_double)))
211  : (ti.get_notnull() ? std::numeric_limits<int64_t>::max()
212  : inline_int_null_val(ti));
213  }
214  default:
215  CHECK(false);
216  }
217  }
218  case kSAMPLE:
219  case kMAX: {
220  switch (byte_width) {
221  case 1: {
222  CHECK(!ti.is_fp());
223  return ti.get_notnull() ? std::numeric_limits<int8_t>::min()
224  : inline_int_null_val(ti);
225  }
226  case 2: {
227  CHECK(!ti.is_fp());
228  return ti.get_notnull() ? std::numeric_limits<int16_t>::min()
229  : inline_int_null_val(ti);
230  }
231  case 4: {
232  const float min_float = -std::numeric_limits<float>::max();
233  const float null_float =
234  ti.is_fp() ? static_cast<float>(inline_fp_null_val(ti)) : 0.;
235  return (ti.is_fp())
236  ? (ti.get_notnull()
237  ? *reinterpret_cast<const int32_t*>(may_alias_ptr(&min_float))
238  : *reinterpret_cast<const int32_t*>(
239  may_alias_ptr(&null_float)))
240  : (ti.get_notnull() ? std::numeric_limits<int32_t>::min()
241  : inline_int_null_val(ti));
242  }
243  case 8: {
244  const double min_double = -std::numeric_limits<double>::max();
245  const double null_double{ti.is_fp() ? inline_fp_null_val(ti) : 0.};
246  return ti.is_fp() ? (ti.get_notnull() ? *reinterpret_cast<const int64_t*>(
247  may_alias_ptr(&min_double))
248  : *reinterpret_cast<const int64_t*>(
249  may_alias_ptr(&null_double)))
250  : (ti.get_notnull() ? std::numeric_limits<int64_t>::min()
251  : inline_int_null_val(ti));
252  }
253  default:
254  CHECK(false);
255  }
256  }
257  default:
258  abort();
259  }
260 }
261 
262 std::vector<int64_t> init_agg_val_vec(
263  const std::vector<Analyzer::Expr*>& targets,
264  const std::list<std::shared_ptr<Analyzer::Expr>>& quals,
266  std::vector<TargetInfo> target_infos;
267  target_infos.reserve(targets.size());
268  const auto agg_col_count = query_mem_desc.getSlotCount();
269  for (size_t target_idx = 0, agg_col_idx = 0;
270  target_idx < targets.size() && agg_col_idx < agg_col_count;
271  ++target_idx, ++agg_col_idx) {
272  const auto target_expr = targets[target_idx];
273  auto target = get_target_info(target_expr, g_bigint_count);
274  auto arg_expr = agg_arg(target_expr);
275  if (arg_expr) {
276  if (query_mem_desc.getQueryDescriptionType() ==
278  target.is_agg &&
279  (target.agg_kind == kMIN || target.agg_kind == kMAX ||
280  target.agg_kind == kSUM || target.agg_kind == kAVG)) {
281  set_notnull(target, false);
282  } else if (constrained_not_null(arg_expr, quals)) {
283  set_notnull(target, true);
284  }
285  }
286  target_infos.push_back(target);
287  }
288  return init_agg_val_vec(target_infos, query_mem_desc);
289 }
290 
291 const Analyzer::Expr* agg_arg(const Analyzer::Expr* expr) {
292  const auto agg_expr = dynamic_cast<const Analyzer::AggExpr*>(expr);
293  return agg_expr ? agg_expr->get_arg() : nullptr;
294 }
295 
297  const std::list<std::shared_ptr<Analyzer::Expr>>& quals) {
298  for (const auto qual : quals) {
299  auto uoper = std::dynamic_pointer_cast<Analyzer::UOper>(qual);
300  if (!uoper) {
301  continue;
302  }
303  bool is_negated{false};
304  if (uoper->get_optype() == kNOT) {
305  uoper = std::dynamic_pointer_cast<Analyzer::UOper>(uoper->get_own_operand());
306  is_negated = true;
307  }
308  if (uoper && (uoper->get_optype() == kISNOTNULL ||
309  (is_negated && uoper->get_optype() == kISNULL))) {
310  if (*uoper->get_own_operand() == *expr) {
311  return true;
312  }
313  }
314  }
315  return false;
316 }
const Analyzer::Expr * agg_arg(const Analyzer::Expr *expr)
bool is_fp() const
Definition: sqltypes.h:481
SQLAgg
Definition: sqldefs.h:71
bool constrained_not_null(const Analyzer::Expr *expr, const std::list< std::shared_ptr< Analyzer::Expr >> &quals)
const int64_t const uint32_t const uint32_t const uint32_t agg_col_count
unsigned compact_byte_width(unsigned qw, unsigned low_bound)
bool isLogicalSizedColumnsAllowed() const
TargetInfo get_target_info(const PointerType target_expr, const bool bigint_count)
Definition: TargetInfo.h:65
std::vector< int64_t > init_agg_val_vec(const std::vector< TargetInfo > &targets, const QueryMemoryDescriptor &query_mem_desc)
int64_t get_agg_initial_val(const SQLAgg agg, const SQLTypeInfo &ti, const bool enable_compaction, const unsigned min_byte_width_to_compact)
Expr * get_arg() const
Definition: Analyzer.h:1045
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:120
#define CHECK_GT(x, y)
Definition: Logger.h:202
double inline_fp_null_val(const SQL_TYPE_INFO &ti)
Definition: sqldefs.h:71
const SQLTypeInfo get_compact_type(const TargetInfo &target)
size_t get_bit_width(const SQLTypeInfo &ti)
CHECK(cgen_state)
int get_logical_size() const
Definition: sqltypes.h:337
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:333
bool g_bigint_count
Definition: sqldefs.h:71
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
QueryDescriptionType getQueryDescriptionType() const
std::pair< uint64_t, uint64_t > inline_uint_max_min(const size_t byte_width)
#define CHECK_LT(x, y)
Definition: Logger.h:200
Definition: sqldefs.h:71
Descriptor for the result set buffer layout.
bool is_string() const
Definition: sqltypes.h:477
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
std::pair< int64_t, int64_t > inline_int_max_min(const size_t byte_width)
Definition: sqldefs.h:71
Definition: sqldefs.h:71
Definition: sqldefs.h:39
void set_notnull(TargetInfo &target, const bool not_null)