OmniSciDB  471d68cefb
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups 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 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 3534 of file Execute.cpp.

References CHECK, CHECK_EQ, and ColumnDescriptor::tableId.

Referenced by Executor::addDeletedColumn().

3535  {
3536  auto deleted_cols_it = deleted_cols_map.find(deleted_cd->tableId);
3537  if (deleted_cols_it == deleted_cols_map.end()) {
3538  CHECK(
3539  deleted_cols_map.insert(std::make_pair(deleted_cd->tableId, deleted_cd)).second);
3540  } else {
3541  CHECK_EQ(deleted_cd, deleted_cols_it->second);
3542  }
3543 }
#define CHECK_EQ(x, y)
Definition: Logger.h:217
#define CHECK(condition)
Definition: Logger.h:209

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

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

Referenced by Executor::collectAllDeviceResults().

1881  {
1882  std::vector<std::shared_ptr<Analyzer::Expr>> target_exprs_owned_copies;
1883  std::vector<Analyzer::Expr*> target_exprs;
1884  for (const auto target_expr : target_exprs_in) {
1885  const auto target_expr_copy =
1886  std::dynamic_pointer_cast<Analyzer::AggExpr>(target_expr->deep_copy());
1887  CHECK(target_expr_copy);
1888  auto ti = target_expr->get_type_info();
1889  ti.set_notnull(false);
1890  target_expr_copy->set_type_info(ti);
1891  if (target_expr_copy->get_arg()) {
1892  auto arg_ti = target_expr_copy->get_arg()->get_type_info();
1893  arg_ti.set_notnull(false);
1894  target_expr_copy->get_arg()->set_type_info(arg_ti);
1895  }
1896  target_exprs_owned_copies.push_back(target_expr_copy);
1897  target_exprs.push_back(target_expr_copy.get());
1898  }
1899  std::vector<TargetInfo> target_infos;
1900  std::vector<int64_t> entry;
1901  fill_entries_for_empty_input(target_infos, entry, target_exprs, query_mem_desc);
1902  const auto executor = query_mem_desc.getExecutor();
1903  CHECK(executor);
1904  auto row_set_mem_owner = executor->getRowSetMemoryOwner();
1905  CHECK(row_set_mem_owner);
1906  auto rs = std::make_shared<ResultSet>(target_infos,
1907  device_type,
1909  row_set_mem_owner,
1910  executor->getCatalog(),
1911  executor->blockSize(),
1912  executor->gridSize());
1913  rs->allocateStorage();
1914  rs->fillOneEntry(entry);
1915  return rs;
1916 }
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:1823
#define CHECK(condition)
Definition: Logger.h:209
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 3148 of file Execute.cpp.

References CHECK.

Referenced by Executor::executePlanWithGroupBy().

3148  {
3149  CHECK(scan_limit);
3150  return results && results->rowCount() < scan_limit;
3151 }
#define CHECK(condition)
Definition: Logger.h:209

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

1140  {
1141  for (const auto target_expr : ra_exe_unit.target_exprs) {
1142  if (dynamic_cast<const Analyzer::AggExpr*>(target_expr)) {
1143  return;
1144  }
1145  }
1146  if (!ra_exe_unit.scan_limit && table_infos.size() == 1 &&
1147  table_infos.front().info.getPhysicalNumTuples() < Executor::high_scan_limit) {
1148  // Allow a query with no scan limit to run on small tables
1149  return;
1150  }
1151  if (ra_exe_unit.use_bump_allocator) {
1152  // Bump allocator removes the scan limit (and any knowledge of the size of the output
1153  // relative to the size of the input), so we bypass this check for now
1154  return;
1155  }
1156  if (ra_exe_unit.sort_info.algorithm != SortAlgorithm::StreamingTopN &&
1157  ra_exe_unit.groupby_exprs.size() == 1 && !ra_exe_unit.groupby_exprs.front() &&
1158  (!ra_exe_unit.scan_limit ||
1159  ra_exe_unit.scan_limit > getDeviceBasedScanLimit(device_type, device_count))) {
1160  std::vector<std::string> table_names;
1161  const auto& input_descs = ra_exe_unit.input_descs;
1162  for (const auto& input_desc : input_descs) {
1163  table_names.push_back(get_table_name(input_desc, cat));
1164  }
1165  if (!ra_exe_unit.scan_limit) {
1166  throw WatchdogException(
1167  "Projection query would require a scan without a limit on table(s): " +
1168  boost::algorithm::join(table_names, ", "));
1169  } else {
1170  throw WatchdogException(
1171  "Projection query output result set on table(s): " +
1172  boost::algorithm::join(table_names, ", ") + " would contain " +
1173  std::to_string(ra_exe_unit.scan_limit) +
1174  " rows, which is more than the current system limit of " +
1175  std::to_string(getDeviceBasedScanLimit(device_type, device_count)));
1176  }
1177  }
1178 }
std::vector< Analyzer::Expr * > target_exprs
std::string get_table_name(const InputDescriptor &input_desc, const Catalog_Namespace::Catalog &cat)
Definition: Execute.cpp:1116
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:479
size_t getDeviceBasedScanLimit(const ExecutorDeviceType device_type, const int device_count)
Definition: Execute.cpp:1128

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

References CHECK.

Referenced by Executor::executeWorkUnitImpl().

1086  {
1088  // Check for overflows since we're multiplying potentially big table sizes.
1089  using checked_size_t = boost::multiprecision::number<
1090  boost::multiprecision::cpp_int_backend<64,
1091  64,
1092  boost::multiprecision::unsigned_magnitude,
1093  boost::multiprecision::checked,
1094  void>>;
1095  checked_size_t max_groups_buffer_entry_guess = 1;
1096  for (const auto& query_info : query_infos) {
1097  CHECK(!query_info.info.fragments.empty());
1098  auto it = std::max_element(query_info.info.fragments.begin(),
1099  query_info.info.fragments.end(),
1100  [](const FragmentInfo& f1, const FragmentInfo& f2) {
1101  return f1.getNumTuples() < f2.getNumTuples();
1102  });
1103  max_groups_buffer_entry_guess *= it->getNumTuples();
1104  }
1105  // Cap the rough approximation to 100M entries, it's unlikely we can do a great job for
1106  // baseline group layout with that many entries anyway.
1107  constexpr size_t max_groups_buffer_entry_guess_cap = 100000000;
1108  try {
1109  return std::min(static_cast<size_t>(max_groups_buffer_entry_guess),
1110  max_groups_buffer_entry_guess_cap);
1111  } catch (...) {
1112  return max_groups_buffer_entry_guess_cap;
1113  }
1114 }
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:209

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

Referenced by operator<<().

1207  {
1208  std::vector<std::string> expr_strs;
1209  for (const auto& expr : expr_container) {
1210  if (!expr) {
1211  expr_strs.emplace_back("NULL");
1212  } else {
1213  expr_strs.emplace_back(expr->toString());
1214  }
1215  }
1216  return expr_strs;
1217 }

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

1221  {
1222  std::vector<std::string> expr_strs;
1223  for (const auto& expr : expr_container) {
1224  expr_strs.emplace_back(expr.toString());
1225  }
1226  return expr_strs;
1227 }
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 1823 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().

1826  {
1827  for (size_t target_idx = 0; target_idx < target_exprs.size(); ++target_idx) {
1828  const auto target_expr = target_exprs[target_idx];
1829  const auto agg_info = get_target_info(target_expr, g_bigint_count);
1830  CHECK(agg_info.is_agg);
1831  target_infos.push_back(agg_info);
1832  if (g_cluster) {
1833  const auto executor = query_mem_desc.getExecutor();
1834  CHECK(executor);
1835  auto row_set_mem_owner = executor->getRowSetMemoryOwner();
1836  CHECK(row_set_mem_owner);
1837  const auto& count_distinct_desc =
1838  query_mem_desc.getCountDistinctDescriptor(target_idx);
1839  if (count_distinct_desc.impl_type_ == CountDistinctImplType::Bitmap) {
1840  CHECK(row_set_mem_owner);
1841  auto count_distinct_buffer = row_set_mem_owner->allocateCountDistinctBuffer(
1842  count_distinct_desc.bitmapPaddedSizeBytes(),
1843  /*thread_idx=*/0); // TODO: can we detect thread idx here?
1844  entry.push_back(reinterpret_cast<int64_t>(count_distinct_buffer));
1845  continue;
1846  }
1847  if (count_distinct_desc.impl_type_ == CountDistinctImplType::StdSet) {
1848  auto count_distinct_set = new std::set<int64_t>();
1849  CHECK(row_set_mem_owner);
1850  row_set_mem_owner->addCountDistinctSet(count_distinct_set);
1851  entry.push_back(reinterpret_cast<int64_t>(count_distinct_set));
1852  continue;
1853  }
1854  }
1855  const bool float_argument_input = takes_float_argument(agg_info);
1856  if (agg_info.agg_kind == kCOUNT || agg_info.agg_kind == kAPPROX_COUNT_DISTINCT) {
1857  entry.push_back(0);
1858  } else if (agg_info.agg_kind == kAVG) {
1859  entry.push_back(0);
1860  entry.push_back(0);
1861  } else if (agg_info.agg_kind == kSINGLE_VALUE || agg_info.agg_kind == kSAMPLE) {
1862  if (agg_info.sql_type.is_geometry() && !agg_info.is_varlen_projection) {
1863  for (int i = 0; i < agg_info.sql_type.get_physical_coord_cols() * 2; i++) {
1864  entry.push_back(0);
1865  }
1866  } else if (agg_info.sql_type.is_varlen()) {
1867  entry.push_back(0);
1868  entry.push_back(0);
1869  } else {
1870  entry.push_back(inline_null_val(agg_info.sql_type, float_argument_input));
1871  }
1872  } else {
1873  entry.push_back(inline_null_val(agg_info.sql_type, float_argument_input));
1874  }
1875  }
1876 }
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:1808
bool g_bigint_count
const CountDistinctDescriptor & getCountDistinctDescriptor(const size_t idx) const
Definition: sqldefs.h:76
#define CHECK(condition)
Definition: Logger.h:209
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 3590 of file Execute.cpp.

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

Referenced by Executor::skipFragment().

3594  {
3595  const int32_t ldim = lhs_type.get_dimension();
3596  const int32_t rdim = rhs_type.get_dimension();
3597  CHECK(ldim != rdim);
3598  const auto scale = DateTimeUtils::get_timestamp_precision_scale(abs(rdim - ldim));
3599  if (ldim > rdim) {
3600  // LHS type precision is more than RHS col type. No chance of overflow/underflow.
3601  return {true, chunk_min / scale, chunk_max / scale};
3602  }
3603 
3604  using checked_int64_t = boost::multiprecision::number<
3605  boost::multiprecision::cpp_int_backend<64,
3606  64,
3607  boost::multiprecision::signed_magnitude,
3608  boost::multiprecision::checked,
3609  void>>;
3610 
3611  try {
3612  auto ret =
3613  std::make_tuple(true,
3614  int64_t(checked_int64_t(chunk_min) * checked_int64_t(scale)),
3615  int64_t(checked_int64_t(chunk_max) * checked_int64_t(scale)));
3616  return ret;
3617  } catch (const std::overflow_error& e) {
3618  // noop
3619  }
3620  return std::make_tuple(false, chunk_min, chunk_max);
3621 }
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:209
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 884 of file Execute.cpp.

References CHECK.

Referenced by Executor::resultsUnion().

885  {
886  auto& first = results_per_device.front().first;
887  CHECK(first);
888  for (size_t dev_idx = 1; dev_idx < results_per_device.size(); ++dev_idx) {
889  const auto& next = results_per_device[dev_idx].first;
890  CHECK(next);
891  first->append(*next);
892  }
893  return std::move(first);
894 }
#define CHECK(condition)
Definition: Logger.h:209

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

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

Referenced by Executor::reduceMultiDeviceResultSets().

960  {
961  auto clock_begin = timer_start();
962  std::lock_guard<std::mutex> compilation_lock(Executor::compilation_mutex_);
963  *compilation_queue_time = timer_stop(clock_begin);
964  const auto& this_result_set = results_per_device[0].first;
965  ResultSetReductionJIT reduction_jit(this_result_set->getQueryMemDesc(),
966  this_result_set->getTargetInfos(),
967  this_result_set->getTargetInitVals());
968  return reduction_jit.codegen();
969 };
TypeR::rep timer_stop(Type clock_begin)
Definition: measure.h:48
virtual ReductionCode codegen() const
static std::mutex compilation_mutex_
Definition: Execute.h:1172
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 1116 of file Execute.cpp.

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

Referenced by checkWorkUnitWatchdog().

1117  {
1118  const auto source_type = input_desc.getSourceType();
1119  if (source_type == InputSourceType::TABLE) {
1120  const auto td = cat.getMetadataForTable(input_desc.getTableId());
1121  CHECK(td);
1122  return td->tableName;
1123  } else {
1124  return "$TEMPORARY_TABLE" + std::to_string(-input_desc.getTableId());
1125  }
1126 }
std::string to_string(char const *&&v)
int getTableId() const
InputSourceType getSourceType() const
#define CHECK(condition)
Definition: Logger.h:209
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 1128 of file Execute.cpp.

References GPU, and Executor::high_scan_limit.

Referenced by checkWorkUnitWatchdog().

1129  {
1130  if (device_type == ExecutorDeviceType::GPU) {
1131  return device_count * Executor::high_scan_limit;
1132  }
1134 }
static const size_t high_scan_limit
Definition: Execute.h:479

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

Referenced by Executor::createKernels().

2100  {
2101  for (const auto& col : fetched_cols) {
2102  if (col.is_lazily_fetched) {
2103  return true;
2104  }
2105  }
2106  return false;
2107 }

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

1808  {
1809  CHECK(ti.is_number() || ti.is_time() || ti.is_boolean() || ti.is_string());
1810  if (ti.is_fp()) {
1811  if (float_argument_input && ti.get_type() == kFLOAT) {
1812  int64_t float_null_val = 0;
1813  *reinterpret_cast<float*>(may_alias_ptr(&float_null_val)) =
1814  static_cast<float>(inline_fp_null_val(ti));
1815  return float_null_val;
1816  }
1817  const auto double_null_val = inline_fp_null_val(ti);
1818  return *reinterpret_cast<const int64_t*>(may_alias_ptr(&double_null_val));
1819  }
1820  return inline_int_null_val(ti);
1821 }
bool is_fp() const
Definition: sqltypes.h:513
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:329
bool is_number() const
Definition: sqltypes.h:514
double inline_fp_null_val(const SQL_TYPE_INFO &ti)
bool is_time() const
Definition: sqltypes.h:515
bool is_boolean() const
Definition: sqltypes.h:516
#define CHECK(condition)
Definition: Logger.h:209
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
bool is_string() const
Definition: sqltypes.h:509

+ Here is the call graph for this function:

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

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

Referenced by Executor::collectAllDeviceShardedTopResults().

1969  {
1970  const auto output_buffer = output_storage->getUnderlyingBuffer();
1971  const auto input_buffer = input_storage->getUnderlyingBuffer();
1972  for (const auto sorted_idx : top_permutation) {
1973  // permuting all group-columns in this result set into the final buffer:
1974  for (size_t group_idx = 0; group_idx < input_query_mem_desc.getKeyCount();
1975  group_idx++) {
1976  const auto input_column_ptr =
1977  input_buffer + input_query_mem_desc.getPrependedGroupColOffInBytes(group_idx) +
1978  sorted_idx * input_query_mem_desc.groupColWidth(group_idx);
1979  const auto output_column_ptr =
1980  output_buffer +
1981  output_query_mem_desc.getPrependedGroupColOffInBytes(group_idx) +
1982  output_row_index * output_query_mem_desc.groupColWidth(group_idx);
1983  memcpy(output_column_ptr,
1984  input_column_ptr,
1985  output_query_mem_desc.groupColWidth(group_idx));
1986  }
1987  // permuting all agg-columns in this result set into the final buffer:
1988  for (size_t slot_idx = 0; slot_idx < input_query_mem_desc.getSlotCount();
1989  slot_idx++) {
1990  const auto input_column_ptr =
1991  input_buffer + input_query_mem_desc.getColOffInBytes(slot_idx) +
1992  sorted_idx * input_query_mem_desc.getPaddedSlotWidthBytes(slot_idx);
1993  const auto output_column_ptr =
1994  output_buffer + output_query_mem_desc.getColOffInBytes(slot_idx) +
1995  output_row_index * output_query_mem_desc.getPaddedSlotWidthBytes(slot_idx);
1996  memcpy(output_column_ptr,
1997  input_column_ptr,
1998  output_query_mem_desc.getPaddedSlotWidthBytes(slot_idx));
1999  }
2000  ++output_row_index;
2001  }
2002  return output_row_index;
2003 }
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 2014 of file Execute.cpp.

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

Referenced by Executor::collectAllDeviceShardedTopResults().

2018  {
2019  const auto output_buffer = output_storage->getUnderlyingBuffer();
2020  const auto input_buffer = input_storage->getUnderlyingBuffer();
2021  for (const auto sorted_idx : top_permutation) {
2022  const auto row_ptr = input_buffer + sorted_idx * output_query_mem_desc.getRowSize();
2023  memcpy(output_buffer + output_row_index * output_query_mem_desc.getRowSize(),
2024  row_ptr,
2025  output_query_mem_desc.getRowSize());
2026  ++output_row_index;
2027  }
2028  return output_row_index;
2029 }
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 1347 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, 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().

1348  {
1349  return {ra_exe_unit_in.input_descs,
1350  ra_exe_unit_in.input_col_descs,
1351  ra_exe_unit_in.simple_quals,
1352  ra_exe_unit_in.quals,
1353  ra_exe_unit_in.join_quals,
1354  ra_exe_unit_in.groupby_exprs,
1355  ra_exe_unit_in.target_exprs,
1356  ra_exe_unit_in.estimator,
1357  ra_exe_unit_in.sort_info,
1358  new_scan_limit,
1359  ra_exe_unit_in.query_hint,
1360  ra_exe_unit_in.query_plan_dag,
1361  ra_exe_unit_in.hash_table_build_plan_dag,
1362  ra_exe_unit_in.table_id_to_node_map,
1363  ra_exe_unit_in.use_bump_allocator,
1364  ra_exe_unit_in.union_all,
1365  ra_exe_unit_in.query_state};
1366 }
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 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 1229 of file Execute.cpp.

References Default, SpeculativeTopN, StreamingTopN, and UNREACHABLE.

Referenced by operator<<().

1229  {
1230  switch (algorithm) {
1232  return "ResultSet";
1234  return "Speculative Top N";
1236  return "Streaming Top N";
1237  }
1238  UNREACHABLE();
1239  return "";
1240 }
#define UNREACHABLE()
Definition: Logger.h:253

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

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

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

2402  {
2403  const int table_id = col_desc->getScanDesc().getTableId();
2404  const int col_id = col_desc->getColId();
2405  return get_column_descriptor_maybe(col_id, table_id, cat);
2406 }
const ColumnDescriptor * get_column_descriptor_maybe(const int col_id, const int table_id, const Catalog_Namespace::Catalog &cat)
Definition: Execute.h:218
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: