OmniSciDB  a5dc49c757
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
InputMetadata.cpp
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 
17 #include "InputMetadata.h"
18 #include "Execute.h"
19 
20 #include "../Fragmenter/Fragmenter.h"
21 
22 #include <tbb/parallel_for.h>
23 #include <tbb/task_arena.h>
24 #include <future>
25 
26 extern bool g_enable_data_recycler;
27 extern bool g_use_chunk_metadata_cache;
28 
29 InputTableInfoCache::InputTableInfoCache(Executor* executor) : executor_(executor) {}
30 
31 namespace {
32 
34  const Fragmenter_Namespace::TableInfo& table_info) {
35  Fragmenter_Namespace::TableInfo table_info_copy;
36  table_info_copy.chunkKeyPrefix = table_info.chunkKeyPrefix;
37  table_info_copy.fragments = table_info.fragments;
38  table_info_copy.setPhysicalNumTuples(table_info.getPhysicalNumTuples());
39  return table_info_copy;
40 }
41 
42 } // namespace
43 
45  const std::vector<const TableDescriptor*>& shard_tables) {
46  size_t total_number_of_tuples{0};
47  Fragmenter_Namespace::TableInfo table_info_all_shards;
48  for (const TableDescriptor* shard_table : shard_tables) {
49  CHECK(shard_table->fragmenter);
50  const auto& shard_metainfo = shard_table->fragmenter->getFragmentsForQuery();
51  total_number_of_tuples += shard_metainfo.getPhysicalNumTuples();
52  table_info_all_shards.fragments.reserve(table_info_all_shards.fragments.size() +
53  shard_metainfo.fragments.size());
54  table_info_all_shards.fragments.insert(table_info_all_shards.fragments.end(),
55  shard_metainfo.fragments.begin(),
56  shard_metainfo.fragments.end());
57  }
58  table_info_all_shards.setPhysicalNumTuples(total_number_of_tuples);
59  return table_info_all_shards;
60 }
61 
63  const shared::TableKey& table_key) {
64  const auto it = cache_.find(table_key);
65  if (it != cache_.end()) {
66  const auto& table_info = it->second;
67  return copy_table_info(table_info);
68  }
70  CHECK(cat);
71  const auto td = cat->getMetadataForTable(table_key.table_id);
72  CHECK(td);
73  const auto shard_tables = cat->getPhysicalTablesDescriptors(td);
74  auto table_info = build_table_info(shard_tables);
75  auto it_ok = cache_.emplace(table_key, copy_table_info(table_info));
76  CHECK(it_ok.second);
77  return copy_table_info(table_info);
78 }
79 
81  decltype(cache_)().swap(cache_);
82 }
83 
84 namespace {
85 
86 bool uses_int_meta(const SQLTypeInfo& col_ti) {
87  return col_ti.is_integer() || col_ti.is_decimal() || col_ti.is_time() ||
88  col_ti.is_boolean() ||
89  (col_ti.is_string() && col_ti.get_compression() == kENCODING_DICT);
90 }
91 
93  std::vector<Fragmenter_Namespace::FragmentInfo> result;
94  if (rows) {
95  result.resize(1);
96  auto& fragment = result.front();
97  fragment.fragmentId = 0;
98  fragment.deviceIds.resize(3);
99  fragment.resultSet = rows.get();
100  fragment.resultSetMutex.reset(new std::mutex());
101  }
103  table_info.fragments = result;
104  return table_info;
105 }
106 
107 void collect_table_infos(std::vector<InputTableInfo>& table_infos,
108  const std::vector<InputDescriptor>& input_descs,
109  Executor* executor) {
110  const auto temporary_tables = executor->getTemporaryTables();
111  std::unordered_map<shared::TableKey, size_t> info_cache;
112  for (const auto& input_desc : input_descs) {
113  const auto& table_key = input_desc.getTableKey();
114  const auto cached_index_it = info_cache.find(table_key);
115  if (cached_index_it != info_cache.end()) {
116  CHECK_LT(cached_index_it->second, table_infos.size());
117  table_infos.push_back(
118  {table_key, copy_table_info(table_infos[cached_index_it->second].info)});
119  continue;
120  }
121 
122  if (input_desc.getSourceType() == InputSourceType::RESULT) {
123  auto table_id = table_key.table_id;
124  CHECK_LT(table_id, 0);
125  CHECK(temporary_tables);
126  const auto it = temporary_tables->find(table_id);
127  LOG_IF(FATAL, it == temporary_tables->end())
128  << "Failed to find previous query result for node " << -table_id;
129  table_infos.push_back({{0, table_id}, synthesize_table_info(it->second)});
130  } else {
131  CHECK(input_desc.getSourceType() == InputSourceType::TABLE);
132  table_infos.push_back({table_key, executor->getTableInfo(table_key)});
133  }
134  CHECK(!table_infos.empty());
135  info_cache.insert(std::make_pair(table_key, table_infos.size() - 1));
136  }
137 }
138 
139 } // namespace
140 
141 template <typename T>
143  std::shared_ptr<ChunkMetadata>& chunk_metadata,
144  const T* values_buffer,
145  const size_t values_count,
146  const T null_val) {
147  T min_val{std::numeric_limits<T>::max()};
148  T max_val{std::numeric_limits<T>::lowest()};
149  bool has_nulls{false};
150  constexpr size_t parallel_stats_compute_threshold = 20000UL;
151  if (values_count < parallel_stats_compute_threshold) {
152  for (size_t row_idx = 0; row_idx < values_count; ++row_idx) {
153  const T cell_val = values_buffer[row_idx];
154  if (cell_val == null_val) {
155  has_nulls = true;
156  continue;
157  }
158  if (cell_val < min_val) {
159  min_val = cell_val;
160  }
161  if (cell_val > max_val) {
162  max_val = cell_val;
163  }
164  }
165  } else {
166  const size_t max_thread_count = std::thread::hardware_concurrency();
167  const size_t max_inputs_per_thread = 20000;
168  const size_t min_grain_size = max_inputs_per_thread / 2;
169  const size_t num_threads =
170  std::min(max_thread_count,
171  ((values_count + max_inputs_per_thread - 1) / max_inputs_per_thread));
172 
173  std::vector<T> threads_local_mins(num_threads, std::numeric_limits<T>::max());
174  std::vector<T> threads_local_maxes(num_threads, std::numeric_limits<T>::lowest());
175  std::vector<bool> threads_local_has_nulls(num_threads, false);
176  tbb::task_arena limited_arena(num_threads);
177 
178  limited_arena.execute([&] {
180  tbb::blocked_range<size_t>(0, values_count, min_grain_size),
181  [&](const tbb::blocked_range<size_t>& r) {
182  const size_t start_idx = r.begin();
183  const size_t end_idx = r.end();
184  T local_min_val = std::numeric_limits<T>::max();
185  T local_max_val = std::numeric_limits<T>::lowest();
186  bool local_has_nulls = false;
187  for (size_t row_idx = start_idx; row_idx < end_idx; ++row_idx) {
188  const T cell_val = values_buffer[row_idx];
189  if (cell_val == null_val) {
190  local_has_nulls = true;
191  continue;
192  }
193  if (cell_val < local_min_val) {
194  local_min_val = cell_val;
195  }
196  if (cell_val > local_max_val) {
197  local_max_val = cell_val;
198  }
199  }
200  size_t thread_idx = tbb::this_task_arena::current_thread_index();
201  if (local_min_val < threads_local_mins[thread_idx]) {
202  threads_local_mins[thread_idx] = local_min_val;
203  }
204  if (local_max_val > threads_local_maxes[thread_idx]) {
205  threads_local_maxes[thread_idx] = local_max_val;
206  }
207  if (local_has_nulls) {
208  threads_local_has_nulls[thread_idx] = true;
209  }
210  },
211  tbb::simple_partitioner());
212  });
213 
214  for (size_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
215  if (threads_local_mins[thread_idx] < min_val) {
216  min_val = threads_local_mins[thread_idx];
217  }
218  if (threads_local_maxes[thread_idx] > max_val) {
219  max_val = threads_local_maxes[thread_idx];
220  }
221  has_nulls |= threads_local_has_nulls[thread_idx];
222  }
223  }
224  chunk_metadata->fillChunkStats(min_val, max_val, has_nulls);
225 }
226 
228  CHECK(rows->getQueryMemDesc().getQueryDescriptionType() ==
230  CHECK(rows->didOutputColumnar());
231  CHECK(!(rows->areAnyColumnsLazyFetched()));
232  const size_t col_count = rows->colCount();
233  const auto row_count = rows->entryCount();
234 
235  ChunkMetadataMap chunk_metadata_map;
236 
237  for (size_t col_idx = 0; col_idx < col_count; ++col_idx) {
238  std::shared_ptr<ChunkMetadata> chunk_metadata = std::make_shared<ChunkMetadata>();
239  const int8_t* columnar_buffer = const_cast<int8_t*>(rows->getColumnarBuffer(col_idx));
240  const auto col_sql_type_info = rows->getColType(col_idx);
241  // Here, min/max of a column of arrays, col, is defined as
242  // min/max(unnest(col)). That is, if is_array is true, the
243  // metadata is supposed to be syntesized for a query like `SELECT
244  // UNNEST(col_of_arrays) ... GROUP BY ...`. How can we verify that
245  // here?
246 
247  // min/max of a column of a geotype is defined as the min/max of
248  // all x and y coordinate values
249  bool is_array = col_sql_type_info.is_array();
250  bool is_geometry = col_sql_type_info.is_geometry();
251  const auto col_type =
252  (is_array ? col_sql_type_info.get_subtype()
253  : (is_geometry ? col_sql_type_info.get_elem_type().get_type()
254  : col_sql_type_info.get_type()));
255  const auto col_type_info =
256  ((is_array || is_geometry) ? col_sql_type_info.get_elem_type()
257  : col_sql_type_info);
258 
259  chunk_metadata->sqlType = col_type_info;
260  chunk_metadata->numElements = row_count;
261 
262  const int8_t* values_buffer{nullptr};
263  size_t values_count{0};
264  if (FlatBufferManager::isFlatBuffer(columnar_buffer)) {
265  CHECK(FlatBufferManager::isFlatBuffer(columnar_buffer));
266  FlatBufferManager m{const_cast<int8_t*>(columnar_buffer)};
267  chunk_metadata->numBytes = m.getBufferSize();
268  if (is_geometry) {
269  switch (col_sql_type_info.get_type()) {
270  case kPOINT:
271  // a geometry value is a pair of coordinates but its element
272  // type value is a int or double, hence multiplication by 2:
273  values_count = row_count * 2;
274  values_buffer = m.get_values();
275  break;
276  case kLINESTRING:
277  case kPOLYGON:
278  case kMULTILINESTRING:
279  case kMULTIPOLYGON: {
280  values_count = m.getValuesCount();
281  values_buffer = m.getValuesBuffer();
282  } break;
283  default:
284  UNREACHABLE();
285  }
286  } else {
287  CHECK(is_array);
288  CHECK(m.isNestedArray());
289  values_count = m.getValuesCount();
290  values_buffer = m.getValuesBuffer();
291  }
292  } else {
293  chunk_metadata->numBytes = row_count * col_type_info.get_size();
294  values_count = row_count;
295  values_buffer = columnar_buffer;
296  }
297 
298  if (col_type != kTEXT) {
299  CHECK(col_type_info.get_compression() == kENCODING_NONE);
300  } else {
301  CHECK(col_type_info.get_compression() == kENCODING_DICT);
302  CHECK_EQ(col_type_info.get_size(), sizeof(int32_t));
303  }
304 
305  switch (col_type) {
306  case kBOOLEAN:
307  case kTINYINT:
309  chunk_metadata,
310  values_buffer,
311  values_count,
312  static_cast<int8_t>(inline_fixed_encoding_null_val(col_type_info)));
313  break;
314  case kSMALLINT:
316  chunk_metadata,
317  reinterpret_cast<const int16_t*>(values_buffer),
318  values_count,
319  static_cast<int16_t>(inline_fixed_encoding_null_val(col_type_info)));
320  break;
321  case kINT:
322  case kTEXT:
324  chunk_metadata,
325  reinterpret_cast<const int32_t*>(values_buffer),
326  values_count,
327  static_cast<int32_t>(inline_fixed_encoding_null_val(col_type_info)));
328  break;
329  case kBIGINT:
330  case kTIMESTAMP:
332  chunk_metadata,
333  reinterpret_cast<const int64_t*>(values_buffer),
334  values_count,
335  static_cast<int64_t>(inline_fixed_encoding_null_val(col_type_info)));
336  break;
337  case kFLOAT:
338  // For float use the typed null accessor as the generic one converts to double,
339  // and do not want to risk loss of precision
341  chunk_metadata,
342  reinterpret_cast<const float*>(values_buffer),
343  values_count,
345  break;
346  case kDOUBLE:
348  chunk_metadata,
349  reinterpret_cast<const double*>(values_buffer),
350  values_count,
352  break;
353  default:
354  UNREACHABLE();
355  }
356  chunk_metadata_map.emplace(col_idx, chunk_metadata);
357  }
358  return chunk_metadata_map;
359 }
360 
361 namespace {
362 union Number64 {
363  double as_double;
364  int64_t as_int64;
365 };
366 } // namespace
367 
368 ChunkMetadataMap synthesize_metadata(const ResultSet* rows) {
369  auto timer = DEBUG_TIMER(__func__);
370  ChunkMetadataMap metadata_map;
371 
372  // If the ResultSet has no rows, fill with dummy metadata and return early.
373  if (rows->definitelyHasNoRows()) {
374  // resultset has no valid storage, so we fill dummy metadata and return early
375  std::vector<std::unique_ptr<Encoder>> decoders;
376  for (size_t i = 0; i < rows->colCount(); ++i) {
377  decoders.emplace_back(Encoder::Create(nullptr, rows->getColType(i)));
378  const auto it_ok =
379  metadata_map.emplace(i, decoders.back()->getMetadata(rows->getColType(i)));
380  CHECK(it_ok.second);
381  }
382  return metadata_map;
383  }
384 
385  // Create a vector of Encoder vectors for each worker.
386  std::vector<std::vector<std::unique_ptr<Encoder>>> dummy_encoders;
387  const size_t worker_count =
389  for (size_t worker_idx = 0; worker_idx < worker_count; ++worker_idx) {
390  dummy_encoders.emplace_back();
391  for (size_t i = 0; i < rows->colCount(); ++i) {
392  const auto& col_ti = rows->getColType(i);
393  dummy_encoders.back().emplace_back(Encoder::Create(nullptr, col_ti));
394  }
395  }
396 
397  // For TableFunctions, call the optimized function we have for this format.
398  if (rows->getQueryMemDesc().getQueryDescriptionType() ==
401  }
402  rows->moveToBegin();
403 
404  std::vector<SQLTypeInfo> row_col_ti;
405  std::vector<Number64> col_null_vals(rows->colCount());
406  for (size_t i = 0; i < rows->colCount(); i++) {
407  auto const col_ti = rows->getColType(i);
408  row_col_ti.push_back(col_ti);
409  if (uses_int_meta(col_ti)) {
410  col_null_vals[i].as_int64 = inline_int_null_val(col_ti);
411  } else if (col_ti.is_fp()) {
412  col_null_vals[i].as_double = inline_fp_null_val(col_ti);
413  } else {
414  throw std::runtime_error(col_ti.get_type_name() +
415  " is not supported in temporary table.");
416  }
417  }
418 
419  // Code in the do_work lambda runs for and processes each row.
420  const auto do_work = [rows, &row_col_ti, &col_null_vals](
421  const std::vector<TargetValue>& crt_row,
422  std::vector<std::unique_ptr<Encoder>>& dummy_encoders) {
423  for (size_t i = 0; i < rows->colCount(); ++i) {
424  const auto& col_ti = row_col_ti[i];
425  const auto& col_val = crt_row[i];
426  const auto scalar_col_val = boost::get<ScalarTargetValue>(&col_val);
427  CHECK(scalar_col_val);
428  if (uses_int_meta(col_ti)) {
429  const auto i64_p = boost::get<int64_t>(scalar_col_val);
430  CHECK(i64_p);
431  dummy_encoders[i]->updateStats(*i64_p, *i64_p == col_null_vals[i].as_int64);
432  } else {
433  CHECK(col_ti.is_fp());
434  switch (col_ti.get_type()) {
435  case kFLOAT: {
436  const auto float_p = boost::get<float>(scalar_col_val);
437  CHECK(float_p);
438  dummy_encoders[i]->updateStats(*float_p,
439  *float_p == col_null_vals[i].as_double);
440  break;
441  }
442  case kDOUBLE: {
443  const auto double_p = boost::get<double>(scalar_col_val);
444  CHECK(double_p);
445  dummy_encoders[i]->updateStats(*double_p,
446  *double_p == col_null_vals[i].as_double);
447  break;
448  }
449  default:
450  CHECK(false);
451  }
452  }
453  }
454  };
455 
456  // Parallelize the processing using TBB if parallel algorithms are enabled.
458  const size_t entry_count = rows->entryCount();
460  tbb::blocked_range<size_t>(0, entry_count),
461  [&do_work, &rows, &dummy_encoders](const tbb::blocked_range<size_t>& range) {
462  const size_t worker_idx = tbb::this_task_arena::current_thread_index();
463  for (size_t i = range.begin(); i < range.end(); ++i) {
464  const auto crt_row = rows->getRowAtNoTranslations(i);
465  if (!crt_row.empty()) {
466  do_work(crt_row, dummy_encoders[worker_idx]);
467  }
468  }
469  });
470 
471  } else {
472  // If parallel algorithms are not enabled, process the rows sequentially.
473  while (true) {
474  auto crt_row = rows->getNextRow(false, false);
475  if (crt_row.empty()) {
476  break;
477  }
478  do_work(crt_row, dummy_encoders[0]);
479  }
480  }
481  rows->moveToBegin();
482 
483  // Reduce the results from each worker.
484  for (size_t worker_idx = 1; worker_idx < worker_count; ++worker_idx) {
485  CHECK_LT(worker_idx, dummy_encoders.size());
486  const auto& worker_encoders = dummy_encoders[worker_idx];
487  for (size_t i = 0; i < rows->colCount(); ++i) {
488  dummy_encoders[0][i]->reduceStats(*worker_encoders[i]);
489  }
490  }
491  // Add each column's results to the metadata map.
492  for (size_t i = 0; i < rows->colCount(); ++i) {
493  const auto it_ok =
494  metadata_map.emplace(i, dummy_encoders[0][i]->getMetadata(rows->getColType(i)));
495  CHECK(it_ok.second);
496  }
497  return metadata_map;
498 }
499 
500 size_t get_frag_count_of_table(const shared::TableKey& table_key, Executor* executor) {
501  const auto temporary_tables = executor->getTemporaryTables();
502  CHECK(temporary_tables);
503  auto it = temporary_tables->find(table_key.table_id);
504  if (it != temporary_tables->end()) {
505  CHECK_GE(int(0), table_key.table_id);
506  return size_t(1);
507  } else {
508  const auto table_info = executor->getTableInfo(table_key);
509  return table_info.fragments.size();
510  }
511 }
512 
513 std::vector<InputTableInfo> get_table_infos(
514  const std::vector<InputDescriptor>& input_descs,
515  Executor* executor) {
516  std::vector<InputTableInfo> table_infos;
517  collect_table_infos(table_infos, input_descs, executor);
518  return table_infos;
519 }
520 
521 std::vector<InputTableInfo> get_table_infos(const RelAlgExecutionUnit& ra_exe_unit,
522  Executor* executor) {
523  std::vector<InputTableInfo> table_infos;
524  collect_table_infos(table_infos, ra_exe_unit.input_descs, executor);
525  return table_infos;
526 }
527 
530  bool need_to_compute_metadata = true;
531  // we disable chunk metadata recycler when filter pushdown is enabled
532  // since re-executing the query invalidates the cached metdata
533  // todo(yoonmin): relax this
534  bool enable_chunk_metadata_cache = g_enable_data_recycler &&
538  if (enable_chunk_metadata_cache) {
539  std::optional<ChunkMetadataMap> cached =
540  executor->getResultSetRecyclerHolder().getCachedChunkMetadata(
541  resultSet->getQueryPlanHash());
542  if (cached) {
543  chunkMetadataMap = *cached;
544  need_to_compute_metadata = false;
545  }
546  }
547  if (need_to_compute_metadata) {
549  if (enable_chunk_metadata_cache && !chunkMetadataMap.empty()) {
550  executor->getResultSetRecyclerHolder().putChunkMetadataToCache(
551  resultSet->getQueryPlanHash(),
552  resultSet->getInputTableKeys(),
554  }
555  }
557  }
558  return chunkMetadataMap;
559 }
560 
562  const {
563  ChunkMetadataMap metadata_map;
564  for (const auto& [column_id, chunk_metadata] : chunkMetadataMap) {
565  metadata_map[column_id] = std::make_shared<ChunkMetadata>(*chunk_metadata);
566  }
567  return metadata_map;
568 }
569 
571  std::unique_ptr<std::lock_guard<std::mutex>> lock;
572  if (resultSetMutex) {
573  lock.reset(new std::lock_guard<std::mutex>(*resultSetMutex));
574  }
575  CHECK_EQ(!!resultSet, !!resultSetMutex);
576  if (resultSet && !synthesizedNumTuplesIsValid) {
577  numTuples = resultSet->rowCount();
578  synthesizedNumTuplesIsValid = true;
579  }
580  return numTuples;
581 }
582 
584  if (!fragments.empty() && fragments.front().resultSet) {
585  return fragments.front().getNumTuples();
586  }
587  return numTuples;
588 }
589 
591  if (!fragments.empty() && fragments.front().resultSet) {
592  return fragments.front().resultSet->entryCount();
593  }
594  return numTuples;
595 }
596 
598  if (!fragments.empty() && fragments.front().resultSet) {
599  return fragments.front().resultSet->entryCount();
600  }
601  size_t fragment_num_tupples_upper_bound = 0;
602  for (const auto& fragment : fragments) {
603  fragment_num_tupples_upper_bound =
604  std::max(fragment.getNumTuples(), fragment_num_tupples_upper_bound);
605  }
606  return fragment_num_tupples_upper_bound;
607 }
ChunkMetadataMap synthesize_metadata_table_function(const ResultSet *rows)
#define CHECK_EQ(x, y)
Definition: Logger.h:301
ChunkMetadataMap getChunkMetadataMapPhysicalCopy() const
std::string cat(Ts &&...args)
Fragmenter_Namespace::TableInfo copy_table_info(const Fragmenter_Namespace::TableInfo &table_info)
ChunkMetadataMap synthesize_metadata(const ResultSet *rows)
static Encoder * Create(Data_Namespace::AbstractBuffer *buffer, const SQLTypeInfo sqlType)
Definition: Encoder.cpp:26
std::vector< InputDescriptor > input_descs
#define UNREACHABLE()
Definition: Logger.h:338
#define CHECK_GE(x, y)
Definition: Logger.h:306
std::shared_ptr< ResultSet > ResultSetPtr
std::vector< FragmentInfo > fragments
Definition: Fragmenter.h:171
std::vector< int > chunkKeyPrefix
Definition: Fragmenter.h:170
size_t get_frag_count_of_table(const shared::TableKey &table_key, Executor *executor)
bool g_enable_data_recycler
Definition: Execute.cpp:158
double inline_fp_null_val(const SQL_TYPE_INFO &ti)
bool is_time() const
Definition: sqltypes.h:579
#define LOG_IF(severity, condition)
Definition: Logger.h:384
Fragmenter_Namespace::TableInfo build_table_info(const std::vector< const TableDescriptor * > &shard_tables)
bool g_use_chunk_metadata_cache
Definition: Execute.cpp:161
static std::shared_ptr< Executor > getExecutor(const ExecutorId id, const std::string &debug_dir="", const std::string &debug_file="", const SystemParameters &system_parameters=SystemParameters())
Definition: Execute.cpp:513
std::map< int, std::shared_ptr< ChunkMetadata >> ChunkMetadataMap
bool use_parallel_algorithms(const ResultSet &rows)
Definition: ResultSet.cpp:1600
TableFunction
Definition: enums.h:58
tuple rows
Definition: report.py:114
size_t getPhysicalNumTuples() const
Definition: Fragmenter.h:164
const size_t max_inputs_per_thread
static SysCatalog & instance()
Definition: SysCatalog.h:343
bool uses_int_meta(const SQLTypeInfo &col_ti)
bool is_integer() const
Definition: sqltypes.h:567
size_t getFragmentNumTuplesUpperBound() const
executor_(executor)
Fragmenter_Namespace::TableInfo synthesize_table_info(const ResultSetPtr &rows)
const ChunkMetadataMap & getChunkMetadataMap() const
bool is_boolean() const
Definition: sqltypes.h:582
std::shared_ptr< Catalog > getCatalog(const std::string &dbName)
#define CHECK_LT(x, y)
Definition: Logger.h:303
Definition: sqltypes.h:79
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:399
constexpr float inline_fp_null_value< float >()
Fragmenter_Namespace::TableInfo getTableInfo(const shared::TableKey &table_key)
InputTableInfoCache(Executor *executor)
constexpr double inline_fp_null_value< double >()
std::unordered_map< shared::TableKey, Fragmenter_Namespace::TableInfo > cache_
Definition: InputMetadata.h:47
void parallel_for(const blocked_range< Int > &range, const Body &body, const Partitioner &p=Partitioner())
bool g_enable_filter_push_down
Definition: Execute.cpp:102
#define CHECK(condition)
Definition: Logger.h:291
std::vector< InputTableInfo > get_table_infos(const std::vector< InputDescriptor > &input_descs, Executor *executor)
#define DEBUG_TIMER(name)
Definition: Logger.h:412
void compute_table_function_col_chunk_stats(std::shared_ptr< ChunkMetadata > &chunk_metadata, const T *values_buffer, const size_t values_count, const T null_val)
void setPhysicalNumTuples(const size_t physNumTuples)
Definition: Fragmenter.h:166
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
int64_t inline_fixed_encoding_null_val(const SQL_TYPE_INFO &ti)
void collect_table_infos(std::vector< InputTableInfo > &table_infos, const std::vector< InputDescriptor > &input_descs, Executor *executor)
Definition: sqltypes.h:72
static constexpr ExecutorId UNITARY_EXECUTOR_ID
Definition: Execute.h:423
bool is_string() const
Definition: sqltypes.h:561
HOST static DEVICE bool isFlatBuffer(const void *buffer)
Definition: FlatBuffer.h:528
int cpu_threads()
Definition: thread_count.h:25
bool is_decimal() const
Definition: sqltypes.h:570
DEVICE void swap(ARGS &&...args)
Definition: gpu_enabled.h:114
static int64_t getBufferSize(const void *buffer)
Definition: FlatBuffer.h:553