OmniSciDB  a5dc49c757
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
anonymous_namespace{Execute.cpp} Namespace Reference

Classes

struct  GetTargetInfo
 
class  OutVecOwner
 

Functions

void prepare_string_dictionaries (const std::unordered_set< PhysicalInput > &phys_inputs)
 
bool is_empty_table (Fragmenter_Namespace::AbstractFragmenter *fragmenter)
 
void log_system_memory_info_impl (std::string const &mem_log, size_t executor_id, size_t log_time_ms, std::string const &log_tag, size_t const thread_idx)
 
size_t get_col_byte_width (const shared::ColumnKey &column_key)
 
ResultSetPtr get_merged_result (std::vector< std::pair< ResultSetPtr, std::vector< size_t >>> &results_per_device, std::vector< TargetInfo > const &targets)
 
ReductionCode get_reduction_code (const size_t executor_id, std::vector< std::pair< ResultSetPtr, std::vector< size_t >>> &results_per_device, int64_t *compilation_queue_time)
 
size_t compute_buffer_entry_guess (const std::vector< InputTableInfo > &query_infos, const RelAlgExecutionUnit &ra_exe_unit)
 
std::string get_table_name (const InputDescriptor &input_desc)
 
size_t getDeviceBasedWatchdogScanLimit (size_t watchdog_max_projected_rows_per_device, const ExecutorDeviceType device_type, const int device_count)
 
void checkWorkUnitWatchdog (const RelAlgExecutionUnit &ra_exe_unit, const std::vector< InputTableInfo > &table_infos, const ExecutorDeviceType device_type, const int device_count)
 
template<typename T >
std::vector< std::string > expr_container_to_string (const T &expr_container)
 
template<>
std::vector< std::string > expr_container_to_string (const std::list< Analyzer::OrderEntry > &expr_container)
 
std::string sort_algorithm_to_string (const SortAlgorithm algorithm)
 
RelAlgExecutionUnit replace_scan_limit (const RelAlgExecutionUnit &ra_exe_unit_in, const size_t new_scan_limit)
 
int64_t inline_null_val (const SQLTypeInfo &ti, const bool float_argument_input)
 
void fill_entries_for_empty_input (std::vector< TargetInfo > &target_infos, std::vector< int64_t > &entry, const std::vector< Analyzer::Expr * > &target_exprs, const QueryMemoryDescriptor &query_mem_desc)
 
ResultSetPtr build_row_for_empty_input (const std::vector< Analyzer::Expr * > &target_exprs_in, const QueryMemoryDescriptor &query_mem_desc, const ExecutorDeviceType device_type)
 
size_t permute_storage_columnar (const ResultSetStorage *input_storage, const QueryMemoryDescriptor &input_query_mem_desc, const ResultSetStorage *output_storage, size_t output_row_index, const QueryMemoryDescriptor &output_query_mem_desc, const std::vector< uint32_t > &top_permutation)
 
size_t permute_storage_row_wise (const ResultSetStorage *input_storage, const ResultSetStorage *output_storage, size_t output_row_index, const QueryMemoryDescriptor &output_query_mem_desc, const std::vector< uint32_t > &top_permutation)
 
bool has_lazy_fetched_columns (const std::vector< ColumnLazyFetchInfo > &fetched_cols)
 
const ColumnDescriptortry_get_column_descriptor (const InputColDescriptor *col_desc)
 
size_t get_selected_input_descs_index (const shared::TableKey &table_key, std::vector< InputDescriptor > const &input_descs)
 
size_t get_selected_input_col_descs_index (const shared::TableKey &table_key, std::list< std::shared_ptr< InputColDescriptor const >> const &input_col_descs)
 
std::list< std::shared_ptr
< const InputColDescriptor > > 
get_selected_input_col_descs (const shared::TableKey &table_key, std::list< std::shared_ptr< InputColDescriptor const >> const &input_col_descs)
 
void set_mod_range (std::vector< int8_t const * > &frag_col_buffers, int8_t const *const ptr, size_t const local_col_id, size_t const N)
 
bool check_rows_less_than_needed (const ResultSetPtr &results, const size_t scan_limit)
 
void add_deleted_col_to_map (PlanState::DeletedColumnsMap &deleted_cols_map, const ColumnDescriptor *deleted_cd, const shared::TableKey &table_key)
 
std::tuple< bool, int64_t,
int64_t > 
get_hpt_overflow_underflow_safe_scaled_values (const int64_t chunk_min, const int64_t chunk_max, const SQLTypeInfo &lhs_type, const SQLTypeInfo &rhs_type)
 

Function Documentation

void anonymous_namespace{Execute.cpp}::add_deleted_col_to_map ( PlanState::DeletedColumnsMap deleted_cols_map,
const ColumnDescriptor deleted_cd,
const shared::TableKey table_key 
)

Definition at line 4463 of file Execute.cpp.

References CHECK, and CHECK_EQ.

Referenced by Executor::addDeletedColumn().

4465  {
4466  auto deleted_cols_it = deleted_cols_map.find(table_key);
4467  if (deleted_cols_it == deleted_cols_map.end()) {
4468  CHECK(deleted_cols_map.insert(std::make_pair(table_key, deleted_cd)).second);
4469  } else {
4470  CHECK_EQ(deleted_cd, deleted_cols_it->second);
4471  }
4472 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
#define CHECK(condition)
Definition: Logger.h:291

+ Here is the caller graph for this function:

ResultSetPtr anonymous_namespace{Execute.cpp}::build_row_for_empty_input ( const std::vector< Analyzer::Expr * > &  target_exprs_in,
const QueryMemoryDescriptor query_mem_desc,
const ExecutorDeviceType  device_type 
)

Definition at line 2673 of file Execute.cpp.

References CHECK, fill_entries_for_empty_input(), QueryMemoryDescriptor::getExecutor(), query_mem_desc, and SQLTypeInfo::set_notnull().

Referenced by Executor::collectAllDeviceResults().

2676  {
2677  std::vector<std::shared_ptr<Analyzer::Expr>> target_exprs_owned_copies;
2678  std::vector<Analyzer::Expr*> target_exprs;
2679  for (const auto target_expr : target_exprs_in) {
2680  const auto target_expr_copy =
2681  std::dynamic_pointer_cast<Analyzer::AggExpr>(target_expr->deep_copy());
2682  CHECK(target_expr_copy);
2683  auto ti = target_expr->get_type_info();
2684  ti.set_notnull(false);
2685  target_expr_copy->set_type_info(ti);
2686  if (target_expr_copy->get_arg()) {
2687  auto arg_ti = target_expr_copy->get_arg()->get_type_info();
2688  arg_ti.set_notnull(false);
2689  target_expr_copy->get_arg()->set_type_info(arg_ti);
2690  }
2691  target_exprs_owned_copies.push_back(target_expr_copy);
2692  target_exprs.push_back(target_expr_copy.get());
2693  }
2694  std::vector<TargetInfo> target_infos;
2695  std::vector<int64_t> entry;
2696  fill_entries_for_empty_input(target_infos, entry, target_exprs, query_mem_desc);
2697  const auto executor = query_mem_desc.getExecutor();
2698  CHECK(executor);
2699  // todo(yoonmin): Can we avoid initialize DramArena for this empty result case?
2700  auto row_set_mem_owner = executor->getRowSetMemoryOwner();
2701  CHECK(row_set_mem_owner);
2702  auto rs = std::make_shared<ResultSet>(target_infos,
2703  device_type,
2705  row_set_mem_owner,
2706  executor->blockSize(),
2707  executor->gridSize());
2708  rs->allocateStorage();
2709  rs->fillOneEntry(entry);
2710  return rs;
2711 }
void fill_entries_for_empty_input(std::vector< TargetInfo > &target_infos, std::vector< int64_t > &entry, const std::vector< Analyzer::Expr * > &target_exprs, const QueryMemoryDescriptor &query_mem_desc)
Definition: Execute.cpp:2615
#define CHECK(condition)
Definition: Logger.h:291
const Executor * getExecutor() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool anonymous_namespace{Execute.cpp}::check_rows_less_than_needed ( const ResultSetPtr results,
const size_t  scan_limit 
)

Definition at line 4054 of file Execute.cpp.

References CHECK.

Referenced by Executor::executePlanWithGroupBy().

4054  {
4055  CHECK(scan_limit);
4056  return results && results->rowCount() < scan_limit;
4057 }
#define CHECK(condition)
Definition: Logger.h:291

+ Here is the caller graph for this function:

void anonymous_namespace{Execute.cpp}::checkWorkUnitWatchdog ( const RelAlgExecutionUnit ra_exe_unit,
const std::vector< InputTableInfo > &  table_infos,
const ExecutorDeviceType  device_type,
const int  device_count 
)

Definition at line 1847 of file Execute.cpp.

References SortInfo::algorithm, g_watchdog_max_projected_rows_per_device, foreign_storage::get_table_name(), getDeviceBasedWatchdogScanLimit(), RelAlgExecutionUnit::groupby_exprs, RelAlgExecutionUnit::input_descs, RegisteredQueryHint::isHintRegistered(), join(), kWatchdogMaxProjectedRowsPerDevice, RelAlgExecutionUnit::query_hint, RelAlgExecutionUnit::scan_limit, RelAlgExecutionUnit::sort_info, StreamingTopN, RelAlgExecutionUnit::target_exprs, to_string(), RelAlgExecutionUnit::use_bump_allocator, VLOG, and RegisteredQueryHint::watchdog_max_projected_rows_per_device.

Referenced by Executor::createKernels().

1850  {
1851  for (const auto target_expr : ra_exe_unit.target_exprs) {
1852  if (dynamic_cast<const Analyzer::AggExpr*>(target_expr)) {
1853  return;
1854  }
1855  }
1856  size_t watchdog_max_projected_rows_per_device =
1858  if (ra_exe_unit.query_hint.isHintRegistered(
1860  watchdog_max_projected_rows_per_device =
1862  VLOG(1) << "Set the watchdog per device maximum projection limit: "
1863  << watchdog_max_projected_rows_per_device << " by a query hint";
1864  }
1865  if (!ra_exe_unit.scan_limit && table_infos.size() == 1 &&
1866  table_infos.front().info.getPhysicalNumTuples() <
1867  watchdog_max_projected_rows_per_device) {
1868  // Allow a query with no scan limit to run on small tables
1869  return;
1870  }
1871  if (ra_exe_unit.use_bump_allocator) {
1872  // Bump allocator removes the scan limit (and any knowledge of the size of the output
1873  // relative to the size of the input), so we bypass this check for now
1874  return;
1875  }
1876  if (ra_exe_unit.sort_info.algorithm != SortAlgorithm::StreamingTopN &&
1877  ra_exe_unit.groupby_exprs.size() == 1 && !ra_exe_unit.groupby_exprs.front() &&
1878  (!ra_exe_unit.scan_limit ||
1879  ra_exe_unit.scan_limit >
1881  watchdog_max_projected_rows_per_device, device_type, device_count))) {
1882  std::vector<std::string> table_names;
1883  const auto& input_descs = ra_exe_unit.input_descs;
1884  for (const auto& input_desc : input_descs) {
1885  table_names.push_back(get_table_name(input_desc));
1886  }
1887  if (!ra_exe_unit.scan_limit) {
1888  throw WatchdogException(
1889  "Projection query would require a scan without a limit on table(s): " +
1890  boost::algorithm::join(table_names, ", "));
1891  } else {
1892  throw WatchdogException(
1893  "Projection query output result set on table(s): " +
1894  boost::algorithm::join(table_names, ", ") + " would contain " +
1895  std::to_string(ra_exe_unit.scan_limit) +
1896  " rows, which is more than the current system limit of " +
1898  watchdog_max_projected_rows_per_device, device_type, device_count)));
1899  }
1900  }
1901 }
std::vector< Analyzer::Expr * > target_exprs
size_t getDeviceBasedWatchdogScanLimit(size_t watchdog_max_projected_rows_per_device, const ExecutorDeviceType device_type, const int device_count)
Definition: Execute.cpp:1837
std::string join(T const &container, std::string const &delim)
std::vector< InputDescriptor > input_descs
const std::list< std::shared_ptr< Analyzer::Expr > > groupby_exprs
SortAlgorithm algorithm
std::string to_string(char const *&&v)
size_t g_watchdog_max_projected_rows_per_device
Definition: Execute.cpp:83
size_t watchdog_max_projected_rows_per_device
Definition: QueryHint.h:349
bool isHintRegistered(const QueryHint hint) const
Definition: QueryHint.h:398
RegisteredQueryHint query_hint
#define VLOG(n)
Definition: Logger.h:388
std::string get_table_name(int32_t db_id, int32_t table_id)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

size_t anonymous_namespace{Execute.cpp}::compute_buffer_entry_guess ( const std::vector< InputTableInfo > &  query_infos,
const RelAlgExecutionUnit ra_exe_unit 
)

Definition at line 1778 of file Execute.cpp.

References CHECK, RelAlgExecutionUnit::scan_limit, and VLOG.

Referenced by Executor::executeWorkUnitImpl().

1779  {
1780  // we can use filtered_count_all's result if available
1781  if (ra_exe_unit.scan_limit) {
1782  VLOG(1)
1783  << "Exploiting a result of filtered count query as output buffer entry count: "
1784  << ra_exe_unit.scan_limit;
1785  return ra_exe_unit.scan_limit;
1786  }
1788  using checked_size_t = boost::multiprecision::number<
1789  boost::multiprecision::cpp_int_backend<64,
1790  64,
1791  boost::multiprecision::unsigned_magnitude,
1792  boost::multiprecision::checked,
1793  void>>;
1794  checked_size_t checked_max_groups_buffer_entry_guess = 1;
1795  // Cap the rough approximation to 100M entries, it's unlikely we can do a great job for
1796  // baseline group layout with that many entries anyway.
1797  constexpr size_t max_groups_buffer_entry_guess_cap = 100000000;
1798  // Check for overflows since we're multiplying potentially big table sizes.
1799  try {
1800  for (const auto& table_info : query_infos) {
1801  CHECK(!table_info.info.fragments.empty());
1802  checked_size_t table_cardinality = 0;
1803  std::for_each(table_info.info.fragments.begin(),
1804  table_info.info.fragments.end(),
1805  [&table_cardinality](const FragmentInfo& frag_info) {
1806  table_cardinality += frag_info.getNumTuples();
1807  });
1808  checked_max_groups_buffer_entry_guess *= table_cardinality;
1809  }
1810  } catch (...) {
1811  checked_max_groups_buffer_entry_guess = max_groups_buffer_entry_guess_cap;
1812  VLOG(1) << "Detect overflow when approximating output buffer entry count, "
1813  "resetting it as "
1814  << max_groups_buffer_entry_guess_cap;
1815  }
1816  size_t max_groups_buffer_entry_guess =
1817  std::min(static_cast<size_t>(checked_max_groups_buffer_entry_guess),
1818  max_groups_buffer_entry_guess_cap);
1819  VLOG(1) << "Set an approximated output entry count as: "
1820  << max_groups_buffer_entry_guess;
1821  return max_groups_buffer_entry_guess;
1822 }
Used by Fragmenter classes to store info about each fragment - the fragment id and number of tuples(r...
Definition: Fragmenter.h:86
#define CHECK(condition)
Definition: Logger.h:291
#define VLOG(n)
Definition: Logger.h:388

+ Here is the caller graph for this function:

template<typename T >
std::vector<std::string> anonymous_namespace{Execute.cpp}::expr_container_to_string ( const T &  expr_container)

Definition at line 1923 of file Execute.cpp.

Referenced by operator<<().

1923  {
1924  std::vector<std::string> expr_strs;
1925  for (const auto& expr : expr_container) {
1926  if (!expr) {
1927  expr_strs.emplace_back("NULL");
1928  } else {
1929  expr_strs.emplace_back(expr->toString());
1930  }
1931  }
1932  return expr_strs;
1933 }

+ Here is the caller graph for this function:

template<>
std::vector<std::string> anonymous_namespace{Execute.cpp}::expr_container_to_string ( const std::list< Analyzer::OrderEntry > &  expr_container)

Definition at line 1936 of file Execute.cpp.

1937  {
1938  std::vector<std::string> expr_strs;
1939  for (const auto& expr : expr_container) {
1940  expr_strs.emplace_back(expr.toString());
1941  }
1942  return expr_strs;
1943 }
void anonymous_namespace{Execute.cpp}::fill_entries_for_empty_input ( std::vector< TargetInfo > &  target_infos,
std::vector< int64_t > &  entry,
const std::vector< Analyzer::Expr * > &  target_exprs,
const QueryMemoryDescriptor query_mem_desc 
)

Definition at line 2615 of file Execute.cpp.

References Bitmap, CHECK, g_bigint_count, g_cluster, get_target_info(), QueryMemoryDescriptor::getCountDistinctDescriptor(), QueryMemoryDescriptor::getExecutor(), inline_null_val(), takes_float_argument(), and UnorderedSet.

Referenced by build_row_for_empty_input().

2618  {
2619  for (size_t target_idx = 0; target_idx < target_exprs.size(); ++target_idx) {
2620  const auto target_expr = target_exprs[target_idx];
2621  const auto agg_info = get_target_info(target_expr, g_bigint_count);
2622  CHECK(agg_info.is_agg);
2623  target_infos.push_back(agg_info);
2624  if (g_cluster) {
2625  const auto executor = query_mem_desc.getExecutor();
2626  CHECK(executor);
2627  auto row_set_mem_owner = executor->getRowSetMemoryOwner();
2628  CHECK(row_set_mem_owner);
2629  const auto& count_distinct_desc =
2630  query_mem_desc.getCountDistinctDescriptor(target_idx);
2631  if (count_distinct_desc.impl_type_ == CountDistinctImplType::Bitmap) {
2632  CHECK(row_set_mem_owner);
2633  // TODO: can we detect thread idx here?
2634  constexpr size_t thread_idx{0};
2635  const auto bitmap_size = count_distinct_desc.bitmapPaddedSizeBytes();
2636  row_set_mem_owner->initCountDistinctBufferAllocator(bitmap_size, thread_idx);
2637  auto count_distinct_buffer =
2638  row_set_mem_owner->allocateCountDistinctBuffer(bitmap_size, thread_idx);
2639  entry.push_back(reinterpret_cast<int64_t>(count_distinct_buffer));
2640  continue;
2641  }
2642  if (count_distinct_desc.impl_type_ == CountDistinctImplType::UnorderedSet) {
2643  auto count_distinct_set = new CountDistinctSet();
2644  CHECK(row_set_mem_owner);
2645  row_set_mem_owner->addCountDistinctSet(count_distinct_set);
2646  entry.push_back(reinterpret_cast<int64_t>(count_distinct_set));
2647  continue;
2648  }
2649  }
2650  const bool float_argument_input = takes_float_argument(agg_info);
2651  if (shared::is_any<kCOUNT, kCOUNT_IF, kAPPROX_COUNT_DISTINCT>(agg_info.agg_kind)) {
2652  entry.push_back(0);
2653  } else if (shared::is_any<kAVG>(agg_info.agg_kind)) {
2654  entry.push_back(0);
2655  entry.push_back(0);
2656  } else if (shared::is_any<kSINGLE_VALUE, kSAMPLE>(agg_info.agg_kind)) {
2657  if (agg_info.sql_type.is_geometry() && !agg_info.is_varlen_projection) {
2658  for (int i = 0; i < agg_info.sql_type.get_physical_coord_cols() * 2; i++) {
2659  entry.push_back(0);
2660  }
2661  } else if (agg_info.sql_type.is_varlen()) {
2662  entry.push_back(0);
2663  entry.push_back(0);
2664  } else {
2665  entry.push_back(inline_null_val(agg_info.sql_type, float_argument_input));
2666  }
2667  } else {
2668  entry.push_back(inline_null_val(agg_info.sql_type, float_argument_input));
2669  }
2670  }
2671 }
robin_hood::unordered_set< int64_t > CountDistinctSet
Definition: CountDistinct.h:35
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:106
TargetInfo get_target_info(const Analyzer::Expr *target_expr, const bool bigint_count)
Definition: TargetInfo.h:92
int64_t inline_null_val(const SQLTypeInfo &ti, const bool float_argument_input)
Definition: Execute.cpp:2600
bool g_bigint_count
const CountDistinctDescriptor & getCountDistinctDescriptor(const size_t idx) const
#define CHECK(condition)
Definition: Logger.h:291
bool g_cluster
const Executor * getExecutor() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

size_t anonymous_namespace{Execute.cpp}::get_col_byte_width ( const shared::ColumnKey column_key)

Definition at line 791 of file Execute.cpp.

References Catalog_Namespace::get_metadata_for_column(), and shared::ColumnKey::table_id.

Referenced by Executor::getColumnByteWidthMap().

791  {
792  if (column_key.table_id < 0) {
793  // We have an intermediate results table
794 
795  // Todo(todd): Get more accurate representation of column width
796  // for intermediate tables
797  return size_t(8);
798  } else {
799  const auto cd = Catalog_Namespace::get_metadata_for_column(column_key);
800  const auto& ti = cd->columnType;
801  const auto sz = ti.get_size();
802  if (sz < 0) {
803  // for varlen types, only account for the pointer/size for each row, for now
804  if (ti.is_logical_geo_type()) {
805  // Don't count size for logical geo types, as they are
806  // backed by physical columns
807  return size_t(0);
808  } else {
809  return size_t(16);
810  }
811  } else {
812  return sz;
813  }
814  }
815 }
const ColumnDescriptor * get_metadata_for_column(const ::shared::ColumnKey &column_key)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::tuple<bool, int64_t, int64_t> anonymous_namespace{Execute.cpp}::get_hpt_overflow_underflow_safe_scaled_values ( const int64_t  chunk_min,
const int64_t  chunk_max,
const SQLTypeInfo lhs_type,
const SQLTypeInfo rhs_type 
)

Definition at line 4526 of file Execute.cpp.

References CHECK, SQLTypeInfo::get_dimension(), and DateTimeUtils::get_timestamp_precision_scale().

Referenced by Executor::skipFragment().

4530  {
4531  const int32_t ldim = lhs_type.get_dimension();
4532  const int32_t rdim = rhs_type.get_dimension();
4533  CHECK(ldim != rdim);
4534  const auto scale = DateTimeUtils::get_timestamp_precision_scale(abs(rdim - ldim));
4535  if (ldim > rdim) {
4536  // LHS type precision is more than RHS col type. No chance of overflow/underflow.
4537  return {true, chunk_min / scale, chunk_max / scale};
4538  }
4539 
4540  using checked_int64_t = boost::multiprecision::number<
4541  boost::multiprecision::cpp_int_backend<64,
4542  64,
4543  boost::multiprecision::signed_magnitude,
4544  boost::multiprecision::checked,
4545  void>>;
4546 
4547  try {
4548  auto ret =
4549  std::make_tuple(true,
4550  int64_t(checked_int64_t(chunk_min) * checked_int64_t(scale)),
4551  int64_t(checked_int64_t(chunk_max) * checked_int64_t(scale)));
4552  return ret;
4553  } catch (const std::overflow_error& e) {
4554  // noop
4555  }
4556  return std::make_tuple(false, chunk_min, chunk_max);
4557 }
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 64, 64, boost::multiprecision::signed_magnitude, boost::multiprecision::checked, void >> checked_int64_t
HOST DEVICE int get_dimension() const
Definition: sqltypes.h:393
#define CHECK(condition)
Definition: Logger.h:291
constexpr int64_t get_timestamp_precision_scale(const int32_t dimen)
Definition: DateTimeUtils.h:51

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ResultSetPtr anonymous_namespace{Execute.cpp}::get_merged_result ( std::vector< std::pair< ResultSetPtr, std::vector< size_t >>> &  results_per_device,
std::vector< TargetInfo > const &  targets 
)

Definition at line 1535 of file Execute.cpp.

References CHECK, and result_set::first_dict_encoded_idx().

Referenced by Executor::resultsUnion().

1537  {
1538  auto& first = results_per_device.front().first;
1539  CHECK(first);
1540  auto const first_target_idx = result_set::first_dict_encoded_idx(targets);
1541  if (first_target_idx) {
1542  first->translateDictEncodedColumns(targets, *first_target_idx);
1543  }
1544  for (size_t dev_idx = 1; dev_idx < results_per_device.size(); ++dev_idx) {
1545  const auto& next = results_per_device[dev_idx].first;
1546  CHECK(next);
1547  if (first_target_idx) {
1548  next->translateDictEncodedColumns(targets, *first_target_idx);
1549  }
1550  first->append(*next);
1551  }
1552  return std::move(first);
1553 }
std::optional< size_t > first_dict_encoded_idx(std::vector< TargetInfo > const &)
Definition: ResultSet.cpp:1593
#define CHECK(condition)
Definition: Logger.h:291

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ReductionCode anonymous_namespace{Execute.cpp}::get_reduction_code ( const size_t  executor_id,
std::vector< std::pair< ResultSetPtr, std::vector< size_t >>> &  results_per_device,
int64_t *  compilation_queue_time 
)

Definition at line 1647 of file Execute.cpp.

References ResultSetReductionJIT::codegen(), timer_start(), and timer_stop().

Referenced by Executor::reduceMultiDeviceResultSets().

1650  {
1651  auto clock_begin = timer_start();
1652  // ResultSetReductionJIT::codegen compilation-locks if new code will be generated
1653  *compilation_queue_time = timer_stop(clock_begin);
1654  const auto& this_result_set = results_per_device[0].first;
1655  ResultSetReductionJIT reduction_jit(this_result_set->getQueryMemDesc(),
1656  this_result_set->getTargetInfos(),
1657  this_result_set->getTargetInitVals(),
1658  executor_id);
1659  return reduction_jit.codegen();
1660 };
TypeR::rep timer_stop(Type clock_begin)
Definition: measure.h:48
virtual ReductionCode codegen() const
Type timer_start()
Definition: measure.h:42

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::list<std::shared_ptr<const InputColDescriptor> > anonymous_namespace{Execute.cpp}::get_selected_input_col_descs ( const shared::TableKey table_key,
std::list< std::shared_ptr< InputColDescriptor const >> const &  input_col_descs 
)

Definition at line 3614 of file Execute.cpp.

Referenced by Executor::fetchUnionChunks().

3616  {
3617  std::list<std::shared_ptr<const InputColDescriptor>> selected;
3618  for (auto const& input_col_desc : input_col_descs) {
3619  if (table_key == input_col_desc->getScanDesc().getTableKey()) {
3620  selected.push_back(input_col_desc);
3621  }
3622  }
3623  return selected;
3624 }

+ Here is the caller graph for this function:

size_t anonymous_namespace{Execute.cpp}::get_selected_input_col_descs_index ( const shared::TableKey table_key,
std::list< std::shared_ptr< InputColDescriptor const >> const &  input_col_descs 
)

Definition at line 3603 of file Execute.cpp.

Referenced by Executor::fetchUnionChunks().

3605  {
3606  auto const has_table_key = [&table_key](auto const& input_desc) {
3607  return table_key == input_desc->getScanDesc().getTableKey();
3608  };
3609  return std::distance(
3610  input_col_descs.begin(),
3611  std::find_if(input_col_descs.begin(), input_col_descs.end(), has_table_key));
3612 }

+ Here is the caller graph for this function:

size_t anonymous_namespace{Execute.cpp}::get_selected_input_descs_index ( const shared::TableKey table_key,
std::vector< InputDescriptor > const &  input_descs 
)

Definition at line 3594 of file Execute.cpp.

Referenced by Executor::fetchUnionChunks().

3595  {
3596  auto const has_table_key = [&table_key](InputDescriptor const& input_desc) {
3597  return table_key == input_desc.getTableKey();
3598  };
3599  return std::find_if(input_descs.begin(), input_descs.end(), has_table_key) -
3600  input_descs.begin();
3601 }

+ Here is the caller graph for this function:

std::string anonymous_namespace{Execute.cpp}::get_table_name ( const InputDescriptor input_desc)

Definition at line 1824 of file Execute.cpp.

References CHECK, CHECK_GT, Catalog_Namespace::get_metadata_for_table(), InputDescriptor::getSourceType(), InputDescriptor::getTableKey(), TABLE, shared::TableKey::table_id, and to_string().

1824  {
1825  const auto source_type = input_desc.getSourceType();
1826  if (source_type == InputSourceType::TABLE) {
1827  const auto& table_key = input_desc.getTableKey();
1828  CHECK_GT(table_key.table_id, 0);
1829  const auto td = Catalog_Namespace::get_metadata_for_table(table_key);
1830  CHECK(td);
1831  return td->tableName;
1832  } else {
1833  return "$TEMPORARY_TABLE" + std::to_string(-input_desc.getTableKey().table_id);
1834  }
1835 }
const TableDescriptor * get_metadata_for_table(const ::shared::TableKey &table_key, bool populate_fragmenter)
#define CHECK_GT(x, y)
Definition: Logger.h:305
std::string to_string(char const *&&v)
const shared::TableKey & getTableKey() const
InputSourceType getSourceType() const
#define CHECK(condition)
Definition: Logger.h:291

+ Here is the call graph for this function:

size_t anonymous_namespace{Execute.cpp}::getDeviceBasedWatchdogScanLimit ( size_t  watchdog_max_projected_rows_per_device,
const ExecutorDeviceType  device_type,
const int  device_count 
)
inline

Definition at line 1837 of file Execute.cpp.

References GPU.

Referenced by checkWorkUnitWatchdog().

1840  {
1841  if (device_type == ExecutorDeviceType::GPU) {
1842  return device_count * watchdog_max_projected_rows_per_device;
1843  }
1844  return watchdog_max_projected_rows_per_device;
1845 }

+ Here is the caller graph for this function:

bool anonymous_namespace{Execute.cpp}::has_lazy_fetched_columns ( const std::vector< ColumnLazyFetchInfo > &  fetched_cols)

Definition at line 2896 of file Execute.cpp.

Referenced by Executor::createKernels().

2896  {
2897  for (const auto& col : fetched_cols) {
2898  if (col.is_lazily_fetched) {
2899  return true;
2900  }
2901  }
2902  return false;
2903 }

+ Here is the caller graph for this function:

int64_t anonymous_namespace{Execute.cpp}::inline_null_val ( const SQLTypeInfo ti,
const bool  float_argument_input 
)

Definition at line 2600 of file Execute.cpp.

References CHECK, SQLTypeInfo::get_type(), inline_fp_null_val(), inline_int_null_val(), SQLTypeInfo::is_boolean(), SQLTypeInfo::is_fp(), SQLTypeInfo::is_number(), SQLTypeInfo::is_string(), SQLTypeInfo::is_time(), and kFLOAT.

Referenced by fill_entries_for_empty_input().

2600  {
2601  CHECK(ti.is_number() || ti.is_time() || ti.is_boolean() || ti.is_string());
2602  if (ti.is_fp()) {
2603  if (float_argument_input && ti.get_type() == kFLOAT) {
2604  int64_t float_null_val = 0;
2605  *reinterpret_cast<float*>(may_alias_ptr(&float_null_val)) =
2606  static_cast<float>(inline_fp_null_val(ti));
2607  return float_null_val;
2608  }
2609  const auto double_null_val = inline_fp_null_val(ti);
2610  return *reinterpret_cast<const int64_t*>(may_alias_ptr(&double_null_val));
2611  }
2612  return inline_int_null_val(ti);
2613 }
bool is_fp() const
Definition: sqltypes.h:573
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:391
bool is_number() const
Definition: sqltypes.h:576
double inline_fp_null_val(const SQL_TYPE_INFO &ti)
bool is_time() const
Definition: sqltypes.h:579
bool is_boolean() const
Definition: sqltypes.h:582
#define CHECK(condition)
Definition: Logger.h:291
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
bool is_string() const
Definition: sqltypes.h:561

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool anonymous_namespace{Execute.cpp}::is_empty_table ( Fragmenter_Namespace::AbstractFragmenter fragmenter)

Definition at line 227 of file Execute.cpp.

Referenced by foreign_storage::populate_string_dictionary().

227  {
228  const auto& fragments = fragmenter->getFragmentsForQuery().fragments;
229  // The fragmenter always returns at least one fragment, even when the table is empty.
230  return (fragments.size() == 1 && fragments[0].getChunkMetadataMap().empty());
231 }
std::vector< FragmentInfo > fragments
Definition: Fragmenter.h:171
virtual TableInfo getFragmentsForQuery()=0
Get all fragments for the current table.

+ Here is the caller graph for this function:

void anonymous_namespace{Execute.cpp}::log_system_memory_info_impl ( std::string const &  mem_log,
size_t  executor_id,
size_t  log_time_ms,
std::string const &  log_tag,
size_t const  thread_idx 
)

Definition at line 752 of file Execute.cpp.

References VLOG.

Referenced by Executor::logSystemCPUMemoryStatus(), and Executor::logSystemGPUMemoryStatus().

756  {
757  std::ostringstream oss;
758  oss << mem_log;
759  oss << " (" << log_tag << ", EXECUTOR-" << executor_id << ", THREAD-" << thread_idx
760  << ", TOOK: " << log_time_ms << " ms)";
761  VLOG(1) << oss.str();
762 }
#define VLOG(n)
Definition: Logger.h:388

+ Here is the caller graph for this function:

size_t anonymous_namespace{Execute.cpp}::permute_storage_columnar ( const ResultSetStorage input_storage,
const QueryMemoryDescriptor input_query_mem_desc,
const ResultSetStorage output_storage,
size_t  output_row_index,
const QueryMemoryDescriptor output_query_mem_desc,
const std::vector< uint32_t > &  top_permutation 
)

This functions uses the permutation indices in "top_permutation", and permutes all group columns (if any) and aggregate columns into the output storage. In columnar layout, since different columns are not consecutive in the memory, different columns are copied back into the output storage separetely and through different memcpy operations.

output_row_index contains the current index of the output storage (input storage will be appended to it), and the final output row index is returned.

Definition at line 2759 of file Execute.cpp.

References QueryMemoryDescriptor::getColOffInBytes(), QueryMemoryDescriptor::getKeyCount(), QueryMemoryDescriptor::getPaddedSlotWidthBytes(), QueryMemoryDescriptor::getPrependedGroupColOffInBytes(), QueryMemoryDescriptor::getSlotCount(), ResultSetStorage::getUnderlyingBuffer(), and QueryMemoryDescriptor::groupColWidth().

Referenced by Executor::collectAllDeviceShardedTopResults().

2764  {
2765  const auto output_buffer = output_storage->getUnderlyingBuffer();
2766  const auto input_buffer = input_storage->getUnderlyingBuffer();
2767  for (const auto sorted_idx : top_permutation) {
2768  // permuting all group-columns in this result set into the final buffer:
2769  for (size_t group_idx = 0; group_idx < input_query_mem_desc.getKeyCount();
2770  group_idx++) {
2771  const auto input_column_ptr =
2772  input_buffer + input_query_mem_desc.getPrependedGroupColOffInBytes(group_idx) +
2773  sorted_idx * input_query_mem_desc.groupColWidth(group_idx);
2774  const auto output_column_ptr =
2775  output_buffer +
2776  output_query_mem_desc.getPrependedGroupColOffInBytes(group_idx) +
2777  output_row_index * output_query_mem_desc.groupColWidth(group_idx);
2778  memcpy(output_column_ptr,
2779  input_column_ptr,
2780  output_query_mem_desc.groupColWidth(group_idx));
2781  }
2782  // permuting all agg-columns in this result set into the final buffer:
2783  for (size_t slot_idx = 0; slot_idx < input_query_mem_desc.getSlotCount();
2784  slot_idx++) {
2785  const auto input_column_ptr =
2786  input_buffer + input_query_mem_desc.getColOffInBytes(slot_idx) +
2787  sorted_idx * input_query_mem_desc.getPaddedSlotWidthBytes(slot_idx);
2788  const auto output_column_ptr =
2789  output_buffer + output_query_mem_desc.getColOffInBytes(slot_idx) +
2790  output_row_index * output_query_mem_desc.getPaddedSlotWidthBytes(slot_idx);
2791  memcpy(output_column_ptr,
2792  input_column_ptr,
2793  output_query_mem_desc.getPaddedSlotWidthBytes(slot_idx));
2794  }
2795  ++output_row_index;
2796  }
2797  return output_row_index;
2798 }
int8_t * getUnderlyingBuffer() const
int8_t groupColWidth(const size_t key_idx) const
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
size_t getColOffInBytes(const size_t col_idx) const
size_t getPrependedGroupColOffInBytes(const size_t group_idx) const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

size_t anonymous_namespace{Execute.cpp}::permute_storage_row_wise ( const ResultSetStorage input_storage,
const ResultSetStorage output_storage,
size_t  output_row_index,
const QueryMemoryDescriptor output_query_mem_desc,
const std::vector< uint32_t > &  top_permutation 
)

This functions uses the permutation indices in "top_permutation", and permutes all group columns (if any) and aggregate columns into the output storage. In row-wise, since different columns are consecutive within the memory, it suffices to perform a single memcpy operation and copy the whole row.

output_row_index contains the current index of the output storage (input storage will be appended to it), and the final output row index is returned.

Definition at line 2809 of file Execute.cpp.

References QueryMemoryDescriptor::getRowSize(), and ResultSetStorage::getUnderlyingBuffer().

Referenced by Executor::collectAllDeviceShardedTopResults().

2813  {
2814  const auto output_buffer = output_storage->getUnderlyingBuffer();
2815  const auto input_buffer = input_storage->getUnderlyingBuffer();
2816  for (const auto sorted_idx : top_permutation) {
2817  const auto row_ptr = input_buffer + sorted_idx * output_query_mem_desc.getRowSize();
2818  memcpy(output_buffer + output_row_index * output_query_mem_desc.getRowSize(),
2819  row_ptr,
2820  output_query_mem_desc.getRowSize());
2821  ++output_row_index;
2822  }
2823  return output_row_index;
2824 }
int8_t * getUnderlyingBuffer() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void anonymous_namespace{Execute.cpp}::prepare_string_dictionaries ( const std::unordered_set< PhysicalInput > &  phys_inputs)

Definition at line 221 of file Execute.cpp.

Referenced by Executor::computeStringDictionaryGenerations(), and anonymous_namespace{RelAlgExecutor.cpp}::prepare_foreign_table_for_execution().

221  {
222  for (const auto [col_id, table_id, db_id] : phys_inputs) {
223  foreign_storage::populate_string_dictionary(table_id, col_id, db_id);
224  }
225 }
void populate_string_dictionary(int32_t table_id, int32_t col_id, int32_t db_id)
Definition: Execute.cpp:237

+ Here is the caller graph for this function:

RelAlgExecutionUnit anonymous_namespace{Execute.cpp}::replace_scan_limit ( const RelAlgExecutionUnit ra_exe_unit_in,
const size_t  new_scan_limit 
)

Definition at line 2075 of file Execute.cpp.

References RelAlgExecutionUnit::estimator, RelAlgExecutionUnit::groupby_exprs, RelAlgExecutionUnit::hash_table_build_plan_dag, RelAlgExecutionUnit::input_col_descs, RelAlgExecutionUnit::input_descs, RelAlgExecutionUnit::join_quals, RelAlgExecutionUnit::quals, RelAlgExecutionUnit::query_hint, RelAlgExecutionUnit::query_plan_dag_hash, RelAlgExecutionUnit::query_state, RelAlgExecutionUnit::simple_quals, RelAlgExecutionUnit::sort_info, RelAlgExecutionUnit::table_id_to_node_map, RelAlgExecutionUnit::target_exprs, RelAlgExecutionUnit::target_exprs_original_type_infos, RelAlgExecutionUnit::union_all, and RelAlgExecutionUnit::use_bump_allocator.

Referenced by Executor::executeWorkUnit().

2076  {
2077  return {ra_exe_unit_in.input_descs,
2078  ra_exe_unit_in.input_col_descs,
2079  ra_exe_unit_in.simple_quals,
2080  ra_exe_unit_in.quals,
2081  ra_exe_unit_in.join_quals,
2082  ra_exe_unit_in.groupby_exprs,
2083  ra_exe_unit_in.target_exprs,
2084  ra_exe_unit_in.target_exprs_original_type_infos,
2085  ra_exe_unit_in.estimator,
2086  ra_exe_unit_in.sort_info,
2087  new_scan_limit,
2088  ra_exe_unit_in.query_hint,
2089  ra_exe_unit_in.query_plan_dag_hash,
2090  ra_exe_unit_in.hash_table_build_plan_dag,
2091  ra_exe_unit_in.table_id_to_node_map,
2092  ra_exe_unit_in.use_bump_allocator,
2093  ra_exe_unit_in.union_all,
2094  ra_exe_unit_in.query_state};
2095 }
std::vector< Analyzer::Expr * > target_exprs
QueryPlanHash query_plan_dag_hash
const std::optional< bool > union_all
std::vector< InputDescriptor > input_descs
const std::list< std::shared_ptr< Analyzer::Expr > > groupby_exprs
const JoinQualsPerNestingLevel join_quals
TableIdToNodeMap table_id_to_node_map
const std::shared_ptr< Analyzer::Estimator > estimator
std::unordered_map< size_t, SQLTypeInfo > target_exprs_original_type_infos
std::list< std::shared_ptr< Analyzer::Expr > > quals
RegisteredQueryHint query_hint
std::shared_ptr< const query_state::QueryState > query_state
std::list< std::shared_ptr< const InputColDescriptor > > input_col_descs
std::list< std::shared_ptr< Analyzer::Expr > > simple_quals
HashTableBuildDagMap hash_table_build_plan_dag

+ Here is the caller graph for this function:

void anonymous_namespace{Execute.cpp}::set_mod_range ( std::vector< int8_t const * > &  frag_col_buffers,
int8_t const *const  ptr,
size_t const  local_col_id,
size_t const  N 
)

Definition at line 3627 of file Execute.cpp.

References CHECK_LE, and anonymous_namespace{Utm.h}::N.

Referenced by Executor::fetchUnionChunks().

3630  {
3631  size_t const begin = local_col_id - local_col_id % N; // N divides begin
3632  size_t const end = begin + N;
3633  CHECK_LE(end, frag_col_buffers.size()) << (void*)ptr << ' ' << local_col_id << ' ' << N;
3634  for (size_t i = begin; i < end; ++i) {
3635  frag_col_buffers[i] = ptr;
3636  }
3637 }
#define CHECK_LE(x, y)
Definition: Logger.h:304
constexpr unsigned N
Definition: Utm.h:110

+ Here is the caller graph for this function:

std::string anonymous_namespace{Execute.cpp}::sort_algorithm_to_string ( const SortAlgorithm  algorithm)

Definition at line 1945 of file Execute.cpp.

References Default, SpeculativeTopN, StreamingTopN, and UNREACHABLE.

Referenced by operator<<().

1945  {
1946  switch (algorithm) {
1948  return "ResultSet";
1950  return "Speculative Top N";
1952  return "Streaming Top N";
1953  }
1954  UNREACHABLE();
1955  return "";
1956 }
#define UNREACHABLE()
Definition: Logger.h:338

+ Here is the caller graph for this function:

const ColumnDescriptor* anonymous_namespace{Execute.cpp}::try_get_column_descriptor ( const InputColDescriptor col_desc)

Definition at line 3340 of file Execute.cpp.

References get_column_descriptor_maybe(), InputColDescriptor::getColId(), InputColDescriptor::getScanDesc(), and InputDescriptor::getTableKey().

Referenced by Executor::fetchChunks(), and Executor::fetchUnionChunks().

3340  {
3341  const auto& table_key = col_desc->getScanDesc().getTableKey();
3342  const auto col_id = col_desc->getColId();
3343  return get_column_descriptor_maybe({table_key, col_id});
3344 }
const ColumnDescriptor * get_column_descriptor_maybe(const shared::ColumnKey &column_key)
Definition: Execute.h:241
int getColId() const
const shared::TableKey & getTableKey() const
const InputDescriptor & getScanDesc() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function: