OmniSciDB  fe05a0c208
 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)
 
void add_transient_string_literals_for_expression (const Analyzer::Expr *expr, Executor *executor, const std::shared_ptr< RowSetMemoryOwner > &row_set_mem_owner)
 
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)
 
void add_deleted_col_to_map (PlanState::DeletedColumnsMap &deleted_cols_map, const ColumnDescriptor *deleted_cd)
 
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 
)

Definition at line 3511 of file Execute.cpp.

References CHECK, CHECK_EQ, and ColumnDescriptor::tableId.

Referenced by Executor::addDeletedColumn().

3512  {
3513  auto deleted_cols_it = deleted_cols_map.find(deleted_cd->tableId);
3514  if (deleted_cols_it == deleted_cols_map.end()) {
3515  CHECK(
3516  deleted_cols_map.insert(std::make_pair(deleted_cd->tableId, deleted_cd)).second);
3517  } else {
3518  CHECK_EQ(deleted_cd, deleted_cols_it->second);
3519  }
3520 }
#define CHECK_EQ(x, y)
Definition: Logger.h:211
#define CHECK(condition)
Definition: Logger.h:203

+ Here is the caller graph for this function:

void anonymous_namespace{Execute.cpp}::add_transient_string_literals_for_expression ( const Analyzer::Expr expr,
Executor executor,
const std::shared_ptr< RowSetMemoryOwner > &  row_set_mem_owner 
)

Definition at line 1724 of file Execute.cpp.

References CHECK, CHECK_EQ, Analyzer::CaseExpr::get_domain(), Analyzer::UOper::get_optype(), Analyzer::Expr::get_type_info(), i, kCAST, and kENCODING_DICT.

Referenced by Executor::addTransientStringLiterals().

1727  {
1728  if (!expr) {
1729  return;
1730  }
1731 
1732  const auto array_expr = dynamic_cast<const Analyzer::ArrayExpr*>(expr);
1733  if (array_expr) {
1734  for (size_t i = 0; i < array_expr->getElementCount(); i++) {
1736  array_expr->getElement(i), executor, row_set_mem_owner);
1737  }
1738  return;
1739  }
1740 
1741  const auto cast_expr = dynamic_cast<const Analyzer::UOper*>(expr);
1742  const auto& expr_ti = expr->get_type_info();
1743  if (cast_expr && cast_expr->get_optype() == kCAST && expr_ti.is_string()) {
1744  CHECK_EQ(kENCODING_DICT, expr_ti.get_compression());
1745  auto sdp = executor->getStringDictionaryProxy(
1746  expr_ti.get_comp_param(), row_set_mem_owner, true);
1747  CHECK(sdp);
1748  const auto str_lit_expr =
1749  dynamic_cast<const Analyzer::Constant*>(cast_expr->get_operand());
1750  if (str_lit_expr && str_lit_expr->get_constval().stringval) {
1751  sdp->getOrAddTransient(*str_lit_expr->get_constval().stringval);
1752  }
1753  return;
1754  }
1755  const auto case_expr = dynamic_cast<const Analyzer::CaseExpr*>(expr);
1756  if (!case_expr) {
1757  return;
1758  }
1759  Analyzer::DomainSet domain_set;
1760  case_expr->get_domain(domain_set);
1761  if (domain_set.empty()) {
1762  return;
1763  }
1764  if (expr_ti.is_string()) {
1765  CHECK_EQ(kENCODING_DICT, expr_ti.get_compression());
1766  auto sdp = executor->getStringDictionaryProxy(
1767  expr_ti.get_comp_param(), row_set_mem_owner, true);
1768  CHECK(sdp);
1769  for (const auto domain_expr : domain_set) {
1770  const auto cast_expr = dynamic_cast<const Analyzer::UOper*>(domain_expr);
1771  const auto str_lit_expr =
1772  cast_expr && cast_expr->get_optype() == kCAST
1773  ? dynamic_cast<const Analyzer::Constant*>(cast_expr->get_operand())
1774  : dynamic_cast<const Analyzer::Constant*>(domain_expr);
1775  if (str_lit_expr && str_lit_expr->get_constval().stringval) {
1776  sdp->getOrAddTransient(*str_lit_expr->get_constval().stringval);
1777  }
1778  }
1779  }
1780 }
#define CHECK_EQ(x, y)
Definition: Logger.h:211
void get_domain(DomainSet &domain_set) const override
Definition: Analyzer.cpp:3167
Definition: sqldefs.h:49
void add_transient_string_literals_for_expression(const Analyzer::Expr *expr, Executor *executor, const std::shared_ptr< RowSetMemoryOwner > &row_set_mem_owner)
Definition: Execute.cpp:1724
std::list< const Expr * > DomainSet
Definition: Analyzer.h:61
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
#define CHECK(condition)
Definition: Logger.h:203
SQLOps get_optype() const
Definition: Analyzer.h:370

+ Here is the call graph for this function:

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

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

Referenced by Executor::collectAllDeviceResults().

1903  {
1904  std::vector<std::shared_ptr<Analyzer::Expr>> target_exprs_owned_copies;
1905  std::vector<Analyzer::Expr*> target_exprs;
1906  for (const auto target_expr : target_exprs_in) {
1907  const auto target_expr_copy =
1908  std::dynamic_pointer_cast<Analyzer::AggExpr>(target_expr->deep_copy());
1909  CHECK(target_expr_copy);
1910  auto ti = target_expr->get_type_info();
1911  ti.set_notnull(false);
1912  target_expr_copy->set_type_info(ti);
1913  if (target_expr_copy->get_arg()) {
1914  auto arg_ti = target_expr_copy->get_arg()->get_type_info();
1915  arg_ti.set_notnull(false);
1916  target_expr_copy->get_arg()->set_type_info(arg_ti);
1917  }
1918  target_exprs_owned_copies.push_back(target_expr_copy);
1919  target_exprs.push_back(target_expr_copy.get());
1920  }
1921  std::vector<TargetInfo> target_infos;
1922  std::vector<int64_t> entry;
1923  fill_entries_for_empty_input(target_infos, entry, target_exprs, query_mem_desc);
1924  const auto executor = query_mem_desc.getExecutor();
1925  CHECK(executor);
1926  auto row_set_mem_owner = executor->getRowSetMemoryOwner();
1927  CHECK(row_set_mem_owner);
1928  auto rs = std::make_shared<ResultSet>(target_infos,
1929  device_type,
1931  row_set_mem_owner,
1932  executor->getCatalog(),
1933  executor->blockSize(),
1934  executor->gridSize());
1935  rs->allocateStorage();
1936  rs->fillOneEntry(entry);
1937  return rs;
1938 }
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:1845
#define CHECK(condition)
Definition: Logger.h:203
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 3135 of file Execute.cpp.

References CHECK.

Referenced by Executor::executePlanWithGroupBy().

3135  {
3136  CHECK(scan_limit);
3137  return results && results->rowCount() < scan_limit;
3138 }
#define CHECK(condition)
Definition: Logger.h:203

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

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

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

References CHECK.

Referenced by Executor::executeWorkUnitImpl().

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

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

Referenced by operator<<().

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

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

1193  {
1194  std::vector<std::string> expr_strs;
1195  for (const auto& expr : expr_container) {
1196  expr_strs.emplace_back(expr.toString());
1197  }
1198  return expr_strs;
1199 }
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 1845 of file Execute.cpp.

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

Referenced by build_row_for_empty_input().

1848  {
1849  for (size_t target_idx = 0; target_idx < target_exprs.size(); ++target_idx) {
1850  const auto target_expr = target_exprs[target_idx];
1851  const auto agg_info = get_target_info(target_expr, g_bigint_count);
1852  CHECK(agg_info.is_agg);
1853  target_infos.push_back(agg_info);
1854  if (g_cluster) {
1855  const auto executor = query_mem_desc.getExecutor();
1856  CHECK(executor);
1857  auto row_set_mem_owner = executor->getRowSetMemoryOwner();
1858  CHECK(row_set_mem_owner);
1859  const auto& count_distinct_desc =
1860  query_mem_desc.getCountDistinctDescriptor(target_idx);
1861  if (count_distinct_desc.impl_type_ == CountDistinctImplType::Bitmap) {
1862  CHECK(row_set_mem_owner);
1863  auto count_distinct_buffer = row_set_mem_owner->allocateCountDistinctBuffer(
1864  count_distinct_desc.bitmapPaddedSizeBytes(),
1865  /*thread_idx=*/0); // TODO: can we detect thread idx here?
1866  entry.push_back(reinterpret_cast<int64_t>(count_distinct_buffer));
1867  continue;
1868  }
1869  if (count_distinct_desc.impl_type_ == CountDistinctImplType::StdSet) {
1870  auto count_distinct_set = new std::set<int64_t>();
1871  CHECK(row_set_mem_owner);
1872  row_set_mem_owner->addCountDistinctSet(count_distinct_set);
1873  entry.push_back(reinterpret_cast<int64_t>(count_distinct_set));
1874  continue;
1875  }
1876  }
1877  const bool float_argument_input = takes_float_argument(agg_info);
1878  if (agg_info.agg_kind == kCOUNT || agg_info.agg_kind == kAPPROX_COUNT_DISTINCT) {
1879  entry.push_back(0);
1880  } else if (agg_info.agg_kind == kAVG) {
1881  entry.push_back(inline_null_val(agg_info.sql_type, float_argument_input));
1882  entry.push_back(0);
1883  } else if (agg_info.agg_kind == kSINGLE_VALUE || agg_info.agg_kind == kSAMPLE) {
1884  if (agg_info.sql_type.is_geometry()) {
1885  for (int i = 0; i < agg_info.sql_type.get_physical_coord_cols() * 2; i++) {
1886  entry.push_back(0);
1887  }
1888  } else if (agg_info.sql_type.is_varlen()) {
1889  entry.push_back(0);
1890  entry.push_back(0);
1891  } else {
1892  entry.push_back(inline_null_val(agg_info.sql_type, float_argument_input));
1893  }
1894  } else {
1895  entry.push_back(inline_null_val(agg_info.sql_type, float_argument_input));
1896  }
1897  }
1898 }
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:1830
bool g_bigint_count
const CountDistinctDescriptor & getCountDistinctDescriptor(const size_t idx) const
Definition: sqldefs.h:76
#define CHECK(condition)
Definition: Logger.h:203
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 3567 of file Execute.cpp.

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

Referenced by Executor::skipFragment().

3571  {
3572  const int32_t ldim = lhs_type.get_dimension();
3573  const int32_t rdim = rhs_type.get_dimension();
3574  CHECK(ldim != rdim);
3575  const auto scale = DateTimeUtils::get_timestamp_precision_scale(abs(rdim - ldim));
3576  if (ldim > rdim) {
3577  // LHS type precision is more than RHS col type. No chance of overflow/underflow.
3578  return {true, chunk_min / scale, chunk_max / scale};
3579  }
3580 
3581  using checked_int64_t = boost::multiprecision::number<
3582  boost::multiprecision::cpp_int_backend<64,
3583  64,
3584  boost::multiprecision::signed_magnitude,
3585  boost::multiprecision::checked,
3586  void>>;
3587 
3588  try {
3589  auto ret =
3590  std::make_tuple(true,
3591  int64_t(checked_int64_t(chunk_min) * checked_int64_t(scale)),
3592  int64_t(checked_int64_t(chunk_max) * checked_int64_t(scale)));
3593  return ret;
3594  } catch (const std::overflow_error& e) {
3595  // noop
3596  }
3597  return std::make_tuple(false, chunk_min, chunk_max);
3598 }
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:316
#define CHECK(condition)
Definition: Logger.h:203
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 858 of file Execute.cpp.

References CHECK.

Referenced by Executor::resultsUnion().

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

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

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

Referenced by Executor::reduceMultiDeviceResultSets().

934  {
935  auto clock_begin = timer_start();
936  std::lock_guard<std::mutex> compilation_lock(Executor::compilation_mutex_);
937  *compilation_queue_time = timer_stop(clock_begin);
938  const auto& this_result_set = results_per_device[0].first;
939  ResultSetReductionJIT reduction_jit(this_result_set->getQueryMemDesc(),
940  this_result_set->getTargetInfos(),
941  this_result_set->getTargetInitVals());
942  return reduction_jit.codegen();
943 };
TypeR::rep timer_stop(Type clock_begin)
Definition: measure.h:48
virtual ReductionCode codegen() const
static std::mutex compilation_mutex_
Definition: Execute.h:1128
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 1088 of file Execute.cpp.

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

Referenced by checkWorkUnitWatchdog().

1089  {
1090  const auto source_type = input_desc.getSourceType();
1091  if (source_type == InputSourceType::TABLE) {
1092  const auto td = cat.getMetadataForTable(input_desc.getTableId());
1093  CHECK(td);
1094  return td->tableName;
1095  } else {
1096  return "$TEMPORARY_TABLE" + std::to_string(-input_desc.getTableId());
1097  }
1098 }
std::string to_string(char const *&&v)
int getTableId() const
InputSourceType getSourceType() const
#define CHECK(condition)
Definition: Logger.h:203
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 1100 of file Execute.cpp.

References GPU, and Executor::high_scan_limit.

Referenced by checkWorkUnitWatchdog().

1101  {
1102  if (device_type == ExecutorDeviceType::GPU) {
1103  return device_count * Executor::high_scan_limit;
1104  }
1106 }
static const size_t high_scan_limit
Definition: Execute.h:452

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

Referenced by Executor::createKernels().

2122  {
2123  for (const auto& col : fetched_cols) {
2124  if (col.is_lazily_fetched) {
2125  return true;
2126  }
2127  }
2128  return false;
2129 }

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

1830  {
1831  CHECK(ti.is_number() || ti.is_time() || ti.is_boolean() || ti.is_string());
1832  if (ti.is_fp()) {
1833  if (float_argument_input && ti.get_type() == kFLOAT) {
1834  int64_t float_null_val = 0;
1835  *reinterpret_cast<float*>(may_alias_ptr(&float_null_val)) =
1836  static_cast<float>(inline_fp_null_val(ti));
1837  return float_null_val;
1838  }
1839  const auto double_null_val = inline_fp_null_val(ti);
1840  return *reinterpret_cast<const int64_t*>(may_alias_ptr(&double_null_val));
1841  }
1842  return inline_int_null_val(ti);
1843 }
bool is_fp() const
Definition: sqltypes.h:493
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:314
bool is_number() const
Definition: sqltypes.h:494
double inline_fp_null_val(const SQL_TYPE_INFO &ti)
bool is_time() const
Definition: sqltypes.h:495
bool is_boolean() const
Definition: sqltypes.h:496
#define CHECK(condition)
Definition: Logger.h:203
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
bool is_string() const
Definition: sqltypes.h:489

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

References INNER, INVALID, LEFT, and UNREACHABLE.

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

1201  {
1202  switch (type) {
1203  case JoinType::INNER:
1204  return "INNER";
1205  case JoinType::LEFT:
1206  return "LEFT";
1207  case JoinType::INVALID:
1208  return "INVALID";
1209  }
1210  UNREACHABLE();
1211  return "";
1212 }
#define UNREACHABLE()
Definition: Logger.h:247

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

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

Referenced by Executor::collectAllDeviceShardedTopResults().

1991  {
1992  const auto output_buffer = output_storage->getUnderlyingBuffer();
1993  const auto input_buffer = input_storage->getUnderlyingBuffer();
1994  for (const auto sorted_idx : top_permutation) {
1995  // permuting all group-columns in this result set into the final buffer:
1996  for (size_t group_idx = 0; group_idx < input_query_mem_desc.getKeyCount();
1997  group_idx++) {
1998  const auto input_column_ptr =
1999  input_buffer + input_query_mem_desc.getPrependedGroupColOffInBytes(group_idx) +
2000  sorted_idx * input_query_mem_desc.groupColWidth(group_idx);
2001  const auto output_column_ptr =
2002  output_buffer +
2003  output_query_mem_desc.getPrependedGroupColOffInBytes(group_idx) +
2004  output_row_index * output_query_mem_desc.groupColWidth(group_idx);
2005  memcpy(output_column_ptr,
2006  input_column_ptr,
2007  output_query_mem_desc.groupColWidth(group_idx));
2008  }
2009  // permuting all agg-columns in this result set into the final buffer:
2010  for (size_t slot_idx = 0; slot_idx < input_query_mem_desc.getSlotCount();
2011  slot_idx++) {
2012  const auto input_column_ptr =
2013  input_buffer + input_query_mem_desc.getColOffInBytes(slot_idx) +
2014  sorted_idx * input_query_mem_desc.getPaddedSlotWidthBytes(slot_idx);
2015  const auto output_column_ptr =
2016  output_buffer + output_query_mem_desc.getColOffInBytes(slot_idx) +
2017  output_row_index * output_query_mem_desc.getPaddedSlotWidthBytes(slot_idx);
2018  memcpy(output_column_ptr,
2019  input_column_ptr,
2020  output_query_mem_desc.getPaddedSlotWidthBytes(slot_idx));
2021  }
2022  ++output_row_index;
2023  }
2024  return output_row_index;
2025 }
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 2036 of file Execute.cpp.

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

Referenced by Executor::collectAllDeviceShardedTopResults().

2040  {
2041  const auto output_buffer = output_storage->getUnderlyingBuffer();
2042  const auto input_buffer = input_storage->getUnderlyingBuffer();
2043  for (const auto sorted_idx : top_permutation) {
2044  const auto row_ptr = input_buffer + sorted_idx * output_query_mem_desc.getRowSize();
2045  memcpy(output_buffer + output_row_index * output_query_mem_desc.getRowSize(),
2046  row_ptr,
2047  output_query_mem_desc.getRowSize());
2048  ++output_row_index;
2049  }
2050  return output_row_index;
2051 }
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 1330 of file Execute.cpp.

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

Referenced by Executor::executeWorkUnit().

1331  {
1332  return {ra_exe_unit_in.input_descs,
1333  ra_exe_unit_in.input_col_descs,
1334  ra_exe_unit_in.simple_quals,
1335  ra_exe_unit_in.quals,
1336  ra_exe_unit_in.join_quals,
1337  ra_exe_unit_in.groupby_exprs,
1338  ra_exe_unit_in.target_exprs,
1339  ra_exe_unit_in.estimator,
1340  ra_exe_unit_in.sort_info,
1341  new_scan_limit,
1342  ra_exe_unit_in.query_hint,
1343  ra_exe_unit_in.use_bump_allocator,
1344  ra_exe_unit_in.union_all,
1345  ra_exe_unit_in.query_state};
1346 }
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
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

+ Here is the caller graph for this function:

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

Definition at line 1214 of file Execute.cpp.

References Default, SpeculativeTopN, StreamingTopN, and UNREACHABLE.

Referenced by operator<<().

1214  {
1215  switch (algorithm) {
1217  return "ResultSet";
1219  return "Speculative Top N";
1221  return "Streaming Top N";
1222  }
1223  UNREACHABLE();
1224  return "";
1225 }
#define UNREACHABLE()
Definition: Logger.h:247

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

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

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

2397  {
2398  const int table_id = col_desc->getScanDesc().getTableId();
2399  const int col_id = col_desc->getColId();
2400  return get_column_descriptor_maybe(col_id, table_id, cat);
2401 }
const ColumnDescriptor * get_column_descriptor_maybe(const int col_id, const int table_id, const Catalog_Namespace::Catalog &cat)
Definition: Execute.h:221
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: