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

Classes

struct  GetTargetInfo
 
class  OutVecOwner
 

Functions

void prepare_string_dictionaries (const std::unordered_set< PhysicalInput > &phys_inputs, const Catalog_Namespace::Catalog &catalog)
 
bool is_empty_table (Fragmenter_Namespace::AbstractFragmenter *fragmenter)
 
ResultSetPtr get_merged_result (std::vector< std::pair< ResultSetPtr, std::vector< size_t >>> &results_per_device, std::vector< TargetInfo > const &targets)
 
ReductionCode get_reduction_code (const size_t executor_id, std::vector< std::pair< ResultSetPtr, std::vector< size_t >>> &results_per_device, int64_t *compilation_queue_time)
 
size_t compute_buffer_entry_guess (const std::vector< InputTableInfo > &query_infos)
 
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 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 3942 of file Execute.cpp.

References CHECK, CHECK_EQ, and ColumnDescriptor::tableId.

Referenced by Executor::addDeletedColumn().

3943  {
3944  auto deleted_cols_it = deleted_cols_map.find(deleted_cd->tableId);
3945  if (deleted_cols_it == deleted_cols_map.end()) {
3946  CHECK(
3947  deleted_cols_map.insert(std::make_pair(deleted_cd->tableId, deleted_cd)).second);
3948  } else {
3949  CHECK_EQ(deleted_cd, deleted_cols_it->second);
3950  }
3951 }
#define CHECK_EQ(x, y)
Definition: Logger.h:231
#define CHECK(condition)
Definition: Logger.h:223

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

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

Referenced by Executor::collectAllDeviceResults().

2288  {
2289  std::vector<std::shared_ptr<Analyzer::Expr>> target_exprs_owned_copies;
2290  std::vector<Analyzer::Expr*> target_exprs;
2291  for (const auto target_expr : target_exprs_in) {
2292  const auto target_expr_copy =
2293  std::dynamic_pointer_cast<Analyzer::AggExpr>(target_expr->deep_copy());
2294  CHECK(target_expr_copy);
2295  auto ti = target_expr->get_type_info();
2296  ti.set_notnull(false);
2297  target_expr_copy->set_type_info(ti);
2298  if (target_expr_copy->get_arg()) {
2299  auto arg_ti = target_expr_copy->get_arg()->get_type_info();
2300  arg_ti.set_notnull(false);
2301  target_expr_copy->get_arg()->set_type_info(arg_ti);
2302  }
2303  target_exprs_owned_copies.push_back(target_expr_copy);
2304  target_exprs.push_back(target_expr_copy.get());
2305  }
2306  std::vector<TargetInfo> target_infos;
2307  std::vector<int64_t> entry;
2308  fill_entries_for_empty_input(target_infos, entry, target_exprs, query_mem_desc);
2309  const auto executor = query_mem_desc.getExecutor();
2310  CHECK(executor);
2311  auto row_set_mem_owner = executor->getRowSetMemoryOwner();
2312  CHECK(row_set_mem_owner);
2313  auto rs = std::make_shared<ResultSet>(target_infos,
2314  device_type,
2316  row_set_mem_owner,
2317  executor->getCatalog(),
2318  executor->blockSize(),
2319  executor->gridSize());
2320  rs->allocateStorage();
2321  rs->fillOneEntry(entry);
2322  return rs;
2323 }
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:2230
#define CHECK(condition)
Definition: Logger.h:223
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 3556 of file Execute.cpp.

References CHECK.

Referenced by Executor::executePlanWithGroupBy().

3556  {
3557  CHECK(scan_limit);
3558  return results && results->rowCount() < scan_limit;
3559 }
#define CHECK(condition)
Definition: Logger.h:223

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

References SortInfo::algorithm, foreign_storage::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().

1518  {
1519  for (const auto target_expr : ra_exe_unit.target_exprs) {
1520  if (dynamic_cast<const Analyzer::AggExpr*>(target_expr)) {
1521  return;
1522  }
1523  }
1524  if (!ra_exe_unit.scan_limit && table_infos.size() == 1 &&
1525  table_infos.front().info.getPhysicalNumTuples() < Executor::high_scan_limit) {
1526  // Allow a query with no scan limit to run on small tables
1527  return;
1528  }
1529  if (ra_exe_unit.use_bump_allocator) {
1530  // Bump allocator removes the scan limit (and any knowledge of the size of the output
1531  // relative to the size of the input), so we bypass this check for now
1532  return;
1533  }
1534  if (ra_exe_unit.sort_info.algorithm != SortAlgorithm::StreamingTopN &&
1535  ra_exe_unit.groupby_exprs.size() == 1 && !ra_exe_unit.groupby_exprs.front() &&
1536  (!ra_exe_unit.scan_limit ||
1537  ra_exe_unit.scan_limit > getDeviceBasedScanLimit(device_type, device_count))) {
1538  std::vector<std::string> table_names;
1539  const auto& input_descs = ra_exe_unit.input_descs;
1540  for (const auto& input_desc : input_descs) {
1541  table_names.push_back(get_table_name(input_desc, cat));
1542  }
1543  if (!ra_exe_unit.scan_limit) {
1544  throw WatchdogException(
1545  "Projection query would require a scan without a limit on table(s): " +
1546  boost::algorithm::join(table_names, ", "));
1547  } else {
1548  throw WatchdogException(
1549  "Projection query output result set on table(s): " +
1550  boost::algorithm::join(table_names, ", ") + " would contain " +
1551  std::to_string(ra_exe_unit.scan_limit) +
1552  " rows, which is more than the current system limit of " +
1553  std::to_string(getDeviceBasedScanLimit(device_type, device_count)));
1554  }
1555  }
1556 }
std::vector< Analyzer::Expr * > target_exprs
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:602
size_t getDeviceBasedScanLimit(const ExecutorDeviceType device_type, const int device_count)
Definition: Execute.cpp:1506
std::string get_table_name(int32_t db_id, int32_t table_id)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 1464 of file Execute.cpp.

References CHECK.

Referenced by Executor::executeWorkUnitImpl().

1464  {
1466  // Check for overflows since we're multiplying potentially big table sizes.
1467  using checked_size_t = boost::multiprecision::number<
1468  boost::multiprecision::cpp_int_backend<64,
1469  64,
1470  boost::multiprecision::unsigned_magnitude,
1471  boost::multiprecision::checked,
1472  void>>;
1473  checked_size_t max_groups_buffer_entry_guess = 1;
1474  for (const auto& query_info : query_infos) {
1475  CHECK(!query_info.info.fragments.empty());
1476  auto it = std::max_element(query_info.info.fragments.begin(),
1477  query_info.info.fragments.end(),
1478  [](const FragmentInfo& f1, const FragmentInfo& f2) {
1479  return f1.getNumTuples() < f2.getNumTuples();
1480  });
1481  max_groups_buffer_entry_guess *= it->getNumTuples();
1482  }
1483  // Cap the rough approximation to 100M entries, it's unlikely we can do a great job for
1484  // baseline group layout with that many entries anyway.
1485  constexpr size_t max_groups_buffer_entry_guess_cap = 100000000;
1486  try {
1487  return std::min(static_cast<size_t>(max_groups_buffer_entry_guess),
1488  max_groups_buffer_entry_guess_cap);
1489  } catch (...) {
1490  return max_groups_buffer_entry_guess_cap;
1491  }
1492 }
Used by Fragmenter classes to store info about each fragment - the fragment id and number of tuples(r...
Definition: Fragmenter.h:86
#define CHECK(condition)
Definition: Logger.h:223

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

Referenced by operator<<().

1585  {
1586  std::vector<std::string> expr_strs;
1587  for (const auto& expr : expr_container) {
1588  if (!expr) {
1589  expr_strs.emplace_back("NULL");
1590  } else {
1591  expr_strs.emplace_back(expr->toString());
1592  }
1593  }
1594  return expr_strs;
1595 }

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

1599  {
1600  std::vector<std::string> expr_strs;
1601  for (const auto& expr : expr_container) {
1602  expr_strs.emplace_back(expr.toString());
1603  }
1604  return expr_strs;
1605 }
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 2230 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, takes_float_argument(), and UnorderedSet.

Referenced by build_row_for_empty_input().

2233  {
2234  for (size_t target_idx = 0; target_idx < target_exprs.size(); ++target_idx) {
2235  const auto target_expr = target_exprs[target_idx];
2236  const auto agg_info = get_target_info(target_expr, g_bigint_count);
2237  CHECK(agg_info.is_agg);
2238  target_infos.push_back(agg_info);
2239  if (g_cluster) {
2240  const auto executor = query_mem_desc.getExecutor();
2241  CHECK(executor);
2242  auto row_set_mem_owner = executor->getRowSetMemoryOwner();
2243  CHECK(row_set_mem_owner);
2244  const auto& count_distinct_desc =
2245  query_mem_desc.getCountDistinctDescriptor(target_idx);
2246  if (count_distinct_desc.impl_type_ == CountDistinctImplType::Bitmap) {
2247  CHECK(row_set_mem_owner);
2248  auto count_distinct_buffer = row_set_mem_owner->allocateCountDistinctBuffer(
2249  count_distinct_desc.bitmapPaddedSizeBytes(),
2250  /*thread_idx=*/0); // TODO: can we detect thread idx here?
2251  entry.push_back(reinterpret_cast<int64_t>(count_distinct_buffer));
2252  continue;
2253  }
2254  if (count_distinct_desc.impl_type_ == CountDistinctImplType::UnorderedSet) {
2255  auto count_distinct_set = new CountDistinctSet();
2256  CHECK(row_set_mem_owner);
2257  row_set_mem_owner->addCountDistinctSet(count_distinct_set);
2258  entry.push_back(reinterpret_cast<int64_t>(count_distinct_set));
2259  continue;
2260  }
2261  }
2262  const bool float_argument_input = takes_float_argument(agg_info);
2263  if (agg_info.agg_kind == kCOUNT || agg_info.agg_kind == kAPPROX_COUNT_DISTINCT) {
2264  entry.push_back(0);
2265  } else if (agg_info.agg_kind == kAVG) {
2266  entry.push_back(0);
2267  entry.push_back(0);
2268  } else if (agg_info.agg_kind == kSINGLE_VALUE || agg_info.agg_kind == kSAMPLE) {
2269  if (agg_info.sql_type.is_geometry() && !agg_info.is_varlen_projection) {
2270  for (int i = 0; i < agg_info.sql_type.get_physical_coord_cols() * 2; i++) {
2271  entry.push_back(0);
2272  }
2273  } else if (agg_info.sql_type.is_varlen()) {
2274  entry.push_back(0);
2275  entry.push_back(0);
2276  } else {
2277  entry.push_back(inline_null_val(agg_info.sql_type, float_argument_input));
2278  }
2279  } else {
2280  entry.push_back(inline_null_val(agg_info.sql_type, float_argument_input));
2281  }
2282  }
2283 }
robin_hood::unordered_set< int64_t > CountDistinctSet
Definition: CountDistinct.h:37
TargetInfo get_target_info(const PointerType target_expr, const bool bigint_count)
Definition: TargetInfo.h:92
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:157
int64_t inline_null_val(const SQLTypeInfo &ti, const bool float_argument_input)
Definition: Execute.cpp:2215
bool g_bigint_count
const CountDistinctDescriptor & getCountDistinctDescriptor(const size_t idx) const
Definition: sqldefs.h:78
#define CHECK(condition)
Definition: Logger.h:223
bool g_cluster
Definition: sqldefs.h:74
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 3998 of file Execute.cpp.

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

Referenced by Executor::skipFragment().

4002  {
4003  const int32_t ldim = lhs_type.get_dimension();
4004  const int32_t rdim = rhs_type.get_dimension();
4005  CHECK(ldim != rdim);
4006  const auto scale = DateTimeUtils::get_timestamp_precision_scale(abs(rdim - ldim));
4007  if (ldim > rdim) {
4008  // LHS type precision is more than RHS col type. No chance of overflow/underflow.
4009  return {true, chunk_min / scale, chunk_max / scale};
4010  }
4011 
4012  using checked_int64_t = boost::multiprecision::number<
4013  boost::multiprecision::cpp_int_backend<64,
4014  64,
4015  boost::multiprecision::signed_magnitude,
4016  boost::multiprecision::checked,
4017  void>>;
4018 
4019  try {
4020  auto ret =
4021  std::make_tuple(true,
4022  int64_t(checked_int64_t(chunk_min) * checked_int64_t(scale)),
4023  int64_t(checked_int64_t(chunk_max) * checked_int64_t(scale)));
4024  return ret;
4025  } catch (const std::overflow_error& e) {
4026  // noop
4027  }
4028  return std::make_tuple(false, chunk_min, chunk_max);
4029 }
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:331
#define CHECK(condition)
Definition: Logger.h:223
constexpr int64_t get_timestamp_precision_scale(const int32_t dimen)
Definition: DateTimeUtils.h:51

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 1249 of file Execute.cpp.

References CHECK, and result_set::first_dict_encoded_idx().

Referenced by Executor::resultsUnion().

1251  {
1252  auto& first = results_per_device.front().first;
1253  CHECK(first);
1254  auto const first_target_idx = result_set::first_dict_encoded_idx(targets);
1255  if (first_target_idx) {
1256  first->translateDictEncodedColumns(targets, *first_target_idx);
1257  }
1258  for (size_t dev_idx = 1; dev_idx < results_per_device.size(); ++dev_idx) {
1259  const auto& next = results_per_device[dev_idx].first;
1260  CHECK(next);
1261  if (first_target_idx) {
1262  next->translateDictEncodedColumns(targets, *first_target_idx);
1263  }
1264  first->append(*next);
1265  }
1266  return std::move(first);
1267 }
std::optional< size_t > first_dict_encoded_idx(std::vector< TargetInfo > const &)
Definition: ResultSet.cpp:1461
#define CHECK(condition)
Definition: Logger.h:223

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 1334 of file Execute.cpp.

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

Referenced by Executor::reduceMultiDeviceResultSets().

1337  {
1338  auto clock_begin = timer_start();
1339  // ResultSetReductionJIT::codegen compilation-locks if new code will be generated
1340  *compilation_queue_time = timer_stop(clock_begin);
1341  const auto& this_result_set = results_per_device[0].first;
1342  ResultSetReductionJIT reduction_jit(this_result_set->getQueryMemDesc(),
1343  this_result_set->getTargetInfos(),
1344  this_result_set->getTargetInitVals(),
1345  executor_id);
1346  return reduction_jit.codegen();
1347 };
TypeR::rep timer_stop(Type clock_begin)
Definition: measure.h:48
virtual ReductionCode codegen() const
Type timer_start()
Definition: measure.h:42

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 1494 of file Execute.cpp.

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

1495  {
1496  const auto source_type = input_desc.getSourceType();
1497  if (source_type == InputSourceType::TABLE) {
1498  const auto td = cat.getMetadataForTable(input_desc.getTableId());
1499  CHECK(td);
1500  return td->tableName;
1501  } else {
1502  return "$TEMPORARY_TABLE" + std::to_string(-input_desc.getTableId());
1503  }
1504 }
std::string to_string(char const *&&v)
int getTableId() const
InputSourceType getSourceType() const
#define CHECK(condition)
Definition: Logger.h:223
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:

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

Definition at line 1506 of file Execute.cpp.

References GPU, and Executor::high_scan_limit.

Referenced by checkWorkUnitWatchdog().

1507  {
1508  if (device_type == ExecutorDeviceType::GPU) {
1509  return device_count * Executor::high_scan_limit;
1510  }
1512 }
static const size_t high_scan_limit
Definition: Execute.h:602

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

Referenced by Executor::createKernels().

2507  {
2508  for (const auto& col : fetched_cols) {
2509  if (col.is_lazily_fetched) {
2510  return true;
2511  }
2512  }
2513  return false;
2514 }

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

2215  {
2216  CHECK(ti.is_number() || ti.is_time() || ti.is_boolean() || ti.is_string());
2217  if (ti.is_fp()) {
2218  if (float_argument_input && ti.get_type() == kFLOAT) {
2219  int64_t float_null_val = 0;
2220  *reinterpret_cast<float*>(may_alias_ptr(&float_null_val)) =
2221  static_cast<float>(inline_fp_null_val(ti));
2222  return float_null_val;
2223  }
2224  const auto double_null_val = inline_fp_null_val(ti);
2225  return *reinterpret_cast<const int64_t*>(may_alias_ptr(&double_null_val));
2226  }
2227  return inline_int_null_val(ti);
2228 }
bool is_fp() const
Definition: sqltypes.h:514
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:329
bool is_number() const
Definition: sqltypes.h:515
double inline_fp_null_val(const SQL_TYPE_INFO &ti)
bool is_time() const
Definition: sqltypes.h:516
bool is_boolean() const
Definition: sqltypes.h:517
#define CHECK(condition)
Definition: Logger.h:223
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
bool is_string() const
Definition: sqltypes.h:510

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 211 of file Execute.cpp.

Referenced by foreign_storage::populate_string_dictionary().

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

+ Here is the caller graph for this function:

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

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

Referenced by Executor::collectAllDeviceShardedTopResults().

2376  {
2377  const auto output_buffer = output_storage->getUnderlyingBuffer();
2378  const auto input_buffer = input_storage->getUnderlyingBuffer();
2379  for (const auto sorted_idx : top_permutation) {
2380  // permuting all group-columns in this result set into the final buffer:
2381  for (size_t group_idx = 0; group_idx < input_query_mem_desc.getKeyCount();
2382  group_idx++) {
2383  const auto input_column_ptr =
2384  input_buffer + input_query_mem_desc.getPrependedGroupColOffInBytes(group_idx) +
2385  sorted_idx * input_query_mem_desc.groupColWidth(group_idx);
2386  const auto output_column_ptr =
2387  output_buffer +
2388  output_query_mem_desc.getPrependedGroupColOffInBytes(group_idx) +
2389  output_row_index * output_query_mem_desc.groupColWidth(group_idx);
2390  memcpy(output_column_ptr,
2391  input_column_ptr,
2392  output_query_mem_desc.groupColWidth(group_idx));
2393  }
2394  // permuting all agg-columns in this result set into the final buffer:
2395  for (size_t slot_idx = 0; slot_idx < input_query_mem_desc.getSlotCount();
2396  slot_idx++) {
2397  const auto input_column_ptr =
2398  input_buffer + input_query_mem_desc.getColOffInBytes(slot_idx) +
2399  sorted_idx * input_query_mem_desc.getPaddedSlotWidthBytes(slot_idx);
2400  const auto output_column_ptr =
2401  output_buffer + output_query_mem_desc.getColOffInBytes(slot_idx) +
2402  output_row_index * output_query_mem_desc.getPaddedSlotWidthBytes(slot_idx);
2403  memcpy(output_column_ptr,
2404  input_column_ptr,
2405  output_query_mem_desc.getPaddedSlotWidthBytes(slot_idx));
2406  }
2407  ++output_row_index;
2408  }
2409  return output_row_index;
2410 }
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 2421 of file Execute.cpp.

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

Referenced by Executor::collectAllDeviceShardedTopResults().

2425  {
2426  const auto output_buffer = output_storage->getUnderlyingBuffer();
2427  const auto input_buffer = input_storage->getUnderlyingBuffer();
2428  for (const auto sorted_idx : top_permutation) {
2429  const auto row_ptr = input_buffer + sorted_idx * output_query_mem_desc.getRowSize();
2430  memcpy(output_buffer + output_row_index * output_query_mem_desc.getRowSize(),
2431  row_ptr,
2432  output_query_mem_desc.getRowSize());
2433  ++output_row_index;
2434  }
2435  return output_row_index;
2436 }
int8_t * getUnderlyingBuffer() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 204 of file Execute.cpp.

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

205  {
206  for (const auto [col_id, table_id] : phys_inputs) {
207  foreign_storage::populate_string_dictionary(table_id, col_id, catalog);
208  }
209 }
void populate_string_dictionary(const int32_t table_id, const int32_t col_id, const Catalog_Namespace::Catalog &catalog)
Definition: Execute.cpp:221

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

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

Referenced by Executor::executeWorkUnit().

1724  {
1725  return {ra_exe_unit_in.input_descs,
1726  ra_exe_unit_in.input_col_descs,
1727  ra_exe_unit_in.simple_quals,
1728  ra_exe_unit_in.quals,
1729  ra_exe_unit_in.join_quals,
1730  ra_exe_unit_in.groupby_exprs,
1731  ra_exe_unit_in.target_exprs,
1732  ra_exe_unit_in.estimator,
1733  ra_exe_unit_in.sort_info,
1734  new_scan_limit,
1735  ra_exe_unit_in.query_hint,
1736  ra_exe_unit_in.query_plan_dag_hash,
1737  ra_exe_unit_in.hash_table_build_plan_dag,
1738  ra_exe_unit_in.table_id_to_node_map,
1739  ra_exe_unit_in.use_bump_allocator,
1740  ra_exe_unit_in.union_all,
1741  ra_exe_unit_in.query_state};
1742 }
std::vector< Analyzer::Expr * > target_exprs
QueryPlanHash query_plan_dag_hash
const std::optional< bool > union_all
std::vector< InputDescriptor > input_descs
const std::list< std::shared_ptr< Analyzer::Expr > > groupby_exprs
const JoinQualsPerNestingLevel join_quals
TableIdToNodeMap table_id_to_node_map
const std::shared_ptr< Analyzer::Estimator > estimator
std::list< std::shared_ptr< Analyzer::Expr > > quals
RegisteredQueryHint query_hint
std::shared_ptr< const query_state::QueryState > query_state
std::list< std::shared_ptr< const InputColDescriptor > > input_col_descs
std::list< std::shared_ptr< Analyzer::Expr > > simple_quals
HashTableBuildDagMap hash_table_build_plan_dag

+ Here is the caller graph for this function:

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

Definition at line 1607 of file Execute.cpp.

References Default, SpeculativeTopN, StreamingTopN, and UNREACHABLE.

Referenced by operator<<().

1607  {
1608  switch (algorithm) {
1610  return "ResultSet";
1612  return "Speculative Top N";
1614  return "Streaming Top N";
1615  }
1616  UNREACHABLE();
1617  return "";
1618 }
#define UNREACHABLE()
Definition: Logger.h:267

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

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

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

2810  {
2811  const int table_id = col_desc->getScanDesc().getTableId();
2812  const int col_id = col_desc->getColId();
2813  return get_column_descriptor_maybe(col_id, table_id, cat);
2814 }
const ColumnDescriptor * get_column_descriptor_maybe(const int col_id, const int table_id, const Catalog_Namespace::Catalog &cat)
Definition: Execute.h:220
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: