OmniSciDB  a667adc9c8
 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)
 
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 3420 of file Execute.cpp.

References CHECK, CHECK_EQ, and ColumnDescriptor::tableId.

Referenced by Executor::addDeletedColumn().

3421  {
3422  auto deleted_cols_it = deleted_cols_map.find(deleted_cd->tableId);
3423  if (deleted_cols_it == deleted_cols_map.end()) {
3424  CHECK(
3425  deleted_cols_map.insert(std::make_pair(deleted_cd->tableId, deleted_cd)).second);
3426  } else {
3427  CHECK_EQ(deleted_cd, deleted_cols_it->second);
3428  }
3429 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
#define CHECK(condition)
Definition: Logger.h:197

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

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

Referenced by Executor::collectAllDeviceResults().

1814  {
1815  std::vector<std::shared_ptr<Analyzer::Expr>> target_exprs_owned_copies;
1816  std::vector<Analyzer::Expr*> target_exprs;
1817  for (const auto target_expr : target_exprs_in) {
1818  const auto target_expr_copy =
1819  std::dynamic_pointer_cast<Analyzer::AggExpr>(target_expr->deep_copy());
1820  CHECK(target_expr_copy);
1821  auto ti = target_expr->get_type_info();
1822  ti.set_notnull(false);
1823  target_expr_copy->set_type_info(ti);
1824  if (target_expr_copy->get_arg()) {
1825  auto arg_ti = target_expr_copy->get_arg()->get_type_info();
1826  arg_ti.set_notnull(false);
1827  target_expr_copy->get_arg()->set_type_info(arg_ti);
1828  }
1829  target_exprs_owned_copies.push_back(target_expr_copy);
1830  target_exprs.push_back(target_expr_copy.get());
1831  }
1832  std::vector<TargetInfo> target_infos;
1833  std::vector<int64_t> entry;
1834  fill_entries_for_empty_input(target_infos, entry, target_exprs, query_mem_desc);
1835  const auto executor = query_mem_desc.getExecutor();
1836  CHECK(executor);
1837  auto row_set_mem_owner = executor->getRowSetMemoryOwner();
1838  CHECK(row_set_mem_owner);
1839  auto rs = std::make_shared<ResultSet>(target_infos,
1840  device_type,
1842  row_set_mem_owner,
1843  executor->getCatalog(),
1844  executor->blockSize(),
1845  executor->gridSize());
1846  rs->allocateStorage();
1847  rs->fillOneEntry(entry);
1848  return rs;
1849 }
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:1756
#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 3045 of file Execute.cpp.

References CHECK.

Referenced by Executor::executePlanWithGroupBy().

3045  {
3046  CHECK(scan_limit);
3047  return results && results->rowCount() < scan_limit;
3048 }
#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 1106 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().

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

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

References CHECK.

Referenced by Executor::executeWorkUnitImpl().

1056  {
1058  // Check for overflows since we're multiplying potentially big table sizes.
1059  using checked_size_t = boost::multiprecision::number<
1060  boost::multiprecision::cpp_int_backend<64,
1061  64,
1062  boost::multiprecision::unsigned_magnitude,
1063  boost::multiprecision::checked,
1064  void>>;
1065  checked_size_t max_groups_buffer_entry_guess = 1;
1066  for (const auto& query_info : query_infos) {
1067  CHECK(!query_info.info.fragments.empty());
1068  auto it = std::max_element(query_info.info.fragments.begin(),
1069  query_info.info.fragments.end(),
1070  [](const FragmentInfo& f1, const FragmentInfo& f2) {
1071  return f1.getNumTuples() < f2.getNumTuples();
1072  });
1073  max_groups_buffer_entry_guess *= it->getNumTuples();
1074  }
1075  // Cap the rough approximation to 100M entries, it's unlikely we can do a great job for
1076  // baseline group layout with that many entries anyway.
1077  constexpr size_t max_groups_buffer_entry_guess_cap = 100000000;
1078  try {
1079  return std::min(static_cast<size_t>(max_groups_buffer_entry_guess),
1080  max_groups_buffer_entry_guess_cap);
1081  } catch (...) {
1082  return max_groups_buffer_entry_guess_cap;
1083  }
1084 }
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: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 1177 of file Execute.cpp.

Referenced by operator<<().

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

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

1191  {
1192  std::vector<std::string> expr_strs;
1193  for (const auto& expr : expr_container) {
1194  expr_strs.emplace_back(expr.toString());
1195  }
1196  return expr_strs;
1197 }
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 1756 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().

1759  {
1760  for (size_t target_idx = 0; target_idx < target_exprs.size(); ++target_idx) {
1761  const auto target_expr = target_exprs[target_idx];
1762  const auto agg_info = get_target_info(target_expr, g_bigint_count);
1763  CHECK(agg_info.is_agg);
1764  target_infos.push_back(agg_info);
1765  if (g_cluster) {
1766  const auto executor = query_mem_desc.getExecutor();
1767  CHECK(executor);
1768  auto row_set_mem_owner = executor->getRowSetMemoryOwner();
1769  CHECK(row_set_mem_owner);
1770  const auto& count_distinct_desc =
1771  query_mem_desc.getCountDistinctDescriptor(target_idx);
1772  if (count_distinct_desc.impl_type_ == CountDistinctImplType::Bitmap) {
1773  CHECK(row_set_mem_owner);
1774  auto count_distinct_buffer = row_set_mem_owner->allocateCountDistinctBuffer(
1775  count_distinct_desc.bitmapPaddedSizeBytes(),
1776  /*thread_idx=*/0); // TODO: can we detect thread idx here?
1777  entry.push_back(reinterpret_cast<int64_t>(count_distinct_buffer));
1778  continue;
1779  }
1780  if (count_distinct_desc.impl_type_ == CountDistinctImplType::StdSet) {
1781  auto count_distinct_set = new std::set<int64_t>();
1782  CHECK(row_set_mem_owner);
1783  row_set_mem_owner->addCountDistinctSet(count_distinct_set);
1784  entry.push_back(reinterpret_cast<int64_t>(count_distinct_set));
1785  continue;
1786  }
1787  }
1788  const bool float_argument_input = takes_float_argument(agg_info);
1789  if (agg_info.agg_kind == kCOUNT || agg_info.agg_kind == kAPPROX_COUNT_DISTINCT) {
1790  entry.push_back(0);
1791  } else if (agg_info.agg_kind == kAVG) {
1792  entry.push_back(inline_null_val(agg_info.sql_type, float_argument_input));
1793  entry.push_back(0);
1794  } else if (agg_info.agg_kind == kSINGLE_VALUE || agg_info.agg_kind == kSAMPLE) {
1795  if (agg_info.sql_type.is_geometry()) {
1796  for (int i = 0; i < agg_info.sql_type.get_physical_coord_cols() * 2; i++) {
1797  entry.push_back(0);
1798  }
1799  } else if (agg_info.sql_type.is_varlen()) {
1800  entry.push_back(0);
1801  entry.push_back(0);
1802  } else {
1803  entry.push_back(inline_null_val(agg_info.sql_type, float_argument_input));
1804  }
1805  } else {
1806  entry.push_back(inline_null_val(agg_info.sql_type, float_argument_input));
1807  }
1808  }
1809 }
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:1741
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 3476 of file Execute.cpp.

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

Referenced by Executor::skipFragment().

3480  {
3481  const int32_t ldim = lhs_type.get_dimension();
3482  const int32_t rdim = rhs_type.get_dimension();
3483  CHECK(ldim != rdim);
3484  const auto scale = DateTimeUtils::get_timestamp_precision_scale(abs(rdim - ldim));
3485  if (ldim > rdim) {
3486  // LHS type precision is more than RHS col type. No chance of overflow/underflow.
3487  return {true, chunk_min / scale, chunk_max / scale};
3488  }
3489 
3490  using checked_int64_t = boost::multiprecision::number<
3491  boost::multiprecision::cpp_int_backend<64,
3492  64,
3493  boost::multiprecision::signed_magnitude,
3494  boost::multiprecision::checked,
3495  void>>;
3496 
3497  try {
3498  auto ret =
3499  std::make_tuple(true,
3500  int64_t(checked_int64_t(chunk_min) * checked_int64_t(scale)),
3501  int64_t(checked_int64_t(chunk_max) * checked_int64_t(scale)));
3502  return ret;
3503  } catch (const std::overflow_error& e) {
3504  // noop
3505  }
3506  return std::make_tuple(false, chunk_min, chunk_max);
3507 }
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: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 856 of file Execute.cpp.

References CHECK.

Referenced by Executor::resultsUnion().

857  {
858  auto& first = results_per_device.front().first;
859  CHECK(first);
860  for (size_t dev_idx = 1; dev_idx < results_per_device.size(); ++dev_idx) {
861  const auto& next = results_per_device[dev_idx].first;
862  CHECK(next);
863  first->append(*next);
864  }
865  return std::move(first);
866 }
#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 930 of file Execute.cpp.

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

Referenced by Executor::reduceMultiDeviceResultSets().

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

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

Referenced by checkWorkUnitWatchdog().

1087  {
1088  const auto source_type = input_desc.getSourceType();
1089  if (source_type == InputSourceType::TABLE) {
1090  const auto td = cat.getMetadataForTable(input_desc.getTableId());
1091  CHECK(td);
1092  return td->tableName;
1093  } else {
1094  return "$TEMPORARY_TABLE" + std::to_string(-input_desc.getTableId());
1095  }
1096 }
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 1098 of file Execute.cpp.

References GPU, and Executor::high_scan_limit.

Referenced by checkWorkUnitWatchdog().

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

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

Referenced by Executor::createKernels().

2033  {
2034  for (const auto& col : fetched_cols) {
2035  if (col.is_lazily_fetched) {
2036  return true;
2037  }
2038  }
2039  return false;
2040 }

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

1741  {
1742  CHECK(ti.is_number() || ti.is_time() || ti.is_boolean() || ti.is_string());
1743  if (ti.is_fp()) {
1744  if (float_argument_input && ti.get_type() == kFLOAT) {
1745  int64_t float_null_val = 0;
1746  *reinterpret_cast<float*>(may_alias_ptr(&float_null_val)) =
1747  static_cast<float>(inline_fp_null_val(ti));
1748  return float_null_val;
1749  }
1750  const auto double_null_val = inline_fp_null_val(ti);
1751  return *reinterpret_cast<const int64_t*>(may_alias_ptr(&double_null_val));
1752  }
1753  return inline_int_null_val(ti);
1754 }
bool is_fp() const
Definition: sqltypes.h:492
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:314
bool is_number() const
Definition: sqltypes.h:493
double inline_fp_null_val(const SQL_TYPE_INFO &ti)
bool is_time() const
Definition: sqltypes.h:494
bool is_boolean() const
Definition: sqltypes.h:495
#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:488

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

References INNER, INVALID, LEFT, and UNREACHABLE.

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

1199  {
1200  switch (type) {
1201  case JoinType::INNER:
1202  return "INNER";
1203  case JoinType::LEFT:
1204  return "LEFT";
1205  case JoinType::INVALID:
1206  return "INVALID";
1207  }
1208  UNREACHABLE();
1209  return "";
1210 }
#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 1897 of file Execute.cpp.

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

Referenced by Executor::collectAllDeviceShardedTopResults().

1902  {
1903  const auto output_buffer = output_storage->getUnderlyingBuffer();
1904  const auto input_buffer = input_storage->getUnderlyingBuffer();
1905  for (const auto sorted_idx : top_permutation) {
1906  // permuting all group-columns in this result set into the final buffer:
1907  for (size_t group_idx = 0; group_idx < input_query_mem_desc.getKeyCount();
1908  group_idx++) {
1909  const auto input_column_ptr =
1910  input_buffer + input_query_mem_desc.getPrependedGroupColOffInBytes(group_idx) +
1911  sorted_idx * input_query_mem_desc.groupColWidth(group_idx);
1912  const auto output_column_ptr =
1913  output_buffer +
1914  output_query_mem_desc.getPrependedGroupColOffInBytes(group_idx) +
1915  output_row_index * output_query_mem_desc.groupColWidth(group_idx);
1916  memcpy(output_column_ptr,
1917  input_column_ptr,
1918  output_query_mem_desc.groupColWidth(group_idx));
1919  }
1920  // permuting all agg-columns in this result set into the final buffer:
1921  for (size_t slot_idx = 0; slot_idx < input_query_mem_desc.getSlotCount();
1922  slot_idx++) {
1923  const auto input_column_ptr =
1924  input_buffer + input_query_mem_desc.getColOffInBytes(slot_idx) +
1925  sorted_idx * input_query_mem_desc.getPaddedSlotWidthBytes(slot_idx);
1926  const auto output_column_ptr =
1927  output_buffer + output_query_mem_desc.getColOffInBytes(slot_idx) +
1928  output_row_index * output_query_mem_desc.getPaddedSlotWidthBytes(slot_idx);
1929  memcpy(output_column_ptr,
1930  input_column_ptr,
1931  output_query_mem_desc.getPaddedSlotWidthBytes(slot_idx));
1932  }
1933  ++output_row_index;
1934  }
1935  return output_row_index;
1936 }
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 1947 of file Execute.cpp.

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

Referenced by Executor::collectAllDeviceShardedTopResults().

1951  {
1952  const auto output_buffer = output_storage->getUnderlyingBuffer();
1953  const auto input_buffer = input_storage->getUnderlyingBuffer();
1954  for (const auto sorted_idx : top_permutation) {
1955  const auto row_ptr = input_buffer + sorted_idx * output_query_mem_desc.getRowSize();
1956  memcpy(output_buffer + output_row_index * output_query_mem_desc.getRowSize(),
1957  row_ptr,
1958  output_query_mem_desc.getRowSize());
1959  ++output_row_index;
1960  }
1961  return output_row_index;
1962 }
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 1328 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().

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

References Default, SpeculativeTopN, StreamingTopN, and UNREACHABLE.

Referenced by operator<<().

1212  {
1213  switch (algorithm) {
1215  return "ResultSet";
1217  return "Speculative Top N";
1219  return "Streaming Top N";
1220  }
1221  UNREACHABLE();
1222  return "";
1223 }
#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 2307 of file Execute.cpp.

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

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

2308  {
2309  const int table_id = col_desc->getScanDesc().getTableId();
2310  const int col_id = col_desc->getColId();
2311  return get_column_descriptor_maybe(col_id, table_id, cat);
2312 }
const ColumnDescriptor * get_column_descriptor_maybe(const int col_id, const int table_id, const Catalog_Namespace::Catalog &cat)
Definition: Execute.h:222
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: