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

Classes

class  OutVecOwner
 

Functions

ResultSetPtr get_merged_result (std::vector< std::pair< ResultSetPtr, std::vector< size_t >>> &results_per_device)
 
ReductionCode get_reduction_code (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)
 
std::string get_table_name (const InputDescriptor &input_desc, const Catalog_Namespace::Catalog &cat)
 
size_t getDeviceBasedScanLimit (const ExecutorDeviceType device_type, const int device_count)
 
void checkWorkUnitWatchdog (const RelAlgExecutionUnit &ra_exe_unit, const std::vector< InputTableInfo > &table_infos, const Catalog_Namespace::Catalog &cat, 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 join_type_to_string (const JoinType type)
 
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, const Catalog_Namespace::Catalog &cat)
 
bool check_rows_less_than_needed (const ResultSetPtr &results, const size_t scan_limit)
 
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

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 1755 of file Execute.cpp.

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

Referenced by Executor::collectAllDeviceResults().

1758  {
1759  std::vector<std::shared_ptr<Analyzer::Expr>> target_exprs_owned_copies;
1760  std::vector<Analyzer::Expr*> target_exprs;
1761  for (const auto target_expr : target_exprs_in) {
1762  const auto target_expr_copy =
1763  std::dynamic_pointer_cast<Analyzer::AggExpr>(target_expr->deep_copy());
1764  CHECK(target_expr_copy);
1765  auto ti = target_expr->get_type_info();
1766  ti.set_notnull(false);
1767  target_expr_copy->set_type_info(ti);
1768  if (target_expr_copy->get_arg()) {
1769  auto arg_ti = target_expr_copy->get_arg()->get_type_info();
1770  arg_ti.set_notnull(false);
1771  target_expr_copy->get_arg()->set_type_info(arg_ti);
1772  }
1773  target_exprs_owned_copies.push_back(target_expr_copy);
1774  target_exprs.push_back(target_expr_copy.get());
1775  }
1776  std::vector<TargetInfo> target_infos;
1777  std::vector<int64_t> entry;
1778  fill_entries_for_empty_input(target_infos, entry, target_exprs, query_mem_desc);
1779  const auto executor = query_mem_desc.getExecutor();
1780  CHECK(executor);
1781  auto row_set_mem_owner = executor->getRowSetMemoryOwner();
1782  CHECK(row_set_mem_owner);
1783  auto rs = std::make_shared<ResultSet>(target_infos,
1784  device_type,
1786  row_set_mem_owner,
1787  executor->getCatalog(),
1788  executor->blockSize(),
1789  executor->gridSize());
1790  rs->allocateStorage();
1791  rs->fillOneEntry(entry);
1792  return rs;
1793 }
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:1701
#define CHECK(condition)
Definition: Logger.h:197
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 2890 of file Execute.cpp.

References CHECK.

Referenced by Executor::executePlanWithGroupBy().

2890  {
2891  CHECK(scan_limit);
2892  return results && results->rowCount() < scan_limit;
2893 }
#define CHECK(condition)
Definition: Logger.h:197

+ 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 Catalog_Namespace::Catalog cat,
const ExecutorDeviceType  device_type,
const int  device_count 
)

Definition at line 1104 of file Execute.cpp.

References SortInfo::algorithm, get_table_name(), getDeviceBasedScanLimit(), RelAlgExecutionUnit::groupby_exprs, Executor::high_scan_limit, RelAlgExecutionUnit::input_descs, join(), RelAlgExecutionUnit::scan_limit, RelAlgExecutionUnit::sort_info, StreamingTopN, RelAlgExecutionUnit::target_exprs, to_string(), and RelAlgExecutionUnit::use_bump_allocator.

Referenced by Executor::createKernels().

1108  {
1109  for (const auto target_expr : ra_exe_unit.target_exprs) {
1110  if (dynamic_cast<const Analyzer::AggExpr*>(target_expr)) {
1111  return;
1112  }
1113  }
1114  if (!ra_exe_unit.scan_limit && table_infos.size() == 1 &&
1115  table_infos.front().info.getPhysicalNumTuples() < Executor::high_scan_limit) {
1116  // Allow a query with no scan limit to run on small tables
1117  return;
1118  }
1119  if (ra_exe_unit.use_bump_allocator) {
1120  // Bump allocator removes the scan limit (and any knowledge of the size of the output
1121  // relative to the size of the input), so we bypass this check for now
1122  return;
1123  }
1124  if (ra_exe_unit.sort_info.algorithm != SortAlgorithm::StreamingTopN &&
1125  ra_exe_unit.groupby_exprs.size() == 1 && !ra_exe_unit.groupby_exprs.front() &&
1126  (!ra_exe_unit.scan_limit ||
1127  ra_exe_unit.scan_limit > getDeviceBasedScanLimit(device_type, device_count))) {
1128  std::vector<std::string> table_names;
1129  const auto& input_descs = ra_exe_unit.input_descs;
1130  for (const auto& input_desc : input_descs) {
1131  table_names.push_back(get_table_name(input_desc, cat));
1132  }
1133  if (!ra_exe_unit.scan_limit) {
1134  throw WatchdogException(
1135  "Projection query would require a scan without a limit on table(s): " +
1136  boost::algorithm::join(table_names, ", "));
1137  } else {
1138  throw WatchdogException(
1139  "Projection query output result set on table(s): " +
1140  boost::algorithm::join(table_names, ", ") + " would contain " +
1141  std::to_string(ra_exe_unit.scan_limit) +
1142  " rows, which is more than the current system limit of " +
1143  std::to_string(getDeviceBasedScanLimit(device_type, device_count)));
1144  }
1145  }
1146 }
std::vector< Analyzer::Expr * > target_exprs
std::string get_table_name(const InputDescriptor &input_desc, const Catalog_Namespace::Catalog &cat)
Definition: Execute.cpp:1084
std::string join(T const &container, std::string const &delim)
std::vector< InputDescriptor > input_descs
const SortAlgorithm algorithm
const std::list< std::shared_ptr< Analyzer::Expr > > groupby_exprs
std::string to_string(char const *&&v)
static const size_t high_scan_limit
Definition: Execute.h:461
const SortInfo sort_info
size_t getDeviceBasedScanLimit(const ExecutorDeviceType device_type, const int device_count)
Definition: Execute.cpp:1096

+ 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)

Definition at line 1054 of file Execute.cpp.

References CHECK.

Referenced by Executor::executeWorkUnitImpl().

1054  {
1056  // Check for overflows since we're multiplying potentially big table sizes.
1057  using checked_size_t = boost::multiprecision::number<
1058  boost::multiprecision::cpp_int_backend<64,
1059  64,
1060  boost::multiprecision::unsigned_magnitude,
1061  boost::multiprecision::checked,
1062  void>>;
1063  checked_size_t max_groups_buffer_entry_guess = 1;
1064  for (const auto& query_info : query_infos) {
1065  CHECK(!query_info.info.fragments.empty());
1066  auto it = std::max_element(query_info.info.fragments.begin(),
1067  query_info.info.fragments.end(),
1068  [](const FragmentInfo& f1, const FragmentInfo& f2) {
1069  return f1.getNumTuples() < f2.getNumTuples();
1070  });
1071  max_groups_buffer_entry_guess *= it->getNumTuples();
1072  }
1073  // Cap the rough approximation to 100M entries, it's unlikely we can do a great job for
1074  // baseline group layout with that many entries anyway.
1075  constexpr size_t max_groups_buffer_entry_guess_cap = 100000000;
1076  try {
1077  return std::min(static_cast<size_t>(max_groups_buffer_entry_guess),
1078  max_groups_buffer_entry_guess_cap);
1079  } catch (...) {
1080  return max_groups_buffer_entry_guess_cap;
1081  }
1082 }
Used by Fragmenter classes to store info about each fragment - the fragment id and number of tuples(r...
Definition: Fragmenter.h:78
#define CHECK(condition)
Definition: Logger.h:197

+ 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 1175 of file Execute.cpp.

Referenced by operator<<().

1175  {
1176  std::vector<std::string> expr_strs;
1177  for (const auto& expr : expr_container) {
1178  if (!expr) {
1179  expr_strs.emplace_back("NULL");
1180  } else {
1181  expr_strs.emplace_back(expr->toString());
1182  }
1183  }
1184  return expr_strs;
1185 }

+ 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 1188 of file Execute.cpp.

1189  {
1190  std::vector<std::string> expr_strs;
1191  for (const auto& expr : expr_container) {
1192  expr_strs.emplace_back(expr.toString());
1193  }
1194  return expr_strs;
1195 }
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 1701 of file Execute.cpp.

References Bitmap, CHECK, g_bigint_count, g_cluster, get_target_info(), QueryMemoryDescriptor::getCountDistinctDescriptor(), QueryMemoryDescriptor::getExecutor(), inline_null_val(), kAPPROX_COUNT_DISTINCT, kAVG, kCOUNT, kSAMPLE, kSINGLE_VALUE, StdSet, and takes_float_argument().

Referenced by build_row_for_empty_input().

1704  {
1705  for (size_t target_idx = 0; target_idx < target_exprs.size(); ++target_idx) {
1706  const auto target_expr = target_exprs[target_idx];
1707  const auto agg_info = get_target_info(target_expr, g_bigint_count);
1708  CHECK(agg_info.is_agg);
1709  target_infos.push_back(agg_info);
1710  if (g_cluster) {
1711  const auto executor = query_mem_desc.getExecutor();
1712  CHECK(executor);
1713  auto row_set_mem_owner = executor->getRowSetMemoryOwner();
1714  CHECK(row_set_mem_owner);
1715  const auto& count_distinct_desc =
1716  query_mem_desc.getCountDistinctDescriptor(target_idx);
1717  if (count_distinct_desc.impl_type_ == CountDistinctImplType::Bitmap) {
1718  CHECK(row_set_mem_owner);
1719  auto count_distinct_buffer = row_set_mem_owner->allocateCountDistinctBuffer(
1720  count_distinct_desc.bitmapPaddedSizeBytes());
1721  entry.push_back(reinterpret_cast<int64_t>(count_distinct_buffer));
1722  continue;
1723  }
1724  if (count_distinct_desc.impl_type_ == CountDistinctImplType::StdSet) {
1725  auto count_distinct_set = new std::set<int64_t>();
1726  CHECK(row_set_mem_owner);
1727  row_set_mem_owner->addCountDistinctSet(count_distinct_set);
1728  entry.push_back(reinterpret_cast<int64_t>(count_distinct_set));
1729  continue;
1730  }
1731  }
1732  const bool float_argument_input = takes_float_argument(agg_info);
1733  if (agg_info.agg_kind == kCOUNT || agg_info.agg_kind == kAPPROX_COUNT_DISTINCT) {
1734  entry.push_back(0);
1735  } else if (agg_info.agg_kind == kAVG) {
1736  entry.push_back(inline_null_val(agg_info.sql_type, float_argument_input));
1737  entry.push_back(0);
1738  } else if (agg_info.agg_kind == kSINGLE_VALUE || agg_info.agg_kind == kSAMPLE) {
1739  if (agg_info.sql_type.is_geometry()) {
1740  for (int i = 0; i < agg_info.sql_type.get_physical_coord_cols() * 2; i++) {
1741  entry.push_back(0);
1742  }
1743  } else if (agg_info.sql_type.is_varlen()) {
1744  entry.push_back(0);
1745  entry.push_back(0);
1746  } else {
1747  entry.push_back(inline_null_val(agg_info.sql_type, float_argument_input));
1748  }
1749  } else {
1750  entry.push_back(inline_null_val(agg_info.sql_type, float_argument_input));
1751  }
1752  }
1753 }
TargetInfo get_target_info(const PointerType target_expr, const bool bigint_count)
Definition: TargetInfo.h:79
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:134
int64_t inline_null_val(const SQLTypeInfo &ti, const bool float_argument_input)
Definition: Execute.cpp:1686
bool g_bigint_count
const CountDistinctDescriptor & getCountDistinctDescriptor(const size_t idx) const
Definition: sqldefs.h:76
#define CHECK(condition)
Definition: Logger.h:197
bool g_cluster
Definition: sqldefs.h:72
const Executor * getExecutor() const

+ 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 3295 of file Execute.cpp.

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

Referenced by Executor::skipFragment().

3299  {
3300  const int32_t ldim = lhs_type.get_dimension();
3301  const int32_t rdim = rhs_type.get_dimension();
3302  CHECK(ldim != rdim);
3303  const auto scale = DateTimeUtils::get_timestamp_precision_scale(abs(rdim - ldim));
3304  if (ldim > rdim) {
3305  // LHS type precision is more than RHS col type. No chance of overflow/underflow.
3306  return {true, chunk_min / scale, chunk_max / scale};
3307  }
3308 
3309  using checked_int64_t = boost::multiprecision::number<
3310  boost::multiprecision::cpp_int_backend<64,
3311  64,
3312  boost::multiprecision::signed_magnitude,
3313  boost::multiprecision::checked,
3314  void>>;
3315 
3316  try {
3317  auto ret =
3318  std::make_tuple(true,
3319  int64_t(checked_int64_t(chunk_min) * checked_int64_t(scale)),
3320  int64_t(checked_int64_t(chunk_max) * checked_int64_t(scale)));
3321  return ret;
3322  } catch (const std::overflow_error& e) {
3323  // noop
3324  }
3325  return std::make_tuple(false, chunk_min, chunk_max);
3326 }
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:313
#define CHECK(condition)
Definition: Logger.h:197
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)

Definition at line 854 of file Execute.cpp.

References CHECK.

Referenced by Executor::resultsUnion().

855  {
856  auto& first = results_per_device.front().first;
857  CHECK(first);
858  for (size_t dev_idx = 1; dev_idx < results_per_device.size(); ++dev_idx) {
859  const auto& next = results_per_device[dev_idx].first;
860  CHECK(next);
861  first->append(*next);
862  }
863  return std::move(first);
864 }
#define CHECK(condition)
Definition: Logger.h:197

+ Here is the caller graph for this function:

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

Definition at line 928 of file Execute.cpp.

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

Referenced by Executor::reduceMultiDeviceResultSets().

930  {
931  auto clock_begin = timer_start();
932  std::lock_guard<std::mutex> compilation_lock(Executor::compilation_mutex_);
933  *compilation_queue_time = timer_stop(clock_begin);
934  const auto& this_result_set = results_per_device[0].first;
935  ResultSetReductionJIT reduction_jit(this_result_set->getQueryMemDesc(),
936  this_result_set->getTargetInfos(),
937  this_result_set->getTargetInitVals());
938  return reduction_jit.codegen();
939 };
TypeR::rep timer_stop(Type clock_begin)
Definition: measure.h:48
virtual ReductionCode codegen() const
static std::mutex compilation_mutex_
Definition: Execute.h:1084
Type timer_start()
Definition: measure.h:42

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::string anonymous_namespace{Execute.cpp}::get_table_name ( const InputDescriptor input_desc,
const Catalog_Namespace::Catalog cat 
)

Definition at line 1084 of file Execute.cpp.

References CHECK, Catalog_Namespace::Catalog::getMetadataForTable(), InputDescriptor::getSourceType(), InputDescriptor::getTableId(), TABLE, and to_string().

Referenced by checkWorkUnitWatchdog().

1085  {
1086  const auto source_type = input_desc.getSourceType();
1087  if (source_type == InputSourceType::TABLE) {
1088  const auto td = cat.getMetadataForTable(input_desc.getTableId());
1089  CHECK(td);
1090  return td->tableName;
1091  } else {
1092  return "$TEMPORARY_TABLE" + std::to_string(-input_desc.getTableId());
1093  }
1094 }
std::string to_string(char const *&&v)
int getTableId() const
InputSourceType getSourceType() const
#define CHECK(condition)
Definition: Logger.h:197
const TableDescriptor * getMetadataForTable(const std::string &tableName, const bool populateFragmenter=true) const
Returns a pointer to a const TableDescriptor struct matching the provided tableName.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 1096 of file Execute.cpp.

References GPU, and Executor::high_scan_limit.

Referenced by checkWorkUnitWatchdog().

1097  {
1098  if (device_type == ExecutorDeviceType::GPU) {
1099  return device_count * Executor::high_scan_limit;
1100  }
1102 }
static const size_t high_scan_limit
Definition: Execute.h:461

+ 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 1977 of file Execute.cpp.

Referenced by Executor::createKernels().

1977  {
1978  for (const auto& col : fetched_cols) {
1979  if (col.is_lazily_fetched) {
1980  return true;
1981  }
1982  }
1983  return false;
1984 }

+ 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 1686 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().

1686  {
1687  CHECK(ti.is_number() || ti.is_time() || ti.is_boolean() || ti.is_string());
1688  if (ti.is_fp()) {
1689  if (float_argument_input && ti.get_type() == kFLOAT) {
1690  int64_t float_null_val = 0;
1691  *reinterpret_cast<float*>(may_alias_ptr(&float_null_val)) =
1692  static_cast<float>(inline_fp_null_val(ti));
1693  return float_null_val;
1694  }
1695  const auto double_null_val = inline_fp_null_val(ti);
1696  return *reinterpret_cast<const int64_t*>(may_alias_ptr(&double_null_val));
1697  }
1698  return inline_int_null_val(ti);
1699 }
bool is_fp() const
Definition: sqltypes.h:482
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:311
bool is_number() const
Definition: sqltypes.h:483
double inline_fp_null_val(const SQL_TYPE_INFO &ti)
bool is_time() const
Definition: sqltypes.h:484
bool is_boolean() const
Definition: sqltypes.h:485
#define CHECK(condition)
Definition: Logger.h:197
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
bool is_string() const
Definition: sqltypes.h:478

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::string anonymous_namespace{Execute.cpp}::join_type_to_string ( const JoinType  type)

Definition at line 1197 of file Execute.cpp.

References INNER, INVALID, LEFT, and UNREACHABLE.

Referenced by operator<<(), and ra_exec_unit_desc_for_caching().

1197  {
1198  switch (type) {
1199  case JoinType::INNER:
1200  return "INNER";
1201  case JoinType::LEFT:
1202  return "LEFT";
1203  case JoinType::INVALID:
1204  return "INVALID";
1205  }
1206  UNREACHABLE();
1207  return "";
1208 }
#define UNREACHABLE()
Definition: Logger.h:241

+ 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 1841 of file Execute.cpp.

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

Referenced by Executor::collectAllDeviceShardedTopResults().

1846  {
1847  const auto output_buffer = output_storage->getUnderlyingBuffer();
1848  const auto input_buffer = input_storage->getUnderlyingBuffer();
1849  for (const auto sorted_idx : top_permutation) {
1850  // permuting all group-columns in this result set into the final buffer:
1851  for (size_t group_idx = 0; group_idx < input_query_mem_desc.getKeyCount();
1852  group_idx++) {
1853  const auto input_column_ptr =
1854  input_buffer + input_query_mem_desc.getPrependedGroupColOffInBytes(group_idx) +
1855  sorted_idx * input_query_mem_desc.groupColWidth(group_idx);
1856  const auto output_column_ptr =
1857  output_buffer +
1858  output_query_mem_desc.getPrependedGroupColOffInBytes(group_idx) +
1859  output_row_index * output_query_mem_desc.groupColWidth(group_idx);
1860  memcpy(output_column_ptr,
1861  input_column_ptr,
1862  output_query_mem_desc.groupColWidth(group_idx));
1863  }
1864  // permuting all agg-columns in this result set into the final buffer:
1865  for (size_t slot_idx = 0; slot_idx < input_query_mem_desc.getSlotCount();
1866  slot_idx++) {
1867  const auto input_column_ptr =
1868  input_buffer + input_query_mem_desc.getColOffInBytes(slot_idx) +
1869  sorted_idx * input_query_mem_desc.getPaddedSlotWidthBytes(slot_idx);
1870  const auto output_column_ptr =
1871  output_buffer + output_query_mem_desc.getColOffInBytes(slot_idx) +
1872  output_row_index * output_query_mem_desc.getPaddedSlotWidthBytes(slot_idx);
1873  memcpy(output_column_ptr,
1874  input_column_ptr,
1875  output_query_mem_desc.getPaddedSlotWidthBytes(slot_idx));
1876  }
1877  ++output_row_index;
1878  }
1879  return output_row_index;
1880 }
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 1891 of file Execute.cpp.

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

Referenced by Executor::collectAllDeviceShardedTopResults().

1895  {
1896  const auto output_buffer = output_storage->getUnderlyingBuffer();
1897  const auto input_buffer = input_storage->getUnderlyingBuffer();
1898  for (const auto sorted_idx : top_permutation) {
1899  const auto row_ptr = input_buffer + sorted_idx * output_query_mem_desc.getRowSize();
1900  memcpy(output_buffer + output_row_index * output_query_mem_desc.getRowSize(),
1901  row_ptr,
1902  output_query_mem_desc.getRowSize());
1903  ++output_row_index;
1904  }
1905  return output_row_index;
1906 }
int8_t * getUnderlyingBuffer() const

+ Here is the call graph for this function:

+ 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 1326 of file Execute.cpp.

References RelAlgExecutionUnit::estimator, RelAlgExecutionUnit::groupby_exprs, RelAlgExecutionUnit::input_col_descs, RelAlgExecutionUnit::input_descs, RelAlgExecutionUnit::join_quals, RelAlgExecutionUnit::quals, RelAlgExecutionUnit::query_state, RelAlgExecutionUnit::simple_quals, RelAlgExecutionUnit::sort_info, RelAlgExecutionUnit::target_exprs, RelAlgExecutionUnit::union_all, and RelAlgExecutionUnit::use_bump_allocator.

Referenced by Executor::executeWorkUnit().

1327  {
1328  return {ra_exe_unit_in.input_descs,
1329  ra_exe_unit_in.input_col_descs,
1330  ra_exe_unit_in.simple_quals,
1331  ra_exe_unit_in.quals,
1332  ra_exe_unit_in.join_quals,
1333  ra_exe_unit_in.groupby_exprs,
1334  ra_exe_unit_in.target_exprs,
1335  ra_exe_unit_in.estimator,
1336  ra_exe_unit_in.sort_info,
1337  new_scan_limit,
1338  ra_exe_unit_in.use_bump_allocator,
1339  ra_exe_unit_in.union_all,
1340  ra_exe_unit_in.query_state};
1341 }
std::vector< Analyzer::Expr * > target_exprs
const std::optional< bool > union_all
std::vector< InputDescriptor > input_descs
const std::list< std::shared_ptr< Analyzer::Expr > > groupby_exprs
const SortInfo sort_info
const JoinQualsPerNestingLevel join_quals
const std::shared_ptr< Analyzer::Estimator > estimator
std::list< std::shared_ptr< Analyzer::Expr > > quals
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

+ Here is the caller graph for this function:

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

Definition at line 1210 of file Execute.cpp.

References Default, SpeculativeTopN, StreamingTopN, and UNREACHABLE.

Referenced by operator<<().

1210  {
1211  switch (algorithm) {
1213  return "ResultSet";
1215  return "Speculative Top N";
1217  return "Streaming Top N";
1218  }
1219  UNREACHABLE();
1220  return "";
1221 }
#define UNREACHABLE()
Definition: Logger.h:241

+ Here is the caller graph for this function:

const ColumnDescriptor* anonymous_namespace{Execute.cpp}::try_get_column_descriptor ( const InputColDescriptor col_desc,
const Catalog_Namespace::Catalog cat 
)

Definition at line 2248 of file Execute.cpp.

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

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

2249  {
2250  const int table_id = col_desc->getScanDesc().getTableId();
2251  const int col_id = col_desc->getColId();
2252  return get_column_descriptor_maybe(col_id, table_id, cat);
2253 }
const ColumnDescriptor * get_column_descriptor_maybe(const int col_id, const int table_id, const Catalog_Namespace::Catalog &cat)
Definition: Execute.h:216
int getColId() const
int getTableId() const
const InputDescriptor & getScanDesc() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function: