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

Namespaces

 anonymous_namespace{RelAlgExecutor.cpp}
 

Classes

class  RelLeftDeepTreeIdsCollector
 
struct  TextEncodingCastCounts
 
class  TextEncodingCastCountVisitor
 
class  RexUsedInputsVisitor
 
struct  ErrorInfo
 

Functions

bool node_is_aggregate (const RelAlgNode *ra)
 
std::unordered_set< PhysicalInputget_physical_inputs_with_spi_col_id (const RelAlgNode *ra)
 
void set_parallelism_hints (const RelAlgNode &ra_node)
 
void prepare_string_dictionaries (const RelAlgNode &ra_node)
 
void prepare_foreign_table_for_execution (const RelAlgNode &ra_node)
 
void prepare_for_system_table_execution (const RelAlgNode &ra_node, const CompilationOptions &co)
 
bool has_valid_query_plan_dag (const RelAlgNode *node)
 
std::list< Analyzer::OrderEntryget_order_entries (const RelSort *sort)
 
void build_render_targets (RenderInfo &render_info, const std::vector< Analyzer::Expr * > &work_unit_target_exprs, const std::vector< TargetMetaInfo > &targets_meta)
 
bool is_validate_or_explain_query (const ExecutionOptions &eo)
 
TextEncodingCastCounts get_text_cast_counts (const RelAlgExecutionUnit &ra_exe_unit)
 
void check_none_encoded_string_cast_tuple_limit (const std::vector< InputTableInfo > &query_infos, const RelAlgExecutionUnit &ra_exe_unit)
 
void check_sort_node_source_constraint (const RelSort *sort)
 
const RelAlgNodeget_data_sink (const RelAlgNode *ra_node)
 
std::pair< std::unordered_set
< const RexInput * >
, std::vector< std::shared_ptr
< RexInput > > > 
get_used_inputs (const RelCompound *compound)
 
std::pair< std::unordered_set
< const RexInput * >
, std::vector< std::shared_ptr
< RexInput > > > 
get_used_inputs (const RelAggregate *aggregate)
 
std::pair< std::unordered_set
< const RexInput * >
, std::vector< std::shared_ptr
< RexInput > > > 
get_used_inputs (const RelProject *project)
 
std::pair< std::unordered_set
< const RexInput * >
, std::vector< std::shared_ptr
< RexInput > > > 
get_used_inputs (const RelTableFunction *table_func)
 
std::pair< std::unordered_set
< const RexInput * >
, std::vector< std::shared_ptr
< RexInput > > > 
get_used_inputs (const RelFilter *filter)
 
std::pair< std::unordered_set
< const RexInput * >
, std::vector< std::shared_ptr
< RexInput > > > 
get_used_inputs (const RelLogicalUnion *logical_union)
 
shared::TableKey table_key_from_ra (const RelAlgNode *ra_node)
 
std::unordered_map< const
RelAlgNode *, int > 
get_input_nest_levels (const RelAlgNode *ra_node, const std::vector< size_t > &input_permutation)
 
std::pair< std::unordered_set
< const RexInput * >
, std::vector< std::shared_ptr
< RexInput > > > 
get_join_source_used_inputs (const RelAlgNode *ra_node)
 
void collect_used_input_desc (std::vector< InputDescriptor > &input_descs, std::unordered_set< std::shared_ptr< const InputColDescriptor >> &input_col_descs_unique, const RelAlgNode *ra_node, const std::unordered_set< const RexInput * > &source_used_inputs, const std::unordered_map< const RelAlgNode *, int > &input_to_nest_level)
 
template<class RA >
std::pair< std::vector
< InputDescriptor >, std::list
< std::shared_ptr< const
InputColDescriptor > > > 
get_input_desc_impl (const RA *ra_node, const std::unordered_set< const RexInput * > &used_inputs, const std::unordered_map< const RelAlgNode *, int > &input_to_nest_level, const std::vector< size_t > &input_permutation)
 
template<class RA >
std::tuple< std::vector
< InputDescriptor >, std::list
< std::shared_ptr< const
InputColDescriptor >
>, std::vector
< std::shared_ptr< RexInput > > > 
get_input_desc (const RA *ra_node, const std::unordered_map< const RelAlgNode *, int > &input_to_nest_level, const std::vector< size_t > &input_permutation)
 
size_t get_scalar_sources_size (const RelCompound *compound)
 
size_t get_scalar_sources_size (const RelProject *project)
 
size_t get_scalar_sources_size (const RelTableFunction *table_func)
 
const RexScalarscalar_at (const size_t i, const RelCompound *compound)
 
const RexScalarscalar_at (const size_t i, const RelProject *project)
 
const RexScalarscalar_at (const size_t i, const RelTableFunction *table_func)
 
std::shared_ptr< Analyzer::Exprset_transient_dict (const std::shared_ptr< Analyzer::Expr > expr)
 
void set_transient_dict_maybe (std::vector< std::shared_ptr< Analyzer::Expr >> &scalar_sources, const std::shared_ptr< Analyzer::Expr > &expr)
 
std::shared_ptr< Analyzer::Exprcast_dict_to_none (const std::shared_ptr< Analyzer::Expr > &input)
 
template<class RA >
std::vector< std::shared_ptr
< Analyzer::Expr > > 
translate_scalar_sources (const RA *ra_node, const RelAlgTranslator &translator, const ::ExecutorType executor_type)
 
template<class RA >
std::vector< std::shared_ptr
< Analyzer::Expr > > 
translate_scalar_sources_for_update (const RA *ra_node, const RelAlgTranslator &translator, int32_t tableId, const Catalog_Namespace::Catalog &cat, const ColumnNameList &colNames, size_t starting_projection_column_idx)
 
std::list< std::shared_ptr
< Analyzer::Expr > > 
translate_groupby_exprs (const RelCompound *compound, const std::vector< std::shared_ptr< Analyzer::Expr >> &scalar_sources)
 
std::list< std::shared_ptr
< Analyzer::Expr > > 
translate_groupby_exprs (const RelAggregate *aggregate, const std::vector< std::shared_ptr< Analyzer::Expr >> &scalar_sources)
 
QualsConjunctiveForm translate_quals (const RelCompound *compound, const RelAlgTranslator &translator)
 
std::vector< Analyzer::Expr * > translate_targets (std::vector< std::shared_ptr< Analyzer::Expr >> &target_exprs_owned, std::unordered_map< size_t, SQLTypeInfo > &target_exprs_type_infos, const std::vector< std::shared_ptr< Analyzer::Expr >> &scalar_sources, const std::list< std::shared_ptr< Analyzer::Expr >> &groupby_exprs, const RelCompound *compound, const RelAlgTranslator &translator, const ExecutorType executor_type)
 
std::vector< Analyzer::Expr * > translate_targets (std::vector< std::shared_ptr< Analyzer::Expr >> &target_exprs_owned, std::unordered_map< size_t, SQLTypeInfo > &target_exprs_type_infos, const std::vector< std::shared_ptr< Analyzer::Expr >> &scalar_sources, const std::list< std::shared_ptr< Analyzer::Expr >> &groupby_exprs, const RelAggregate *aggregate, const RelAlgTranslator &translator)
 
bool is_count_distinct (const Analyzer::Expr *expr)
 
bool is_agg (const Analyzer::Expr *expr)
 
SQLTypeInfo get_logical_type_for_expr (const Analyzer::Expr &expr)
 
template<class RA >
std::vector< TargetMetaInfoget_targets_meta (const RA *ra_node, const std::vector< Analyzer::Expr * > &target_exprs)
 
template<>
std::vector< TargetMetaInfoget_targets_meta (const RelFilter *filter, const std::vector< Analyzer::Expr * > &target_exprs)
 
bool is_window_execution_unit (const RelAlgExecutionUnit &ra_exe_unit)
 
std::shared_ptr< Analyzer::Exprtransform_to_inner (const Analyzer::Expr *expr)
 
template<class T >
int64_t insert_one_dict_str (T *col_data, const std::string &columnName, const SQLTypeInfo &columnType, const Analyzer::Constant *col_cv, const Catalog_Namespace::Catalog &catalog)
 
template<class T >
int64_t insert_one_dict_str (T *col_data, const ColumnDescriptor *cd, const Analyzer::Constant *col_cv, const Catalog_Namespace::Catalog &catalog)
 
size_t get_scan_limit (const RelAlgNode *ra, const size_t limit)
 
bool first_oe_is_desc (const std::list< Analyzer::OrderEntry > &order_entries)
 
size_t groups_approx_upper_bound (const std::vector< InputTableInfo > &table_infos)
 
bool is_projection (const RelAlgExecutionUnit &ra_exe_unit)
 
bool can_output_columnar (const RelAlgExecutionUnit &ra_exe_unit, const RenderInfo *render_info, const RelAlgNode *body)
 
bool should_output_columnar (const RelAlgExecutionUnit &ra_exe_unit)
 
bool compute_output_buffer_size (const RelAlgExecutionUnit &ra_exe_unit)
 
bool exe_unit_has_quals (const RelAlgExecutionUnit ra_exe_unit)
 
RelAlgExecutionUnit decide_approx_count_distinct_implementation (const RelAlgExecutionUnit &ra_exe_unit_in, const std::vector< InputTableInfo > &table_infos, const Executor *executor, const ExecutorDeviceType device_type_in, std::vector< std::shared_ptr< Analyzer::Expr >> &target_exprs_owned)
 
bool can_use_bump_allocator (const RelAlgExecutionUnit &ra_exe_unit, const CompilationOptions &co, const ExecutionOptions &eo)
 
ErrorInfo getErrorDescription (const int32_t error_code)
 
JoinType get_join_type (const RelAlgNode *ra)
 
std::unique_ptr< const
RexOperator
get_bitwise_equals (const RexScalar *scalar)
 
std::unique_ptr< const
RexOperator
get_bitwise_equals_conjunction (const RexScalar *scalar)
 
std::vector< JoinTypeleft_deep_join_types (const RelLeftDeepInnerJoin *left_deep_join)
 
template<class RA >
std::vector< size_t > do_table_reordering (std::vector< InputDescriptor > &input_descs, std::list< std::shared_ptr< const InputColDescriptor >> &input_col_descs, const JoinQualsPerNestingLevel &left_deep_join_quals, std::unordered_map< const RelAlgNode *, int > &input_to_nest_level, const RA *node, const std::vector< InputTableInfo > &query_infos, const Executor *executor)
 
std::vector< size_t > get_left_deep_join_input_sizes (const RelLeftDeepInnerJoin *left_deep_join)
 
std::list< std::shared_ptr
< Analyzer::Expr > > 
rewrite_quals (const std::list< std::shared_ptr< Analyzer::Expr >> &quals)
 
std::vector< const RexScalar * > rex_to_conjunctive_form (const RexScalar *qual_expr)
 
std::shared_ptr< Analyzer::Exprbuild_logical_expression (const std::vector< std::shared_ptr< Analyzer::Expr >> &factors, const SQLOps sql_op)
 
template<class QualsList >
bool list_contains_expression (const QualsList &haystack, const std::shared_ptr< Analyzer::Expr > &needle)
 
std::shared_ptr< Analyzer::Exprreverse_logical_distribution (const std::shared_ptr< Analyzer::Expr > &expr)
 
std::vector< std::shared_ptr
< Analyzer::Expr > > 
synthesize_inputs (const RelAlgNode *ra_node, const size_t nest_level, const std::vector< TargetMetaInfo > &in_metainfo, const std::unordered_map< const RelAlgNode *, int > &input_to_nest_level)
 
std::vector< Analyzer::Expr * > get_raw_pointers (std::vector< std::shared_ptr< Analyzer::Expr >> const &input)
 
std::vector< std::shared_ptr
< Analyzer::Expr > > 
target_exprs_for_union (RelAlgNode const *input_node)
 
std::pair< std::vector
< TargetMetaInfo >
, std::vector< std::shared_ptr
< Analyzer::Expr > > > 
get_inputs_meta (const RelFilter *filter, const RelAlgTranslator &translator, const std::vector< std::shared_ptr< RexInput >> &inputs_owned, const std::unordered_map< const RelAlgNode *, int > &input_to_nest_level)
 

Function Documentation

std::shared_ptr<Analyzer::Expr> anonymous_namespace{RelAlgExecutor.cpp}::build_logical_expression ( const std::vector< std::shared_ptr< Analyzer::Expr >> &  factors,
const SQLOps  sql_op 
)

Definition at line 4607 of file RelAlgExecutor.cpp.

References CHECK, kONE, and Parser::OperExpr::normalize().

Referenced by reverse_logical_distribution().

4609  {
4610  CHECK(!factors.empty());
4611  auto acc = factors.front();
4612  for (size_t i = 1; i < factors.size(); ++i) {
4613  acc = Parser::OperExpr::normalize(sql_op, kONE, acc, factors[i]);
4614  }
4615  return acc;
4616 }
static std::shared_ptr< Analyzer::Expr > normalize(const SQLOps optype, const SQLQualifier qual, std::shared_ptr< Analyzer::Expr > left_expr, std::shared_ptr< Analyzer::Expr > right_expr, const Executor *executor=nullptr)
Definition: ParserNode.cpp:372
Definition: sqldefs.h:71
#define CHECK(condition)
Definition: Logger.h:291

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void anonymous_namespace{RelAlgExecutor.cpp}::build_render_targets ( RenderInfo render_info,
const std::vector< Analyzer::Expr * > &  work_unit_target_exprs,
const std::vector< TargetMetaInfo > &  targets_meta 
)

Definition at line 235 of file RelAlgExecutor.cpp.

References CHECK_EQ, and RenderInfo::targets.

Referenced by RelAlgExecutor::executeRelAlgStep(), RelAlgExecutor::executeSort(), and RelAlgExecutor::executeWorkUnit().

237  {
238  CHECK_EQ(work_unit_target_exprs.size(), targets_meta.size());
239  render_info.targets.clear();
240  for (size_t i = 0; i < targets_meta.size(); ++i) {
241  render_info.targets.emplace_back(std::make_shared<Analyzer::TargetEntry>(
242  targets_meta[i].get_resname(),
243  work_unit_target_exprs[i]->get_shared_ptr(),
244  false));
245  }
246 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
std::vector< std::shared_ptr< Analyzer::TargetEntry > > targets
Definition: RenderInfo.h:37

+ Here is the caller graph for this function:

bool anonymous_namespace{RelAlgExecutor.cpp}::can_output_columnar ( const RelAlgExecutionUnit ra_exe_unit,
const RenderInfo render_info,
const RelAlgNode body 
)

Definition at line 3526 of file RelAlgExecutor.cpp.

References is_projection(), heavyai::InSituFlagsOwnerInterface::isInSitu(), SortInfo::order_entries, RelAlgExecutionUnit::sort_info, and RelAlgExecutionUnit::target_exprs.

Referenced by RelAlgExecutor::executeWorkUnit().

3528  {
3529  if (!is_projection(ra_exe_unit)) {
3530  return false;
3531  }
3532  if (render_info && render_info->isInSitu()) {
3533  return false;
3534  }
3535  if (!ra_exe_unit.sort_info.order_entries.empty()) {
3536  // disable output columnar when we have top-sort node query
3537  return false;
3538  }
3539  for (const auto& target_expr : ra_exe_unit.target_exprs) {
3540  // We don't currently support varlen columnar projections, so
3541  // return false if we find one
3542  if (target_expr->get_type_info().is_varlen()) {
3543  return false;
3544  }
3545  }
3546  if (auto top_project = dynamic_cast<const RelProject*>(body)) {
3547  if (top_project->isRowwiseOutputForced()) {
3548  return false;
3549  }
3550  }
3551  return true;
3552 }
std::vector< Analyzer::Expr * > target_exprs
const std::list< Analyzer::OrderEntry > order_entries
bool is_projection(const RelAlgExecutionUnit &ra_exe_unit)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool anonymous_namespace{RelAlgExecutor.cpp}::can_use_bump_allocator ( const RelAlgExecutionUnit ra_exe_unit,
const CompilationOptions co,
const ExecutionOptions eo 
)
inline

Definition at line 3655 of file RelAlgExecutor.cpp.

References CompilationOptions::device_type, g_enable_bump_allocator, GPU, SortInfo::order_entries, ExecutionOptions::output_columnar_hint, and RelAlgExecutionUnit::sort_info.

Referenced by RelAlgExecutor::executeWorkUnit().

3657  {
3659  !eo.output_columnar_hint && ra_exe_unit.sort_info.order_entries.empty();
3660 }
const std::list< Analyzer::OrderEntry > order_entries
ExecutorDeviceType device_type
bool g_enable_bump_allocator
Definition: Execute.cpp:120

+ Here is the caller graph for this function:

std::shared_ptr<Analyzer::Expr> anonymous_namespace{RelAlgExecutor.cpp}::cast_dict_to_none ( const std::shared_ptr< Analyzer::Expr > &  input)

Definition at line 1780 of file RelAlgExecutor.cpp.

References kENCODING_DICT, and kTEXT.

Referenced by translate_scalar_sources(), and translate_targets().

1781  {
1782  const auto& input_ti = input->get_type_info();
1783  if (input_ti.is_string() && input_ti.get_compression() == kENCODING_DICT) {
1784  return input->add_cast(SQLTypeInfo(kTEXT, input_ti.get_notnull()));
1785  }
1786  return input;
1787 }
Definition: sqltypes.h:69

+ Here is the caller graph for this function:

void anonymous_namespace{RelAlgExecutor.cpp}::check_none_encoded_string_cast_tuple_limit ( const std::vector< InputTableInfo > &  query_infos,
const RelAlgExecutionUnit ra_exe_unit 
)

Definition at line 456 of file RelAlgExecutor.cpp.

References gpu_enabled::accumulate(), g_enable_watchdog, g_watchdog_none_encoded_string_translation_limit, and get_text_cast_counts().

Referenced by RelAlgExecutor::executeWorkUnit().

458  {
459  if (!g_enable_watchdog) {
460  return;
461  }
462  auto const tuples_upper_bound =
463  std::accumulate(query_infos.cbegin(),
464  query_infos.cend(),
465  size_t(0),
466  [](auto max, auto const& query_info) {
467  return std::max(max, query_info.info.getNumTuples());
468  });
469  if (tuples_upper_bound <= g_watchdog_none_encoded_string_translation_limit) {
470  return;
471  }
472 
473  const auto& text_cast_counts = get_text_cast_counts(ra_exe_unit);
474  const bool has_text_casts =
475  text_cast_counts.text_decoding_casts + text_cast_counts.text_encoding_casts > 0UL;
476 
477  if (!has_text_casts) {
478  return;
479  }
480  std::ostringstream oss;
481  oss << "Query requires one or more casts between none-encoded and dictionary-encoded "
482  << "strings, and the estimated table size (" << tuples_upper_bound << " rows) "
483  << "exceeds the configured watchdog none-encoded string translation limit of "
485  throw std::runtime_error(oss.str());
486 }
TextEncodingCastCounts get_text_cast_counts(const RelAlgExecutionUnit &ra_exe_unit)
size_t g_watchdog_none_encoded_string_translation_limit
Definition: Execute.cpp:81
DEVICE auto accumulate(ARGS &&...args)
Definition: gpu_enabled.h:42
bool g_enable_watchdog

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void anonymous_namespace{RelAlgExecutor.cpp}::check_sort_node_source_constraint ( const RelSort sort)
inline

Definition at line 831 of file RelAlgExecutor.cpp.

References CHECK_EQ, RelAlgNode::getInput(), and RelAlgNode::inputCount().

Referenced by RelAlgExecutor::executeRelAlgQuerySingleStep(), and RelAlgExecutor::executeSort().

831  {
832  CHECK_EQ(size_t(1), sort->inputCount());
833  const auto source = sort->getInput(0);
834  if (dynamic_cast<const RelSort*>(source)) {
835  throw std::runtime_error("Sort node not supported as input to another sort");
836  }
837 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
const RelAlgNode * getInput(const size_t idx) const
Definition: RelAlgDag.h:892
const size_t inputCount() const
Definition: RelAlgDag.h:890

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void anonymous_namespace{RelAlgExecutor.cpp}::collect_used_input_desc ( std::vector< InputDescriptor > &  input_descs,
std::unordered_set< std::shared_ptr< const InputColDescriptor >> &  input_col_descs_unique,
const RelAlgNode ra_node,
const std::unordered_set< const RexInput * > &  source_used_inputs,
const std::unordered_map< const RelAlgNode *, int > &  input_to_nest_level 
)

Definition at line 1638 of file RelAlgExecutor.cpp.

References RelRexToStringConfig::defaults(), table_key_from_ra(), RelAlgNode::toString(), and VLOG.

Referenced by get_input_desc_impl().

1643  {
1644  VLOG(3) << "ra_node=" << ra_node->toString(RelRexToStringConfig::defaults())
1645  << " input_col_descs_unique.size()=" << input_col_descs_unique.size()
1646  << " source_used_inputs.size()=" << source_used_inputs.size();
1647  for (const auto used_input : source_used_inputs) {
1648  const auto input_ra = used_input->getSourceNode();
1649  const auto table_key = table_key_from_ra(input_ra);
1650  auto col_id = used_input->getIndex();
1651  auto it = input_to_nest_level.find(input_ra);
1652  if (it != input_to_nest_level.end()) {
1653  const int nest_level = it->second;
1654  if (auto rel_scan = dynamic_cast<const RelScan*>(input_ra)) {
1655  const auto& catalog = rel_scan->getCatalog();
1656  col_id = catalog.getColumnIdBySpi(table_key.table_id, col_id + 1);
1657  }
1658  input_col_descs_unique.insert(std::make_shared<const InputColDescriptor>(
1659  col_id, table_key.table_id, table_key.db_id, nest_level));
1660  } else if (!dynamic_cast<const RelLogicalUnion*>(ra_node)) {
1661  throw std::runtime_error("Bushy joins not supported");
1662  }
1663  }
1664 }
shared::TableKey table_key_from_ra(const RelAlgNode *ra_node)
virtual std::string toString(RelRexToStringConfig config) const =0
static RelRexToStringConfig defaults()
Definition: RelAlgDag.h:49
#define VLOG(n)
Definition: Logger.h:387

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool anonymous_namespace{RelAlgExecutor.cpp}::compute_output_buffer_size ( const RelAlgExecutionUnit ra_exe_unit)

Determines whether a query needs to compute the size of its output buffer. Returns true for projection queries with no LIMIT or a LIMIT that exceeds the high scan limit threshold (meaning it would be cheaper to compute the number of rows passing or use the bump allocator than allocate the current scan limit per GPU)

Definition at line 3565 of file RelAlgExecutor.cpp.

References RelAlgExecutionUnit::groupby_exprs, Executor::high_scan_limit, RelAlgExecutionUnit::scan_limit, and RelAlgExecutionUnit::target_exprs.

Referenced by RelAlgExecutor::executeWorkUnit().

3565  {
3566  for (const auto target_expr : ra_exe_unit.target_exprs) {
3567  if (dynamic_cast<const Analyzer::AggExpr*>(target_expr)) {
3568  return false;
3569  }
3570  }
3571  if (ra_exe_unit.groupby_exprs.size() == 1 && !ra_exe_unit.groupby_exprs.front() &&
3572  (!ra_exe_unit.scan_limit || ra_exe_unit.scan_limit > Executor::high_scan_limit)) {
3573  return true;
3574  }
3575  return false;
3576 }
std::vector< Analyzer::Expr * > target_exprs
const std::list< std::shared_ptr< Analyzer::Expr > > groupby_exprs
static const size_t high_scan_limit
Definition: Execute.h:603

+ Here is the caller graph for this function:

RelAlgExecutionUnit anonymous_namespace{RelAlgExecutor.cpp}::decide_approx_count_distinct_implementation ( const RelAlgExecutionUnit ra_exe_unit_in,
const std::vector< InputTableInfo > &  table_infos,
const Executor executor,
const ExecutorDeviceType  device_type_in,
std::vector< std::shared_ptr< Analyzer::Expr >> &  target_exprs_owned 
)

Definition at line 3583 of file RelAlgExecutor.cpp.

References Bitmap, CHECK, CHECK_GE, g_bigint_count, g_cluster, g_hll_precision_bits, get_agg_type(), get_count_distinct_sub_bitmap_count(), get_target_info(), getExpressionRange(), GPU, hll_size_for_rate(), Integer, kAPPROX_COUNT_DISTINCT, kCOUNT, kENCODING_DICT, kINT, and RelAlgExecutionUnit::target_exprs.

Referenced by RelAlgExecutor::executeWorkUnit(), and RelAlgExecutor::handleOutOfMemoryRetry().

3588  {
3589  RelAlgExecutionUnit ra_exe_unit = ra_exe_unit_in;
3590  for (size_t i = 0; i < ra_exe_unit.target_exprs.size(); ++i) {
3591  const auto target_expr = ra_exe_unit.target_exprs[i];
3592  const auto agg_info = get_target_info(target_expr, g_bigint_count);
3593  if (agg_info.agg_kind != kAPPROX_COUNT_DISTINCT) {
3594  continue;
3595  }
3596  CHECK(dynamic_cast<const Analyzer::AggExpr*>(target_expr));
3597  const auto arg = static_cast<Analyzer::AggExpr*>(target_expr)->get_own_arg();
3598  CHECK(arg);
3599  const auto& arg_ti = arg->get_type_info();
3600  // Avoid calling getExpressionRange for variable length types (string and array),
3601  // it'd trigger an assertion since that API expects to be called only for types
3602  // for which the notion of range is well-defined. A bit of a kludge, but the
3603  // logic to reject these types anyway is at lower levels in the stack and not
3604  // really worth pulling into a separate function for now.
3605  if (!(arg_ti.is_number() || arg_ti.is_boolean() || arg_ti.is_time() ||
3606  (arg_ti.is_string() && arg_ti.get_compression() == kENCODING_DICT))) {
3607  continue;
3608  }
3609  const auto arg_range = getExpressionRange(arg.get(), table_infos, executor);
3610  if (arg_range.getType() != ExpressionRangeType::Integer) {
3611  continue;
3612  }
3613  // When running distributed, the threshold for using the precise implementation
3614  // must be consistent across all leaves, otherwise we could have a mix of precise
3615  // and approximate bitmaps and we cannot aggregate them.
3616  const auto device_type = g_cluster ? ExecutorDeviceType::GPU : device_type_in;
3617  const auto bitmap_sz_bits = arg_range.getIntMax() - arg_range.getIntMin() + 1;
3618  const auto sub_bitmap_count =
3619  get_count_distinct_sub_bitmap_count(bitmap_sz_bits, ra_exe_unit, device_type);
3620  int64_t approx_bitmap_sz_bits{0};
3621  const auto error_rate_expr = static_cast<Analyzer::AggExpr*>(target_expr)->get_arg1();
3622  if (error_rate_expr) {
3623  CHECK(error_rate_expr->get_type_info().get_type() == kINT);
3624  auto const error_rate =
3625  dynamic_cast<Analyzer::Constant const*>(error_rate_expr.get());
3626  CHECK(error_rate);
3627  CHECK_GE(error_rate->get_constval().intval, 1);
3628  approx_bitmap_sz_bits = hll_size_for_rate(error_rate->get_constval().intval);
3629  } else {
3630  approx_bitmap_sz_bits = g_hll_precision_bits;
3631  }
3632  CountDistinctDescriptor approx_count_distinct_desc{CountDistinctImplType::Bitmap,
3633  arg_range.getIntMin(),
3634  approx_bitmap_sz_bits,
3635  true,
3636  device_type,
3637  sub_bitmap_count};
3638  CountDistinctDescriptor precise_count_distinct_desc{CountDistinctImplType::Bitmap,
3639  arg_range.getIntMin(),
3640  bitmap_sz_bits,
3641  false,
3642  device_type,
3643  sub_bitmap_count};
3644  if (approx_count_distinct_desc.bitmapPaddedSizeBytes() >=
3645  precise_count_distinct_desc.bitmapPaddedSizeBytes()) {
3646  auto precise_count_distinct = makeExpr<Analyzer::AggExpr>(
3647  get_agg_type(kCOUNT, arg.get()), kCOUNT, arg, true, nullptr);
3648  target_exprs_owned.push_back(precise_count_distinct);
3649  ra_exe_unit.target_exprs[i] = precise_count_distinct.get();
3650  }
3651  }
3652  return ra_exe_unit;
3653 }
std::vector< Analyzer::Expr * > target_exprs
int hll_size_for_rate(const int err_percent)
Definition: HyperLogLog.h:113
#define CHECK_GE(x, y)
Definition: Logger.h:306
SQLTypeInfo get_agg_type(const SQLAgg agg_kind, const Analyzer::Expr *arg_expr)
int g_hll_precision_bits
TargetInfo get_target_info(const Analyzer::Expr *target_expr, const bool bigint_count)
Definition: TargetInfo.h:88
size_t get_count_distinct_sub_bitmap_count(const size_t bitmap_sz_bits, const RelAlgExecutionUnit &ra_exe_unit, const ExecutorDeviceType device_type)
bool g_bigint_count
ExpressionRange getExpressionRange(const Analyzer::BinOper *expr, const std::vector< InputTableInfo > &query_infos, const Executor *, boost::optional< std::list< std::shared_ptr< Analyzer::Expr >>> simple_quals)
Definition: sqldefs.h:78
#define CHECK(condition)
Definition: Logger.h:291
bool g_cluster
Definition: sqltypes.h:62

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

template<class RA >
std::vector<size_t> anonymous_namespace{RelAlgExecutor.cpp}::do_table_reordering ( std::vector< InputDescriptor > &  input_descs,
std::list< std::shared_ptr< const InputColDescriptor >> &  input_col_descs,
const JoinQualsPerNestingLevel left_deep_join_quals,
std::unordered_map< const RelAlgNode *, int > &  input_to_nest_level,
const RA *  node,
const std::vector< InputTableInfo > &  query_infos,
const Executor executor 
)

Definition at line 4420 of file RelAlgExecutor.cpp.

References CHECK, g_cluster, get_input_desc(), get_input_nest_levels(), Catalog_Namespace::get_metadata_for_table(), get_node_input_permutation(), and table_is_replicated().

Referenced by RelAlgExecutor::createCompoundWorkUnit(), and RelAlgExecutor::createProjectWorkUnit().

4427  {
4428  if (g_cluster) {
4429  // Disable table reordering in distributed mode. The aggregator does not have enough
4430  // information to break ties
4431  return {};
4432  }
4433  for (const auto& table_info : query_infos) {
4434  if (table_info.table_key.table_id < 0) {
4435  continue;
4436  }
4437  const auto td = Catalog_Namespace::get_metadata_for_table(table_info.table_key);
4438  CHECK(td);
4439  if (table_is_replicated(td)) {
4440  return {};
4441  }
4442  }
4443  const auto input_permutation =
4444  get_node_input_permutation(left_deep_join_quals, query_infos, executor);
4445  input_to_nest_level = get_input_nest_levels(node, input_permutation);
4446  std::tie(input_descs, input_col_descs, std::ignore) =
4447  get_input_desc(node, input_to_nest_level, input_permutation);
4448  return input_permutation;
4449 }
std::unordered_map< const RelAlgNode *, int > get_input_nest_levels(const RelAlgNode *ra_node, const std::vector< size_t > &input_permutation)
std::tuple< std::vector< InputDescriptor >, std::list< std::shared_ptr< const InputColDescriptor > >, std::vector< std::shared_ptr< RexInput > > > get_input_desc(const RA *ra_node, const std::unordered_map< const RelAlgNode *, int > &input_to_nest_level, const std::vector< size_t > &input_permutation)
const TableDescriptor * get_metadata_for_table(const ::shared::TableKey &table_key, bool populate_fragmenter)
std::vector< node_t > get_node_input_permutation(const JoinQualsPerNestingLevel &left_deep_join_quals, const std::vector< InputTableInfo > &table_infos, const Executor *executor)
bool table_is_replicated(const TableDescriptor *td)
#define CHECK(condition)
Definition: Logger.h:291
bool g_cluster

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool anonymous_namespace{RelAlgExecutor.cpp}::exe_unit_has_quals ( const RelAlgExecutionUnit  ra_exe_unit)
inline

Definition at line 3578 of file RelAlgExecutor.cpp.

References RelAlgExecutionUnit::join_quals, RelAlgExecutionUnit::quals, and RelAlgExecutionUnit::simple_quals.

Referenced by RelAlgExecutor::executeWorkUnit().

3578  {
3579  return !(ra_exe_unit.quals.empty() && ra_exe_unit.join_quals.empty() &&
3580  ra_exe_unit.simple_quals.empty());
3581 }
const JoinQualsPerNestingLevel join_quals
std::list< std::shared_ptr< Analyzer::Expr > > quals
std::list< std::shared_ptr< Analyzer::Expr > > simple_quals

+ Here is the caller graph for this function:

bool anonymous_namespace{RelAlgExecutor.cpp}::first_oe_is_desc ( const std::list< Analyzer::OrderEntry > &  order_entries)

Definition at line 3254 of file RelAlgExecutor.cpp.

Referenced by RelAlgExecutor::createSortInputWorkUnit(), and RelAlgExecutor::executeSort().

3254  {
3255  return !order_entries.empty() && order_entries.front().is_desc;
3256 }

+ Here is the caller graph for this function:

std::unique_ptr<const RexOperator> anonymous_namespace{RelAlgExecutor.cpp}::get_bitwise_equals ( const RexScalar scalar)

Definition at line 4335 of file RelAlgExecutor.cpp.

References CHECK_EQ, kAND, kBW_EQ, kEQ, kISNULL, kOR, and RexVisitorBase< T >::visit().

Referenced by get_bitwise_equals_conjunction().

4335  {
4336  const auto condition = dynamic_cast<const RexOperator*>(scalar);
4337  if (!condition || condition->getOperator() != kOR || condition->size() != 2) {
4338  return nullptr;
4339  }
4340  const auto equi_join_condition =
4341  dynamic_cast<const RexOperator*>(condition->getOperand(0));
4342  if (!equi_join_condition || equi_join_condition->getOperator() != kEQ) {
4343  return nullptr;
4344  }
4345  const auto both_are_null_condition =
4346  dynamic_cast<const RexOperator*>(condition->getOperand(1));
4347  if (!both_are_null_condition || both_are_null_condition->getOperator() != kAND ||
4348  both_are_null_condition->size() != 2) {
4349  return nullptr;
4350  }
4351  const auto lhs_is_null =
4352  dynamic_cast<const RexOperator*>(both_are_null_condition->getOperand(0));
4353  const auto rhs_is_null =
4354  dynamic_cast<const RexOperator*>(both_are_null_condition->getOperand(1));
4355  if (!lhs_is_null || !rhs_is_null || lhs_is_null->getOperator() != kISNULL ||
4356  rhs_is_null->getOperator() != kISNULL) {
4357  return nullptr;
4358  }
4359  CHECK_EQ(size_t(1), lhs_is_null->size());
4360  CHECK_EQ(size_t(1), rhs_is_null->size());
4361  CHECK_EQ(size_t(2), equi_join_condition->size());
4362  const auto eq_lhs = dynamic_cast<const RexInput*>(equi_join_condition->getOperand(0));
4363  const auto eq_rhs = dynamic_cast<const RexInput*>(equi_join_condition->getOperand(1));
4364  const auto is_null_lhs = dynamic_cast<const RexInput*>(lhs_is_null->getOperand(0));
4365  const auto is_null_rhs = dynamic_cast<const RexInput*>(rhs_is_null->getOperand(0));
4366  if (!eq_lhs || !eq_rhs || !is_null_lhs || !is_null_rhs) {
4367  return nullptr;
4368  }
4369  std::vector<std::unique_ptr<const RexScalar>> eq_operands;
4370  if (*eq_lhs == *is_null_lhs && *eq_rhs == *is_null_rhs) {
4371  RexDeepCopyVisitor deep_copy_visitor;
4372  auto lhs_op_copy = deep_copy_visitor.visit(equi_join_condition->getOperand(0));
4373  auto rhs_op_copy = deep_copy_visitor.visit(equi_join_condition->getOperand(1));
4374  eq_operands.emplace_back(lhs_op_copy.release());
4375  eq_operands.emplace_back(rhs_op_copy.release());
4376  return boost::make_unique<const RexOperator>(
4377  kBW_EQ, eq_operands, equi_join_condition->getType());
4378  }
4379  return nullptr;
4380 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
Definition: sqldefs.h:37
Definition: sqldefs.h:29
virtual T visit(const RexScalar *rex_scalar) const
Definition: RexVisitor.h:27
Definition: sqldefs.h:36
Definition: sqldefs.h:30

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::unique_ptr<const RexOperator> anonymous_namespace{RelAlgExecutor.cpp}::get_bitwise_equals_conjunction ( const RexScalar scalar)

Definition at line 4382 of file RelAlgExecutor.cpp.

References CHECK_GE, get_bitwise_equals(), and kAND.

Referenced by RelAlgExecutor::makeJoinQuals().

4383  {
4384  const auto condition = dynamic_cast<const RexOperator*>(scalar);
4385  if (condition && condition->getOperator() == kAND) {
4386  CHECK_GE(condition->size(), size_t(2));
4387  auto acc = get_bitwise_equals(condition->getOperand(0));
4388  if (!acc) {
4389  return nullptr;
4390  }
4391  for (size_t i = 1; i < condition->size(); ++i) {
4392  std::vector<std::unique_ptr<const RexScalar>> and_operands;
4393  and_operands.emplace_back(std::move(acc));
4394  and_operands.emplace_back(get_bitwise_equals_conjunction(condition->getOperand(i)));
4395  acc =
4396  boost::make_unique<const RexOperator>(kAND, and_operands, condition->getType());
4397  }
4398  return acc;
4399  }
4400  return get_bitwise_equals(scalar);
4401 }
std::unique_ptr< const RexOperator > get_bitwise_equals_conjunction(const RexScalar *scalar)
#define CHECK_GE(x, y)
Definition: Logger.h:306
Definition: sqldefs.h:36
std::unique_ptr< const RexOperator > get_bitwise_equals(const RexScalar *scalar)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

const RelAlgNode* anonymous_namespace{RelAlgExecutor.cpp}::get_data_sink ( const RelAlgNode ra_node)

Definition at line 1433 of file RelAlgExecutor.cpp.

References CHECK_EQ, RelAlgNode::getInput(), RelAlgNode::inputCount(), and join().

Referenced by get_input_desc_impl(), get_input_nest_levels(), get_inputs_meta(), get_join_source_used_inputs(), get_join_type(), and get_used_inputs().

1433  {
1434  if (auto table_func = dynamic_cast<const RelTableFunction*>(ra_node)) {
1435  return table_func;
1436  }
1437  if (auto join = dynamic_cast<const RelJoin*>(ra_node)) {
1438  CHECK_EQ(size_t(2), join->inputCount());
1439  return join;
1440  }
1441  if (!dynamic_cast<const RelLogicalUnion*>(ra_node)) {
1442  CHECK_EQ(size_t(1), ra_node->inputCount());
1443  }
1444  auto only_src = ra_node->getInput(0);
1445  const bool is_join = dynamic_cast<const RelJoin*>(only_src) ||
1446  dynamic_cast<const RelLeftDeepInnerJoin*>(only_src);
1447  return is_join ? only_src : ra_node;
1448 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
std::string join(T const &container, std::string const &delim)
const RelAlgNode * getInput(const size_t idx) const
Definition: RelAlgDag.h:892
const size_t inputCount() const
Definition: RelAlgDag.h:890

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

template<class RA >
std::tuple<std::vector<InputDescriptor>, std::list<std::shared_ptr<const InputColDescriptor> >, std::vector<std::shared_ptr<RexInput> > > anonymous_namespace{RelAlgExecutor.cpp}::get_input_desc ( const RA *  ra_node,
const std::unordered_map< const RelAlgNode *, int > &  input_to_nest_level,
const std::vector< size_t > &  input_permutation 
)

Definition at line 1720 of file RelAlgExecutor.cpp.

References get_input_desc_impl(), get_used_inputs(), and VLOG.

Referenced by RelAlgExecutor::createAggregateWorkUnit(), RelAlgExecutor::createCompoundWorkUnit(), RelAlgExecutor::createFilterWorkUnit(), RelAlgExecutor::createProjectWorkUnit(), RelAlgExecutor::createTableFunctionWorkUnit(), RelAlgExecutor::createUnionWorkUnit(), and do_table_reordering().

1722  {
1723  std::unordered_set<const RexInput*> used_inputs;
1724  std::vector<std::shared_ptr<RexInput>> used_inputs_owned;
1725  std::tie(used_inputs, used_inputs_owned) = get_used_inputs(ra_node);
1726  VLOG(3) << "used_inputs.size() = " << used_inputs.size();
1727  auto input_desc_pair =
1728  get_input_desc_impl(ra_node, used_inputs, input_to_nest_level, input_permutation);
1729  return std::make_tuple(
1730  input_desc_pair.first, input_desc_pair.second, used_inputs_owned);
1731 }
std::pair< std::unordered_set< const RexInput * >, std::vector< std::shared_ptr< RexInput > > > get_used_inputs(const RelCompound *compound)
std::pair< std::vector< InputDescriptor >, std::list< std::shared_ptr< const InputColDescriptor > > > get_input_desc_impl(const RA *ra_node, const std::unordered_set< const RexInput * > &used_inputs, const std::unordered_map< const RelAlgNode *, int > &input_to_nest_level, const std::vector< size_t > &input_permutation)
#define VLOG(n)
Definition: Logger.h:387

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

template<class RA >
std::pair<std::vector<InputDescriptor>, std::list<std::shared_ptr<const InputColDescriptor> > > anonymous_namespace{RelAlgExecutor.cpp}::get_input_desc_impl ( const RA *  ra_node,
const std::unordered_set< const RexInput * > &  used_inputs,
const std::unordered_map< const RelAlgNode *, int > &  input_to_nest_level,
const std::vector< size_t > &  input_permutation 
)

Definition at line 1669 of file RelAlgExecutor.cpp.

References collect_used_input_desc(), get_data_sink(), get_join_source_used_inputs(), gpu_enabled::sort(), and table_key_from_ra().

Referenced by get_input_desc().

1672  {
1673  std::vector<InputDescriptor> input_descs;
1674  const auto data_sink_node = get_data_sink(ra_node);
1675  for (size_t input_idx = 0; input_idx < data_sink_node->inputCount(); ++input_idx) {
1676  const auto input_node_idx =
1677  input_permutation.empty() ? input_idx : input_permutation[input_idx];
1678  auto input_ra = data_sink_node->getInput(input_node_idx);
1679  const auto table_key = table_key_from_ra(input_ra);
1680  input_descs.emplace_back(table_key.db_id, table_key.table_id, input_idx);
1681  }
1682  std::unordered_set<std::shared_ptr<const InputColDescriptor>> input_col_descs_unique;
1683  collect_used_input_desc(input_descs,
1684  input_col_descs_unique, // modified
1685  ra_node,
1686  used_inputs,
1687  input_to_nest_level);
1688  std::unordered_set<const RexInput*> join_source_used_inputs;
1689  std::vector<std::shared_ptr<RexInput>> join_source_used_inputs_owned;
1690  std::tie(join_source_used_inputs, join_source_used_inputs_owned) =
1691  get_join_source_used_inputs(ra_node);
1692  collect_used_input_desc(input_descs,
1693  input_col_descs_unique, // modified
1694  ra_node,
1695  join_source_used_inputs,
1696  input_to_nest_level);
1697  std::vector<std::shared_ptr<const InputColDescriptor>> input_col_descs(
1698  input_col_descs_unique.begin(), input_col_descs_unique.end());
1699 
1700  std::sort(input_col_descs.begin(),
1701  input_col_descs.end(),
1702  [](std::shared_ptr<const InputColDescriptor> const& lhs,
1703  std::shared_ptr<const InputColDescriptor> const& rhs) {
1704  return std::make_tuple(lhs->getScanDesc().getNestLevel(),
1705  lhs->getColId(),
1706  lhs->getScanDesc().getTableKey()) <
1707  std::make_tuple(rhs->getScanDesc().getNestLevel(),
1708  rhs->getColId(),
1709  rhs->getScanDesc().getTableKey());
1710  });
1711  return {input_descs,
1712  std::list<std::shared_ptr<const InputColDescriptor>>(input_col_descs.begin(),
1713  input_col_descs.end())};
1714 }
shared::TableKey table_key_from_ra(const RelAlgNode *ra_node)
std::pair< std::unordered_set< const RexInput * >, std::vector< std::shared_ptr< RexInput > > > get_join_source_used_inputs(const RelAlgNode *ra_node)
DEVICE void sort(ARGS &&...args)
Definition: gpu_enabled.h:105
void collect_used_input_desc(std::vector< InputDescriptor > &input_descs, std::unordered_set< std::shared_ptr< const InputColDescriptor >> &input_col_descs_unique, const RelAlgNode *ra_node, const std::unordered_set< const RexInput * > &source_used_inputs, const std::unordered_map< const RelAlgNode *, int > &input_to_nest_level)
const RelAlgNode * get_data_sink(const RelAlgNode *ra_node)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::unordered_map<const RelAlgNode*, int> anonymous_namespace{RelAlgExecutor.cpp}::get_input_nest_levels ( const RelAlgNode ra_node,
const std::vector< size_t > &  input_permutation 
)

Definition at line 1571 of file RelAlgExecutor.cpp.

References CHECK, logger::DEBUG1, RelRexToStringConfig::defaults(), get_data_sink(), and LOG_IF.

Referenced by RelAlgExecutor::createAggregateWorkUnit(), RelAlgExecutor::createCompoundWorkUnit(), RelAlgExecutor::createFilterWorkUnit(), RelAlgExecutor::createProjectWorkUnit(), RelAlgExecutor::createTableFunctionWorkUnit(), RelAlgExecutor::createUnionWorkUnit(), do_table_reordering(), and RelAlgExecutor::getRelAlgTranslator().

1573  {
1574  const auto data_sink_node = get_data_sink(ra_node);
1575  std::unordered_map<const RelAlgNode*, int> input_to_nest_level;
1576  for (size_t input_idx = 0; input_idx < data_sink_node->inputCount(); ++input_idx) {
1577  const auto input_node_idx =
1578  input_permutation.empty() ? input_idx : input_permutation[input_idx];
1579  const auto input_ra = data_sink_node->getInput(input_node_idx);
1580  // Having a non-zero mapped value (input_idx) results in the query being interpretted
1581  // as a JOIN within CodeGenerator::codegenColVar() due to rte_idx being set to the
1582  // mapped value (input_idx) which originates here. This would be incorrect for UNION.
1583  size_t const idx = dynamic_cast<const RelLogicalUnion*>(ra_node) ? 0 : input_idx;
1584  const auto it_ok = input_to_nest_level.emplace(input_ra, idx);
1585  CHECK(it_ok.second);
1586  LOG_IF(DEBUG1, !input_permutation.empty())
1587  << "Assigned input " << input_ra->toString(RelRexToStringConfig::defaults())
1588  << " to nest level " << input_idx;
1589  }
1590  return input_to_nest_level;
1591 }
#define LOG_IF(severity, condition)
Definition: Logger.h:383
static RelRexToStringConfig defaults()
Definition: RelAlgDag.h:49
#define CHECK(condition)
Definition: Logger.h:291
const RelAlgNode * get_data_sink(const RelAlgNode *ra_node)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::pair<std::vector<TargetMetaInfo>, std::vector<std::shared_ptr<Analyzer::Expr> > > anonymous_namespace{RelAlgExecutor.cpp}::get_inputs_meta ( const RelFilter filter,
const RelAlgTranslator translator,
const std::vector< std::shared_ptr< RexInput >> &  inputs_owned,
const std::unordered_map< const RelAlgNode *, int > &  input_to_nest_level 
)

Definition at line 5267 of file RelAlgExecutor.cpp.

References CHECK, get_data_sink(), get_raw_pointers(), get_targets_meta(), synthesize_inputs(), and RelAlgTranslator::translate().

Referenced by RelAlgExecutor::createFilterWorkUnit().

5270  {
5271  std::vector<TargetMetaInfo> in_metainfo;
5272  std::vector<std::shared_ptr<Analyzer::Expr>> exprs_owned;
5273  const auto data_sink_node = get_data_sink(filter);
5274  auto input_it = inputs_owned.begin();
5275  for (size_t nest_level = 0; nest_level < data_sink_node->inputCount(); ++nest_level) {
5276  const auto source = data_sink_node->getInput(nest_level);
5277  const auto scan_source = dynamic_cast<const RelScan*>(source);
5278  if (scan_source) {
5279  CHECK(source->getOutputMetainfo().empty());
5280  std::vector<std::shared_ptr<Analyzer::Expr>> scalar_sources_owned;
5281  for (size_t i = 0; i < scan_source->size(); ++i, ++input_it) {
5282  scalar_sources_owned.push_back(translator.translate(input_it->get()));
5283  }
5284  const auto source_metadata =
5285  get_targets_meta(scan_source, get_raw_pointers(scalar_sources_owned));
5286  in_metainfo.insert(
5287  in_metainfo.end(), source_metadata.begin(), source_metadata.end());
5288  exprs_owned.insert(
5289  exprs_owned.end(), scalar_sources_owned.begin(), scalar_sources_owned.end());
5290  } else {
5291  const auto& source_metadata = source->getOutputMetainfo();
5292  input_it += source_metadata.size();
5293  in_metainfo.insert(
5294  in_metainfo.end(), source_metadata.begin(), source_metadata.end());
5295  const auto scalar_sources_owned = synthesize_inputs(
5296  data_sink_node, nest_level, source_metadata, input_to_nest_level);
5297  exprs_owned.insert(
5298  exprs_owned.end(), scalar_sources_owned.begin(), scalar_sources_owned.end());
5299  }
5300  }
5301  return std::make_pair(in_metainfo, exprs_owned);
5302 }
std::vector< Analyzer::Expr * > get_raw_pointers(std::vector< std::shared_ptr< Analyzer::Expr >> const &input)
std::vector< std::shared_ptr< Analyzer::Expr > > synthesize_inputs(const RelAlgNode *ra_node, const size_t nest_level, const std::vector< TargetMetaInfo > &in_metainfo, const std::unordered_map< const RelAlgNode *, int > &input_to_nest_level)
std::shared_ptr< Analyzer::Expr > translate(const RexScalar *rex) const
std::vector< TargetMetaInfo > get_targets_meta(const RA *ra_node, const std::vector< Analyzer::Expr * > &target_exprs)
#define CHECK(condition)
Definition: Logger.h:291
const RelAlgNode * get_data_sink(const RelAlgNode *ra_node)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::pair<std::unordered_set<const RexInput*>, std::vector<std::shared_ptr<RexInput> > > anonymous_namespace{RelAlgExecutor.cpp}::get_join_source_used_inputs ( const RelAlgNode ra_node)

Definition at line 1594 of file RelAlgExecutor.cpp.

References CHECK_EQ, CHECK_GE, CHECK_GT, RelRexToStringConfig::defaults(), get_data_sink(), anonymous_namespace{RelAlgExecutor.cpp}::RexUsedInputsVisitor::get_inputs_owned(), RelAlgNode::inputCount(), join(), run_benchmark_import::result, and RelAlgNode::toString().

Referenced by get_input_desc_impl().

1594  {
1595  const auto data_sink_node = get_data_sink(ra_node);
1596  if (auto join = dynamic_cast<const RelJoin*>(data_sink_node)) {
1597  CHECK_EQ(join->inputCount(), 2u);
1598  const auto condition = join->getCondition();
1599  RexUsedInputsVisitor visitor;
1600  auto condition_inputs = visitor.visit(condition);
1601  std::vector<std::shared_ptr<RexInput>> condition_inputs_owned(
1602  visitor.get_inputs_owned());
1603  return std::make_pair(condition_inputs, condition_inputs_owned);
1604  }
1605 
1606  if (auto left_deep_join = dynamic_cast<const RelLeftDeepInnerJoin*>(data_sink_node)) {
1607  CHECK_GE(left_deep_join->inputCount(), 2u);
1608  const auto condition = left_deep_join->getInnerCondition();
1609  RexUsedInputsVisitor visitor;
1610  auto result = visitor.visit(condition);
1611  for (size_t nesting_level = 1; nesting_level <= left_deep_join->inputCount() - 1;
1612  ++nesting_level) {
1613  const auto outer_condition = left_deep_join->getOuterCondition(nesting_level);
1614  if (outer_condition) {
1615  const auto outer_result = visitor.visit(outer_condition);
1616  result.insert(outer_result.begin(), outer_result.end());
1617  }
1618  }
1619  std::vector<std::shared_ptr<RexInput>> used_inputs_owned(visitor.get_inputs_owned());
1620  return std::make_pair(result, used_inputs_owned);
1621  }
1622 
1623  if (dynamic_cast<const RelLogicalUnion*>(ra_node)) {
1624  CHECK_GT(ra_node->inputCount(), 1u)
1626  } else if (dynamic_cast<const RelTableFunction*>(ra_node)) {
1627  // no-op
1628  CHECK_GE(ra_node->inputCount(), 0u)
1630  } else {
1631  CHECK_EQ(ra_node->inputCount(), 1u)
1633  }
1634  return std::make_pair(std::unordered_set<const RexInput*>{},
1635  std::vector<std::shared_ptr<RexInput>>{});
1636 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
std::string join(T const &container, std::string const &delim)
#define CHECK_GE(x, y)
Definition: Logger.h:306
#define CHECK_GT(x, y)
Definition: Logger.h:305
virtual std::string toString(RelRexToStringConfig config) const =0
static RelRexToStringConfig defaults()
Definition: RelAlgDag.h:49
const size_t inputCount() const
Definition: RelAlgDag.h:890
const RelAlgNode * get_data_sink(const RelAlgNode *ra_node)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

JoinType anonymous_namespace{RelAlgExecutor.cpp}::get_join_type ( const RelAlgNode ra)

Definition at line 4323 of file RelAlgExecutor.cpp.

References get_data_sink(), INNER, INVALID, and join().

Referenced by RelAlgExecutor::createAggregateWorkUnit(), RelAlgExecutor::createCompoundWorkUnit(), RelAlgExecutor::createFilterWorkUnit(), RelAlgExecutor::createProjectWorkUnit(), and RelAlgExecutor::getRelAlgTranslator().

4323  {
4324  auto sink = get_data_sink(ra);
4325  if (auto join = dynamic_cast<const RelJoin*>(sink)) {
4326  return join->getJoinType();
4327  }
4328  if (dynamic_cast<const RelLeftDeepInnerJoin*>(sink)) {
4329  return JoinType::INNER;
4330  }
4331 
4332  return JoinType::INVALID;
4333 }
std::string join(T const &container, std::string const &delim)
const RelAlgNode * get_data_sink(const RelAlgNode *ra_node)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::vector<size_t> anonymous_namespace{RelAlgExecutor.cpp}::get_left_deep_join_input_sizes ( const RelLeftDeepInnerJoin left_deep_join)

Definition at line 4451 of file RelAlgExecutor.cpp.

References get_node_output(), RelAlgNode::getInput(), and RelAlgNode::inputCount().

Referenced by RelAlgExecutor::createCompoundWorkUnit(), and RelAlgExecutor::createProjectWorkUnit().

4452  {
4453  std::vector<size_t> input_sizes;
4454  for (size_t i = 0; i < left_deep_join->inputCount(); ++i) {
4455  const auto inputs = get_node_output(left_deep_join->getInput(i));
4456  input_sizes.push_back(inputs.size());
4457  }
4458  return input_sizes;
4459 }
const RelAlgNode * getInput(const size_t idx) const
Definition: RelAlgDag.h:892
const size_t inputCount() const
Definition: RelAlgDag.h:890
RANodeOutput get_node_output(const RelAlgNode *ra_node)
Definition: RelAlgDag.cpp:370

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

SQLTypeInfo anonymous_namespace{RelAlgExecutor.cpp}::get_logical_type_for_expr ( const Analyzer::Expr expr)
inline

Definition at line 2005 of file RelAlgExecutor.cpp.

References get_logical_type_info(), get_nullable_logical_type_info(), Analyzer::Expr::get_type_info(), is_agg(), is_count_distinct(), and kBIGINT.

Referenced by get_targets_meta().

2005  {
2006  if (is_count_distinct(&expr)) {
2007  return SQLTypeInfo(kBIGINT, false);
2008  } else if (is_agg(&expr)) {
2010  }
2011  return get_logical_type_info(expr.get_type_info());
2012 }
bool is_agg(const Analyzer::Expr *expr)
SQLTypeInfo get_nullable_logical_type_info(const SQLTypeInfo &type_info)
Definition: sqltypes.h:1253
SQLTypeInfo get_logical_type_info(const SQLTypeInfo &type_info)
Definition: sqltypes.h:1235
bool is_count_distinct(const Analyzer::Expr *expr)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::list<Analyzer::OrderEntry> anonymous_namespace{RelAlgExecutor.cpp}::get_order_entries ( const RelSort sort)

Definition at line 224 of file RelAlgExecutor.cpp.

References RelSort::collationCount(), Descending, First, RelSort::getCollation(), and run_benchmark_import::result.

Referenced by RelAlgExecutor::executeRelAlgQuerySingleStep(), and RelAlgExecutor::executeSort().

224  {
225  std::list<Analyzer::OrderEntry> result;
226  for (size_t i = 0; i < sort->collationCount(); ++i) {
227  const auto sort_field = sort->getCollation(i);
228  result.emplace_back(sort_field.getField() + 1,
229  sort_field.getSortDir() == SortDirection::Descending,
230  sort_field.getNullsPosition() == NullSortedPosition::First);
231  }
232  return result;
233 }
SortField getCollation(const size_t i) const
Definition: RelAlgDag.h:1954
size_t collationCount() const
Definition: RelAlgDag.h:1952

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::unordered_set<PhysicalInput> anonymous_namespace{RelAlgExecutor.cpp}::get_physical_inputs_with_spi_col_id ( const RelAlgNode ra)

Definition at line 74 of file RelAlgExecutor.cpp.

References CHECK, get_physical_inputs(), Catalog_Namespace::SysCatalog::getCatalog(), Catalog_Namespace::SysCatalog::instance(), and PhysicalInput::table_id.

Referenced by RelAlgExecutor::computeColRangesCache(), RelAlgExecutor::computeStringDictionaryGenerations(), and RelAlgExecutor::setupCaching().

75  {
76  const auto phys_inputs = get_physical_inputs(ra);
77  std::unordered_set<PhysicalInput> phys_inputs2;
78  for (auto& phi : phys_inputs) {
79  const auto catalog = Catalog_Namespace::SysCatalog::instance().getCatalog(phi.db_id);
80  CHECK(catalog);
81  phys_inputs2.insert(PhysicalInput{
82  catalog->getColumnIdBySpi(phi.table_id, phi.col_id), phi.table_id, phi.db_id});
83  }
84  return phys_inputs2;
85 }
static SysCatalog & instance()
Definition: SysCatalog.h:343
std::shared_ptr< Catalog > getCatalog(const std::string &dbName)
#define CHECK(condition)
Definition: Logger.h:291
std::unordered_set< PhysicalInput > get_physical_inputs(const RelAlgNode *ra)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::vector<Analyzer::Expr*> anonymous_namespace{RelAlgExecutor.cpp}::get_raw_pointers ( std::vector< std::shared_ptr< Analyzer::Expr >> const &  input)

Definition at line 4782 of file RelAlgExecutor.cpp.

References shared::transform().

Referenced by RelAlgExecutor::createFilterWorkUnit(), RelAlgExecutor::createProjectWorkUnit(), RelAlgExecutor::createTableFunctionWorkUnit(), RelAlgExecutor::createUnionWorkUnit(), and get_inputs_meta().

4783  {
4784  std::vector<Analyzer::Expr*> output(input.size());
4785  auto const raw_ptr = [](auto& shared_ptr) { return shared_ptr.get(); };
4786  std::transform(input.cbegin(), input.cend(), output.begin(), raw_ptr);
4787  return output;
4788 }
OUTPUT transform(INPUT const &input, FUNC const &func)
Definition: misc.h:320

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

size_t anonymous_namespace{RelAlgExecutor.cpp}::get_scalar_sources_size ( const RelCompound compound)

Definition at line 1733 of file RelAlgExecutor.cpp.

References RelCompound::getScalarSourcesSize().

Referenced by translate_scalar_sources(), and translate_scalar_sources_for_update().

1733  {
1734  return compound->getScalarSourcesSize();
1735 }
const size_t getScalarSourcesSize() const
Definition: RelAlgDag.h:1860

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

size_t anonymous_namespace{RelAlgExecutor.cpp}::get_scalar_sources_size ( const RelProject project)

Definition at line 1737 of file RelAlgExecutor.cpp.

References RelProject::size().

1737  {
1738  return project->size();
1739 }
size_t size() const override
Definition: RelAlgDag.h:1172

+ Here is the call graph for this function:

size_t anonymous_namespace{RelAlgExecutor.cpp}::get_scalar_sources_size ( const RelTableFunction table_func)

Definition at line 1741 of file RelAlgExecutor.cpp.

References RelTableFunction::getTableFuncInputsSize().

1741  {
1742  return table_func->getTableFuncInputsSize();
1743 }
size_t getTableFuncInputsSize() const
Definition: RelAlgDag.h:2284

+ Here is the call graph for this function:

size_t anonymous_namespace{RelAlgExecutor.cpp}::get_scan_limit ( const RelAlgNode ra,
const size_t  limit 
)

Definition at line 3245 of file RelAlgExecutor.cpp.

Referenced by RelAlgExecutor::createSortInputWorkUnit().

3245  {
3246  const auto aggregate = dynamic_cast<const RelAggregate*>(ra);
3247  if (aggregate) {
3248  return 0;
3249  }
3250  const auto compound = dynamic_cast<const RelCompound*>(ra);
3251  return (compound && compound->isAggregate()) ? 0 : limit;
3252 }

+ Here is the caller graph for this function:

template<class RA >
std::vector<TargetMetaInfo> anonymous_namespace{RelAlgExecutor.cpp}::get_targets_meta ( const RA *  ra_node,
const std::vector< Analyzer::Expr * > &  target_exprs 
)

Definition at line 2015 of file RelAlgExecutor.cpp.

References CHECK, CHECK_EQ, and get_logical_type_for_expr().

Referenced by RelAlgExecutor::createAggregateWorkUnit(), RelAlgExecutor::createCompoundWorkUnit(), RelAlgExecutor::createProjectWorkUnit(), RelAlgExecutor::createTableFunctionWorkUnit(), RelAlgExecutor::createUnionWorkUnit(), get_inputs_meta(), and get_targets_meta().

2017  {
2018  std::vector<TargetMetaInfo> targets_meta;
2019  CHECK_EQ(ra_node->size(), target_exprs.size());
2020  for (size_t i = 0; i < ra_node->size(); ++i) {
2021  CHECK(target_exprs[i]);
2022  // TODO(alex): remove the count distinct type fixup.
2023  targets_meta.emplace_back(ra_node->getFieldName(i),
2024  get_logical_type_for_expr(*target_exprs[i]),
2025  target_exprs[i]->get_type_info());
2026  }
2027  return targets_meta;
2028 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
SQLTypeInfo get_logical_type_for_expr(const Analyzer::Expr &expr)
#define CHECK(condition)
Definition: Logger.h:291

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

template<>
std::vector<TargetMetaInfo> anonymous_namespace{RelAlgExecutor.cpp}::get_targets_meta ( const RelFilter filter,
const std::vector< Analyzer::Expr * > &  target_exprs 
)

Definition at line 2031 of file RelAlgExecutor.cpp.

References RelRexToStringConfig::defaults(), get_targets_meta(), RelAlgNode::getInput(), RelAlgNode::toString(), and UNREACHABLE.

2033  {
2034  RelAlgNode const* input0 = filter->getInput(0);
2035  if (auto const* input = dynamic_cast<RelCompound const*>(input0)) {
2036  return get_targets_meta(input, target_exprs);
2037  } else if (auto const* input = dynamic_cast<RelProject const*>(input0)) {
2038  return get_targets_meta(input, target_exprs);
2039  } else if (auto const* input = dynamic_cast<RelLogicalUnion const*>(input0)) {
2040  return get_targets_meta(input, target_exprs);
2041  } else if (auto const* input = dynamic_cast<RelAggregate const*>(input0)) {
2042  return get_targets_meta(input, target_exprs);
2043  } else if (auto const* input = dynamic_cast<RelScan const*>(input0)) {
2044  return get_targets_meta(input, target_exprs);
2045  } else if (auto const* input = dynamic_cast<RelLogicalValues const*>(input0)) {
2046  return get_targets_meta(input, target_exprs);
2047  }
2048  UNREACHABLE() << "Unhandled node type: "
2050  return {};
2051 }
#define UNREACHABLE()
Definition: Logger.h:337
virtual std::string toString(RelRexToStringConfig config) const =0
const RelAlgNode * getInput(const size_t idx) const
Definition: RelAlgDag.h:892
std::vector< TargetMetaInfo > get_targets_meta(const RA *ra_node, const std::vector< Analyzer::Expr * > &target_exprs)
static RelRexToStringConfig defaults()
Definition: RelAlgDag.h:49

+ Here is the call graph for this function:

TextEncodingCastCounts anonymous_namespace{RelAlgExecutor.cpp}::get_text_cast_counts ( const RelAlgExecutionUnit ra_exe_unit)

Definition at line 415 of file RelAlgExecutor.cpp.

References RelAlgExecutionUnit::groupby_exprs, RelAlgExecutionUnit::join_quals, RelAlgExecutionUnit::quals, RelAlgExecutionUnit::simple_quals, RelAlgExecutionUnit::target_exprs, anonymous_namespace{RelAlgExecutor.cpp}::TextEncodingCastCounts::text_decoding_casts, anonymous_namespace{RelAlgExecutor.cpp}::TextEncodingCastCounts::text_encoding_casts, and ScalarExprVisitor< T >::visit().

Referenced by check_none_encoded_string_cast_tuple_limit().

415  {
416  TextEncodingCastCounts cast_counts;
417 
418  auto check_node_for_text_casts = [&cast_counts](
419  const Analyzer::Expr* expr,
420  const bool disregard_casts_to_none_encoding) {
421  if (!expr) {
422  return;
423  }
424  TextEncodingCastCountVisitor visitor(disregard_casts_to_none_encoding);
425  const auto this_node_cast_counts = visitor.visit(expr);
426  cast_counts.text_encoding_casts += this_node_cast_counts.text_encoding_casts;
427  cast_counts.text_decoding_casts += this_node_cast_counts.text_decoding_casts;
428  };
429 
430  for (const auto& qual : ra_exe_unit.quals) {
431  check_node_for_text_casts(qual.get(), false);
432  }
433  for (const auto& simple_qual : ra_exe_unit.simple_quals) {
434  check_node_for_text_casts(simple_qual.get(), false);
435  }
436  for (const auto& groupby_expr : ra_exe_unit.groupby_exprs) {
437  check_node_for_text_casts(groupby_expr.get(), false);
438  }
439  for (const auto& target_expr : ra_exe_unit.target_exprs) {
440  check_node_for_text_casts(target_expr, false);
441  }
442  for (const auto& join_condition : ra_exe_unit.join_quals) {
443  for (const auto& join_qual : join_condition.quals) {
444  // We currently need to not count casts to none-encoded strings for join quals,
445  // as analyzer will generate these but our join framework disregards them.
446  // Some investigation was done on having analyzer issue the correct inter-string
447  // dictionary casts, but this actually causes them to get executed and so the same
448  // work gets done twice.
449  check_node_for_text_casts(join_qual.get(),
450  true /* disregard_casts_to_none_encoding */);
451  }
452  }
453  return cast_counts;
454 }
std::vector< Analyzer::Expr * > target_exprs
const std::list< std::shared_ptr< Analyzer::Expr > > groupby_exprs
const JoinQualsPerNestingLevel join_quals
std::list< std::shared_ptr< Analyzer::Expr > > quals
std::list< std::shared_ptr< Analyzer::Expr > > simple_quals

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::pair<std::unordered_set<const RexInput*>, std::vector<std::shared_ptr<RexInput> > > anonymous_namespace{RelAlgExecutor.cpp}::get_used_inputs ( const RelCompound compound)

Definition at line 1451 of file RelAlgExecutor.cpp.

References anonymous_namespace{RelAlgExecutor.cpp}::RexUsedInputsVisitor::get_inputs_owned(), RelCompound::getFilterExpr(), RelCompound::getScalarSource(), and RelCompound::getScalarSourcesSize().

Referenced by get_input_desc().

1451  {
1452  RexUsedInputsVisitor visitor;
1453  const auto filter_expr = compound->getFilterExpr();
1454  std::unordered_set<const RexInput*> used_inputs =
1455  filter_expr ? visitor.visit(filter_expr) : std::unordered_set<const RexInput*>{};
1456  const auto sources_size = compound->getScalarSourcesSize();
1457  for (size_t i = 0; i < sources_size; ++i) {
1458  const auto source_inputs = visitor.visit(compound->getScalarSource(i));
1459  used_inputs.insert(source_inputs.begin(), source_inputs.end());
1460  }
1461  std::vector<std::shared_ptr<RexInput>> used_inputs_owned(visitor.get_inputs_owned());
1462  return std::make_pair(used_inputs, used_inputs_owned);
1463 }
const RexScalar * getFilterExpr() const
Definition: RelAlgDag.h:1846
const size_t getScalarSourcesSize() const
Definition: RelAlgDag.h:1860
const RexScalar * getScalarSource(const size_t i) const
Definition: RelAlgDag.h:1862

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::pair<std::unordered_set<const RexInput*>, std::vector<std::shared_ptr<RexInput> > > anonymous_namespace{RelAlgExecutor.cpp}::get_used_inputs ( const RelAggregate aggregate)

Definition at line 1466 of file RelAlgExecutor.cpp.

References CHECK_EQ, CHECK_GE, RelAggregate::getAggExprs(), RelAggregate::getGroupByCount(), RelAlgNode::getInput(), RelAlgNode::getOutputMetainfo(), and RelAlgNode::inputCount().

1466  {
1467  CHECK_EQ(size_t(1), aggregate->inputCount());
1468  std::unordered_set<const RexInput*> used_inputs;
1469  std::vector<std::shared_ptr<RexInput>> used_inputs_owned;
1470  const auto source = aggregate->getInput(0);
1471  const auto& in_metainfo = source->getOutputMetainfo();
1472  const auto group_count = aggregate->getGroupByCount();
1473  CHECK_GE(in_metainfo.size(), group_count);
1474  for (size_t i = 0; i < group_count; ++i) {
1475  auto synthesized_used_input = new RexInput(source, i);
1476  used_inputs_owned.emplace_back(synthesized_used_input);
1477  used_inputs.insert(synthesized_used_input);
1478  }
1479  for (const auto& agg_expr : aggregate->getAggExprs()) {
1480  for (size_t i = 0; i < agg_expr->size(); ++i) {
1481  const auto operand_idx = agg_expr->getOperand(i);
1482  CHECK_GE(in_metainfo.size(), static_cast<size_t>(operand_idx));
1483  auto synthesized_used_input = new RexInput(source, operand_idx);
1484  used_inputs_owned.emplace_back(synthesized_used_input);
1485  used_inputs.insert(synthesized_used_input);
1486  }
1487  }
1488  return std::make_pair(used_inputs, used_inputs_owned);
1489 }
const size_t getGroupByCount() const
Definition: RelAlgDag.h:1342
#define CHECK_EQ(x, y)
Definition: Logger.h:301
#define CHECK_GE(x, y)
Definition: Logger.h:306
const RelAlgNode * getInput(const size_t idx) const
Definition: RelAlgDag.h:892
const std::vector< std::unique_ptr< const RexAgg > > & getAggExprs() const
Definition: RelAlgDag.h:1365
const size_t inputCount() const
Definition: RelAlgDag.h:890
const std::vector< TargetMetaInfo > & getOutputMetainfo() const
Definition: RelAlgDag.h:876

+ Here is the call graph for this function:

std::pair<std::unordered_set<const RexInput*>, std::vector<std::shared_ptr<RexInput> > > anonymous_namespace{RelAlgExecutor.cpp}::get_used_inputs ( const RelProject project)

Definition at line 1492 of file RelAlgExecutor.cpp.

References anonymous_namespace{RelAlgExecutor.cpp}::RexUsedInputsVisitor::get_inputs_owned(), RelProject::getProjectAt(), and RelProject::size().

1492  {
1493  RexUsedInputsVisitor visitor;
1494  std::unordered_set<const RexInput*> used_inputs;
1495  for (size_t i = 0; i < project->size(); ++i) {
1496  const auto proj_inputs = visitor.visit(project->getProjectAt(i));
1497  used_inputs.insert(proj_inputs.begin(), proj_inputs.end());
1498  }
1499  std::vector<std::shared_ptr<RexInput>> used_inputs_owned(visitor.get_inputs_owned());
1500  return std::make_pair(used_inputs, used_inputs_owned);
1501 }
size_t size() const override
Definition: RelAlgDag.h:1172
const RexScalar * getProjectAt(const size_t idx) const
Definition: RelAlgDag.h:1204

+ Here is the call graph for this function:

std::pair<std::unordered_set<const RexInput*>, std::vector<std::shared_ptr<RexInput> > > anonymous_namespace{RelAlgExecutor.cpp}::get_used_inputs ( const RelTableFunction table_func)

Definition at line 1504 of file RelAlgExecutor.cpp.

References anonymous_namespace{RelAlgExecutor.cpp}::RexUsedInputsVisitor::get_inputs_owned(), RelTableFunction::getTableFuncInputAt(), and RelTableFunction::getTableFuncInputsSize().

1504  {
1505  RexUsedInputsVisitor visitor;
1506  std::unordered_set<const RexInput*> used_inputs;
1507  for (size_t i = 0; i < table_func->getTableFuncInputsSize(); ++i) {
1508  const auto table_func_inputs = visitor.visit(table_func->getTableFuncInputAt(i));
1509  used_inputs.insert(table_func_inputs.begin(), table_func_inputs.end());
1510  }
1511  std::vector<std::shared_ptr<RexInput>> used_inputs_owned(visitor.get_inputs_owned());
1512  return std::make_pair(used_inputs, used_inputs_owned);
1513 }
size_t getTableFuncInputsSize() const
Definition: RelAlgDag.h:2284
const RexScalar * getTableFuncInputAt(const size_t idx) const
Definition: RelAlgDag.h:2290

+ Here is the call graph for this function:

std::pair<std::unordered_set<const RexInput*>, std::vector<std::shared_ptr<RexInput> > > anonymous_namespace{RelAlgExecutor.cpp}::get_used_inputs ( const RelFilter filter)

Definition at line 1516 of file RelAlgExecutor.cpp.

References CHECK, and get_data_sink().

1516  {
1517  std::unordered_set<const RexInput*> used_inputs;
1518  std::vector<std::shared_ptr<RexInput>> used_inputs_owned;
1519  const auto data_sink_node = get_data_sink(filter);
1520  for (size_t nest_level = 0; nest_level < data_sink_node->inputCount(); ++nest_level) {
1521  const auto source = data_sink_node->getInput(nest_level);
1522  const auto scan_source = dynamic_cast<const RelScan*>(source);
1523  if (scan_source) {
1524  CHECK(source->getOutputMetainfo().empty());
1525  for (size_t i = 0; i < scan_source->size(); ++i) {
1526  auto synthesized_used_input = new RexInput(scan_source, i);
1527  used_inputs_owned.emplace_back(synthesized_used_input);
1528  used_inputs.insert(synthesized_used_input);
1529  }
1530  } else {
1531  const auto& partial_in_metadata = source->getOutputMetainfo();
1532  for (size_t i = 0; i < partial_in_metadata.size(); ++i) {
1533  auto synthesized_used_input = new RexInput(source, i);
1534  used_inputs_owned.emplace_back(synthesized_used_input);
1535  used_inputs.insert(synthesized_used_input);
1536  }
1537  }
1538  }
1539  return std::make_pair(used_inputs, used_inputs_owned);
1540 }
#define CHECK(condition)
Definition: Logger.h:291
const RelAlgNode * get_data_sink(const RelAlgNode *ra_node)

+ Here is the call graph for this function:

std::pair<std::unordered_set<const RexInput*>, std::vector<std::shared_ptr<RexInput> > > anonymous_namespace{RelAlgExecutor.cpp}::get_used_inputs ( const RelLogicalUnion logical_union)

Definition at line 1543 of file RelAlgExecutor.cpp.

References RelAlgNode::getInput(), RelAlgNode::inputCount(), and VLOG.

1543  {
1544  std::unordered_set<const RexInput*> used_inputs(logical_union->inputCount());
1545  std::vector<std::shared_ptr<RexInput>> used_inputs_owned;
1546  used_inputs_owned.reserve(logical_union->inputCount());
1547  VLOG(3) << "logical_union->inputCount()=" << logical_union->inputCount();
1548  auto const n_inputs = logical_union->inputCount();
1549  for (size_t nest_level = 0; nest_level < n_inputs; ++nest_level) {
1550  auto input = logical_union->getInput(nest_level);
1551  for (size_t i = 0; i < input->size(); ++i) {
1552  used_inputs_owned.emplace_back(std::make_shared<RexInput>(input, i));
1553  used_inputs.insert(used_inputs_owned.back().get());
1554  }
1555  }
1556  return std::make_pair(std::move(used_inputs), std::move(used_inputs_owned));
1557 }
const RelAlgNode * getInput(const size_t idx) const
Definition: RelAlgDag.h:892
const size_t inputCount() const
Definition: RelAlgDag.h:890
#define VLOG(n)
Definition: Logger.h:387

+ Here is the call graph for this function:

ErrorInfo anonymous_namespace{RelAlgExecutor.cpp}::getErrorDescription ( const int32_t  error_code)

Definition at line 4224 of file RelAlgExecutor.cpp.

References Executor::ERR_COLUMNAR_CONVERSION_NOT_SUPPORTED, Executor::ERR_DIV_BY_ZERO, Executor::ERR_GEOS, Executor::ERR_INTERRUPTED, Executor::ERR_OUT_OF_CPU_MEM, Executor::ERR_OUT_OF_GPU_MEM, Executor::ERR_OUT_OF_RENDER_MEM, Executor::ERR_OUT_OF_TIME, Executor::ERR_OVERFLOW_OR_UNDERFLOW, Executor::ERR_SINGLE_VALUE_FOUND_MULTIPLE_VALUES, Executor::ERR_STREAMING_TOP_N_NOT_SUPPORTED_IN_RENDER_QUERY, Executor::ERR_STRING_CONST_IN_RESULTSET, Executor::ERR_TOO_MANY_LITERALS, Executor::ERR_UNSUPPORTED_SELF_JOIN, and Executor::ERR_WIDTH_BUCKET_INVALID_ARGUMENT.

Referenced by RelAlgExecutor::getErrorMessageFromCode().

4224  {
4225  // 'designated initializers' don't compile on Windows for std 17
4226  // They require /std:c++20. They been removed for the windows port.
4227  switch (error_code) {
4229  return {"ERR_DIV_BY_ZERO", "Division by zero"};
4231  return {"ERR_OUT_OF_GPU_MEM",
4232 
4233  "Query couldn't keep the entire working set of columns in GPU memory"};
4235  return {"ERR_UNSUPPORTED_SELF_JOIN", "Self joins not supported yet"};
4237  return {"ERR_OUT_OF_CPU_MEM", "Not enough host memory to execute the query"};
4239  return {"ERR_OVERFLOW_OR_UNDERFLOW", "Overflow or underflow"};
4241  return {"ERR_OUT_OF_TIME", "Query execution has exceeded the time limit"};
4243  return {"ERR_INTERRUPTED", "Query execution has been interrupted"};
4245  return {"ERR_COLUMNAR_CONVERSION_NOT_SUPPORTED",
4246  "Columnar conversion not supported for variable length types"};
4248  return {"ERR_TOO_MANY_LITERALS", "Too many literals in the query"};
4250  return {"ERR_STRING_CONST_IN_RESULTSET",
4251 
4252  "NONE ENCODED String types are not supported as input result set."};
4254  return {"ERR_OUT_OF_RENDER_MEM",
4255 
4256  "Insufficient GPU memory for query results in render output buffer "
4257  "sized by render-mem-bytes"};
4259  return {"ERR_STREAMING_TOP_N_NOT_SUPPORTED_IN_RENDER_QUERY",
4260  "Streaming-Top-N not supported in Render Query"};
4262  return {"ERR_SINGLE_VALUE_FOUND_MULTIPLE_VALUES",
4263  "Multiple distinct values encountered"};
4264  case Executor::ERR_GEOS:
4265  return {"ERR_GEOS", "ERR_GEOS"};
4267  return {"ERR_WIDTH_BUCKET_INVALID_ARGUMENT",
4268 
4269  "Arguments of WIDTH_BUCKET function does not satisfy the condition"};
4270  default:
4271  return {nullptr, nullptr};
4272  }
4273 }
static const int32_t ERR_INTERRUPTED
Definition: Execute.h:1436
static const int32_t ERR_GEOS
Definition: Execute.h:1442
static const int32_t ERR_TOO_MANY_LITERALS
Definition: Execute.h:1438
static const int32_t ERR_STRING_CONST_IN_RESULTSET
Definition: Execute.h:1439
static const int32_t ERR_STREAMING_TOP_N_NOT_SUPPORTED_IN_RENDER_QUERY
Definition: Execute.h:1440
static const int32_t ERR_COLUMNAR_CONVERSION_NOT_SUPPORTED
Definition: Execute.h:1437
static const int32_t ERR_DIV_BY_ZERO
Definition: Execute.h:1428
static const int32_t ERR_OUT_OF_RENDER_MEM
Definition: Execute.h:1432
static const int32_t ERR_OVERFLOW_OR_UNDERFLOW
Definition: Execute.h:1434
static const int32_t ERR_OUT_OF_TIME
Definition: Execute.h:1435
static const int32_t ERR_UNSUPPORTED_SELF_JOIN
Definition: Execute.h:1431
static const int32_t ERR_SINGLE_VALUE_FOUND_MULTIPLE_VALUES
Definition: Execute.h:1441
static const int32_t ERR_OUT_OF_GPU_MEM
Definition: Execute.h:1429
static const int32_t ERR_WIDTH_BUCKET_INVALID_ARGUMENT
Definition: Execute.h:1443
static const int32_t ERR_OUT_OF_CPU_MEM
Definition: Execute.h:1433

+ Here is the caller graph for this function:

size_t anonymous_namespace{RelAlgExecutor.cpp}::groups_approx_upper_bound ( const std::vector< InputTableInfo > &  table_infos)

Upper bound estimation for the number of groups. Not strictly correct and not tight, but if the tables involved are really small we shouldn't waste time doing the NDV estimation. We don't account for cross-joins and / or group by unnested array, which is the reason this estimation isn't entirely reliable.

Definition at line 3510 of file RelAlgExecutor.cpp.

References CHECK.

Referenced by RelAlgExecutor::executeWorkUnit().

3510  {
3511  CHECK(!table_infos.empty());
3512  const auto& first_table = table_infos.front();
3513  size_t max_num_groups = first_table.info.getNumTuplesUpperBound();
3514  for (const auto& table_info : table_infos) {
3515  if (table_info.info.getNumTuplesUpperBound() > max_num_groups) {
3516  max_num_groups = table_info.info.getNumTuplesUpperBound();
3517  }
3518  }
3519  return std::max(max_num_groups, size_t(1));
3520 }
#define CHECK(condition)
Definition: Logger.h:291

+ Here is the caller graph for this function:

bool anonymous_namespace{RelAlgExecutor.cpp}::has_valid_query_plan_dag ( const RelAlgNode node)

Definition at line 218 of file RelAlgExecutor.cpp.

References EMPTY_HASHED_PLAN_DAG_KEY, and RelAlgNode::getQueryPlanDagHash().

Referenced by RelAlgExecutor::createCompoundWorkUnit(), RelAlgExecutor::createProjectWorkUnit(), RelAlgExecutor::executeRelAlgStep(), RelAlgExecutor::executeSort(), and RelAlgExecutor::executeTableFunction().

218  {
220 }
constexpr QueryPlanHash EMPTY_HASHED_PLAN_DAG_KEY
size_t getQueryPlanDagHash() const
Definition: RelAlgDag.h:874

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

template<class T >
int64_t anonymous_namespace{RelAlgExecutor.cpp}::insert_one_dict_str ( T *  col_data,
const std::string &  columnName,
const SQLTypeInfo columnType,
const Analyzer::Constant col_cv,
const Catalog_Namespace::Catalog catalog 
)

Definition at line 2843 of file RelAlgExecutor.cpp.

References CHECK, logger::ERROR, SQLTypeInfo::get_comp_param(), Analyzer::Constant::get_constval(), Analyzer::Constant::get_is_null(), Catalog_Namespace::Catalog::getMetadataForDict(), inline_fixed_encoding_null_val(), LOG, Datum::stringval, and heavydb.dtypes::T.

Referenced by RelAlgExecutor::executeSimpleInsert(), and insert_one_dict_str().

2847  {
2848  if (col_cv->get_is_null()) {
2849  *col_data = inline_fixed_encoding_null_val(columnType);
2850  } else {
2851  const int dict_id = columnType.get_comp_param();
2852  const auto col_datum = col_cv->get_constval();
2853  const auto& str = *col_datum.stringval;
2854  const auto dd = catalog.getMetadataForDict(dict_id);
2855  CHECK(dd && dd->stringDict);
2856  int32_t str_id = dd->stringDict->getOrAdd(str);
2857  if (!dd->dictIsTemp) {
2858  const auto checkpoint_ok = dd->stringDict->checkpoint();
2859  if (!checkpoint_ok) {
2860  throw std::runtime_error("Failed to checkpoint dictionary for column " +
2861  columnName);
2862  }
2863  }
2864  const bool invalid = str_id > max_valid_int_value<T>();
2865  if (invalid || str_id == inline_int_null_value<int32_t>()) {
2866  if (invalid) {
2867  LOG(ERROR) << "Could not encode string: " << str
2868  << ", the encoded value doesn't fit in " << sizeof(T) * 8
2869  << " bits. Will store NULL instead.";
2870  }
2871  str_id = inline_fixed_encoding_null_val(columnType);
2872  }
2873  *col_data = str_id;
2874  }
2875  return *col_data;
2876 }
#define LOG(tag)
Definition: Logger.h:285
bool get_is_null() const
Definition: Analyzer.h:347
const DictDescriptor * getMetadataForDict(int dict_ref, bool loadDict=true) const
Definition: Catalog.cpp:1999
std::string * stringval
Definition: Datum.h:77
Datum get_constval() const
Definition: Analyzer.h:348
HOST DEVICE int get_comp_param() const
Definition: sqltypes.h:392
#define CHECK(condition)
Definition: Logger.h:291
int64_t inline_fixed_encoding_null_val(const SQL_TYPE_INFO &ti)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

template<class T >
int64_t anonymous_namespace{RelAlgExecutor.cpp}::insert_one_dict_str ( T *  col_data,
const ColumnDescriptor cd,
const Analyzer::Constant col_cv,
const Catalog_Namespace::Catalog catalog 
)

Definition at line 2879 of file RelAlgExecutor.cpp.

References ColumnDescriptor::columnName, ColumnDescriptor::columnType, and insert_one_dict_str().

2882  {
2883  return insert_one_dict_str(col_data, cd->columnName, cd->columnType, col_cv, catalog);
2884 }
int64_t insert_one_dict_str(T *col_data, const std::string &columnName, const SQLTypeInfo &columnType, const Analyzer::Constant *col_cv, const Catalog_Namespace::Catalog &catalog)
SQLTypeInfo columnType
std::string columnName

+ Here is the call graph for this function:

bool anonymous_namespace{RelAlgExecutor.cpp}::is_agg ( const Analyzer::Expr expr)

Definition at line 1992 of file RelAlgExecutor.cpp.

References Analyzer::AggExpr::get_aggtype(), kAVG, kMAX, kMIN, kSUM, and kSUM_IF.

Referenced by anonymous_namespace{RelAlgDag.cpp}::create_compound(), RelAlgExecutor::executeWorkUnit(), get_logical_type_for_expr(), and ResultSet::getSingleSlotTargetBitmap().

1992  {
1993  const auto agg_expr = dynamic_cast<const Analyzer::AggExpr*>(expr);
1994  if (agg_expr && agg_expr->get_contains_agg()) {
1995  auto agg_type = agg_expr->get_aggtype();
1996  if (agg_type == SQLAgg::kMIN || agg_type == SQLAgg::kMAX ||
1997  agg_type == SQLAgg::kSUM || agg_type == SQLAgg::kSUM_IF ||
1998  agg_type == SQLAgg::kAVG) {
1999  return true;
2000  }
2001  }
2002  return false;
2003 }
Definition: sqldefs.h:75
Definition: sqldefs.h:77
SQLAgg get_aggtype() const
Definition: Analyzer.h:1207
Definition: sqldefs.h:76
Definition: sqldefs.h:74

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool anonymous_namespace{RelAlgExecutor.cpp}::is_count_distinct ( const Analyzer::Expr expr)

Definition at line 1987 of file RelAlgExecutor.cpp.

References Analyzer::AggExpr::get_is_distinct().

Referenced by get_logical_type_for_expr().

1987  {
1988  const auto agg_expr = dynamic_cast<const Analyzer::AggExpr*>(expr);
1989  return agg_expr && agg_expr->get_is_distinct();
1990 }
bool get_is_distinct() const
Definition: Analyzer.h:1210

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool anonymous_namespace{RelAlgExecutor.cpp}::is_projection ( const RelAlgExecutionUnit ra_exe_unit)

Definition at line 3522 of file RelAlgExecutor.cpp.

References RelAlgExecutionUnit::groupby_exprs.

Referenced by can_output_columnar(), and RelAlgTranslator::translateGeoFunctionArg().

3522  {
3523  return ra_exe_unit.groupby_exprs.size() == 1 && !ra_exe_unit.groupby_exprs.front();
3524 }
const std::list< std::shared_ptr< Analyzer::Expr > > groupby_exprs

+ Here is the caller graph for this function:

bool anonymous_namespace{RelAlgExecutor.cpp}::is_validate_or_explain_query ( const ExecutionOptions eo)

Definition at line 248 of file RelAlgExecutor.cpp.

References ExecutionOptions::just_calcite_explain, ExecutionOptions::just_explain, and ExecutionOptions::just_validate.

Referenced by RelAlgExecutor::canUseResultsetCache(), RelAlgExecutor::executeTableFunction(), and RelAlgExecutor::executeWorkUnit().

248  {
249  return eo.just_validate || eo.just_explain || eo.just_calcite_explain;
250 }

+ Here is the caller graph for this function:

bool anonymous_namespace{RelAlgExecutor.cpp}::is_window_execution_unit ( const RelAlgExecutionUnit ra_exe_unit)

Definition at line 2360 of file RelAlgExecutor.cpp.

References anonymous_namespace{QueryMemoryDescriptor.cpp}::any_of(), and RelAlgExecutionUnit::target_exprs.

Referenced by RelAlgExecutor::executeWorkUnit().

2360  {
2361  return std::any_of(ra_exe_unit.target_exprs.begin(),
2362  ra_exe_unit.target_exprs.end(),
2363  [](const Analyzer::Expr* expr) {
2364  return dynamic_cast<const Analyzer::WindowFunction*>(expr);
2365  });
2366 }
std::vector< Analyzer::Expr * > target_exprs
bool any_of(std::vector< Analyzer::Expr * > const &target_exprs)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::vector<JoinType> anonymous_namespace{RelAlgExecutor.cpp}::left_deep_join_types ( const RelLeftDeepInnerJoin left_deep_join)

Definition at line 4403 of file RelAlgExecutor.cpp.

References ANTI, CHECK_GE, RelLeftDeepInnerJoin::getJoinType(), RelLeftDeepInnerJoin::getOuterCondition(), INNER, RelAlgNode::inputCount(), LEFT, and SEMI.

Referenced by RelAlgExecutor::createCompoundWorkUnit(), RelAlgExecutor::createProjectWorkUnit(), RelAlgExecutor::getRelAlgTranslator(), and RelAlgExecutor::translateLeftDeepJoinFilter().

4403  {
4404  CHECK_GE(left_deep_join->inputCount(), size_t(2));
4405  std::vector<JoinType> join_types(left_deep_join->inputCount() - 1, JoinType::INNER);
4406  for (size_t nesting_level = 1; nesting_level <= left_deep_join->inputCount() - 1;
4407  ++nesting_level) {
4408  if (left_deep_join->getOuterCondition(nesting_level)) {
4409  join_types[nesting_level - 1] = JoinType::LEFT;
4410  }
4411  auto cur_level_join_type = left_deep_join->getJoinType(nesting_level);
4412  if (cur_level_join_type == JoinType::SEMI || cur_level_join_type == JoinType::ANTI) {
4413  join_types[nesting_level - 1] = cur_level_join_type;
4414  }
4415  }
4416  return join_types;
4417 }
const RexScalar * getOuterCondition(const size_t nesting_level) const
#define CHECK_GE(x, y)
Definition: Logger.h:306
const JoinType getJoinType(const size_t nesting_level) const
const size_t inputCount() const
Definition: RelAlgDag.h:890

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

template<class QualsList >
bool anonymous_namespace{RelAlgExecutor.cpp}::list_contains_expression ( const QualsList &  haystack,
const std::shared_ptr< Analyzer::Expr > &  needle 
)

Definition at line 4619 of file RelAlgExecutor.cpp.

Referenced by reverse_logical_distribution().

4620  {
4621  for (const auto& qual : haystack) {
4622  if (*qual == *needle) {
4623  return true;
4624  }
4625  }
4626  return false;
4627 }

+ Here is the caller graph for this function:

bool anonymous_namespace{RelAlgExecutor.cpp}::node_is_aggregate ( const RelAlgNode ra)

Definition at line 68 of file RelAlgExecutor.cpp.

Referenced by RelAlgExecutor::executeRelAlgQuerySingleStep(), and RelAlgExecutor::executeSort().

68  {
69  const auto compound = dynamic_cast<const RelCompound*>(ra);
70  const auto aggregate = dynamic_cast<const RelAggregate*>(ra);
71  return ((compound && compound->isAggregate()) || aggregate);
72 }

+ Here is the caller graph for this function:

void anonymous_namespace{RelAlgExecutor.cpp}::prepare_for_system_table_execution ( const RelAlgNode ra_node,
const CompilationOptions co 
)

Definition at line 153 of file RelAlgExecutor.cpp.

References CHECK, CHECK_LE, CPU, Data_Namespace::CPU_LEVEL, CompilationOptions::device_type, g_enable_system_tables, get_physical_inputs(), Catalog_Namespace::SysCatalog::getCatalog(), Chunk_NS::Chunk::getChunk(), Catalog_Namespace::SysCatalog::instance(), and shared::kInfoSchemaDbName.

Referenced by RelAlgExecutor::executeRelAlgQueryNoRetry(), and RelAlgExecutor::prepareForSystemTableExecution().

154  {
156  const auto info_schema_catalog =
158  CHECK(info_schema_catalog);
159  std::map<int32_t, std::vector<int32_t>> system_table_columns_by_table_id;
160  for (const auto& physical_input : get_physical_inputs(&ra_node)) {
161  if (info_schema_catalog->getDatabaseId() != physical_input.db_id) {
162  continue;
163  }
164  const auto table_id = physical_input.table_id;
165  const auto table = info_schema_catalog->getMetadataForTable(table_id, false);
166  CHECK(table);
167  if (table->is_in_memory_system_table) {
168  const auto column_id =
169  info_schema_catalog->getColumnIdBySpi(table_id, physical_input.col_id);
170  system_table_columns_by_table_id[table_id].emplace_back(column_id);
171  }
172  }
173  // Execute on CPU for queries involving system tables
174  if (!system_table_columns_by_table_id.empty() &&
176  throw QueryMustRunOnCpu();
177  }
178 
179  for (const auto& [table_id, column_ids] : system_table_columns_by_table_id) {
180  // Clear any previously cached data, since system tables depend on point in
181  // time data snapshots.
182  info_schema_catalog->getDataMgr().deleteChunksWithPrefix(
183  ChunkKey{info_schema_catalog->getDatabaseId(), table_id},
185 
186  // TODO(Misiu): This prefetching can be removed if we can add support for
187  // ExpressionRanges to reduce invalid with valid ranges (right now prefetching
188  // causes us to fetch the chunks twice). Right now if we do not prefetch (i.e. if
189  // we remove the code below) some nodes will return valid ranges and others will
190  // return unknown because they only use placeholder metadata and the LeafAggregator
191  // has no idea how to reduce the two.
192  const auto td = info_schema_catalog->getMetadataForTable(table_id);
193  CHECK(td);
194  CHECK(td->fragmenter);
195  auto fragment_count = td->fragmenter->getFragmentsForQuery().fragments.size();
196  CHECK_LE(fragment_count, static_cast<size_t>(1))
197  << "In-memory system tables are expected to have a single fragment.";
198  if (fragment_count > 0) {
199  for (auto column_id : column_ids) {
200  // Prefetch system table chunks in order to force chunk statistics metadata
201  // computation.
202  const auto cd = info_schema_catalog->getMetadataForColumn(table_id, column_id);
203  const ChunkKey chunk_key{
204  info_schema_catalog->getDatabaseId(), table_id, column_id, 0};
206  &(info_schema_catalog->getDataMgr()),
207  chunk_key,
209  0,
210  0,
211  0);
212  }
213  }
214  }
215  }
216 }
std::vector< int > ChunkKey
Definition: types.h:36
const std::string kInfoSchemaDbName
static SysCatalog & instance()
Definition: SysCatalog.h:343
bool g_enable_system_tables
Definition: SysCatalog.cpp:64
ExecutorDeviceType device_type
std::shared_ptr< Catalog > getCatalog(const std::string &dbName)
#define CHECK_LE(x, y)
Definition: Logger.h:304
#define CHECK(condition)
Definition: Logger.h:291
std::unordered_set< PhysicalInput > get_physical_inputs(const RelAlgNode *ra)
static std::shared_ptr< Chunk > getChunk(const ColumnDescriptor *cd, DataMgr *data_mgr, const ChunkKey &key, const MemoryLevel mem_level, const int deviceId, const size_t num_bytes, const size_t num_elems, const bool pinnable=true)
Definition: Chunk.cpp:31

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void anonymous_namespace{RelAlgExecutor.cpp}::prepare_foreign_table_for_execution ( const RelAlgNode ra_node)

Definition at line 145 of file RelAlgExecutor.cpp.

References anonymous_namespace{Execute.cpp}::prepare_string_dictionaries(), and set_parallelism_hints().

Referenced by RelAlgExecutor::executeRelAlgQueryNoRetry(), and RelAlgExecutor::prepareForeignTables().

145  {
146  // Iterate through ra_node inputs for types that need to be loaded pre-execution
147  // If they do not have valid metadata, load them into CPU memory to generate
148  // the metadata and leave them ready to be used by the query
149  set_parallelism_hints(ra_node);
151 }
void prepare_string_dictionaries(const std::unordered_set< PhysicalInput > &phys_inputs)
Definition: Execute.cpp:189
void set_parallelism_hints(const RelAlgNode &ra_node)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void anonymous_namespace{RelAlgExecutor.cpp}::prepare_string_dictionaries ( const RelAlgNode ra_node)

Definition at line 133 of file RelAlgExecutor.cpp.

References CHECK, StorageType::FOREIGN_TABLE, get_physical_inputs(), Catalog_Namespace::SysCatalog::getCatalog(), Catalog_Namespace::SysCatalog::instance(), and foreign_storage::populate_string_dictionary().

133  {
134  for (const auto [col_id, table_id, db_id] : get_physical_inputs(&ra_node)) {
135  const auto catalog = Catalog_Namespace::SysCatalog::instance().getCatalog(db_id);
136  CHECK(catalog);
137  const auto table = catalog->getMetadataForTable(table_id, false);
138  if (table && table->storageType == StorageType::FOREIGN_TABLE) {
139  const auto spi_col_id = catalog->getColumnIdBySpi(table_id, col_id);
140  foreign_storage::populate_string_dictionary(table_id, spi_col_id, db_id);
141  }
142  }
143 }
static SysCatalog & instance()
Definition: SysCatalog.h:343
void populate_string_dictionary(int32_t table_id, int32_t col_id, int32_t db_id)
Definition: Execute.cpp:205
std::shared_ptr< Catalog > getCatalog(const std::string &dbName)
#define CHECK(condition)
Definition: Logger.h:291
std::unordered_set< PhysicalInput > get_physical_inputs(const RelAlgNode *ra)
static constexpr char const * FOREIGN_TABLE

+ Here is the call graph for this function:

std::shared_ptr<Analyzer::Expr> anonymous_namespace{RelAlgExecutor.cpp}::reverse_logical_distribution ( const std::shared_ptr< Analyzer::Expr > &  expr)

Definition at line 4632 of file RelAlgExecutor.cpp.

References build_logical_expression(), CHECK_GE, kAND, kONE, kOR, list_contains_expression(), Parser::OperExpr::normalize(), qual_to_conjunctive_form(), and qual_to_disjunctive_form().

Referenced by RelAlgExecutor::makeJoinQuals().

4633  {
4634  const auto expr_terms = qual_to_disjunctive_form(expr);
4635  CHECK_GE(expr_terms.size(), size_t(1));
4636  const auto& first_term = expr_terms.front();
4637  const auto first_term_factors = qual_to_conjunctive_form(first_term);
4638  std::vector<std::shared_ptr<Analyzer::Expr>> common_factors;
4639  // First, collect the conjunctive components common to all the disjunctive components.
4640  // Don't do it for simple qualifiers, we only care about expensive or join qualifiers.
4641  for (const auto& first_term_factor : first_term_factors.quals) {
4642  bool is_common =
4643  expr_terms.size() > 1; // Only report common factors for disjunction.
4644  for (size_t i = 1; i < expr_terms.size(); ++i) {
4645  const auto crt_term_factors = qual_to_conjunctive_form(expr_terms[i]);
4646  if (!list_contains_expression(crt_term_factors.quals, first_term_factor)) {
4647  is_common = false;
4648  break;
4649  }
4650  }
4651  if (is_common) {
4652  common_factors.push_back(first_term_factor);
4653  }
4654  }
4655  if (common_factors.empty()) {
4656  return expr;
4657  }
4658  // Now that the common expressions are known, collect the remaining expressions.
4659  std::vector<std::shared_ptr<Analyzer::Expr>> remaining_terms;
4660  for (const auto& term : expr_terms) {
4661  const auto term_cf = qual_to_conjunctive_form(term);
4662  std::vector<std::shared_ptr<Analyzer::Expr>> remaining_quals(
4663  term_cf.simple_quals.begin(), term_cf.simple_quals.end());
4664  for (const auto& qual : term_cf.quals) {
4665  if (!list_contains_expression(common_factors, qual)) {
4666  remaining_quals.push_back(qual);
4667  }
4668  }
4669  if (!remaining_quals.empty()) {
4670  remaining_terms.push_back(build_logical_expression(remaining_quals, kAND));
4671  }
4672  }
4673  // Reconstruct the expression with the transformation applied.
4674  const auto common_expr = build_logical_expression(common_factors, kAND);
4675  if (remaining_terms.empty()) {
4676  return common_expr;
4677  }
4678  const auto remaining_expr = build_logical_expression(remaining_terms, kOR);
4679  return Parser::OperExpr::normalize(kAND, kONE, common_expr, remaining_expr);
4680 }
static std::shared_ptr< Analyzer::Expr > normalize(const SQLOps optype, const SQLQualifier qual, std::shared_ptr< Analyzer::Expr > left_expr, std::shared_ptr< Analyzer::Expr > right_expr, const Executor *executor=nullptr)
Definition: ParserNode.cpp:372
Definition: sqldefs.h:37
#define CHECK_GE(x, y)
Definition: Logger.h:306
QualsConjunctiveForm qual_to_conjunctive_form(const std::shared_ptr< Analyzer::Expr > qual_expr)
bool list_contains_expression(const QualsList &haystack, const std::shared_ptr< Analyzer::Expr > &needle)
Definition: sqldefs.h:36
std::shared_ptr< Analyzer::Expr > build_logical_expression(const std::vector< std::shared_ptr< Analyzer::Expr >> &factors, const SQLOps sql_op)
Definition: sqldefs.h:71
std::vector< std::shared_ptr< Analyzer::Expr > > qual_to_disjunctive_form(const std::shared_ptr< Analyzer::Expr > &qual_expr)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::list<std::shared_ptr<Analyzer::Expr> > anonymous_namespace{RelAlgExecutor.cpp}::rewrite_quals ( const std::list< std::shared_ptr< Analyzer::Expr >> &  quals)

Definition at line 4461 of file RelAlgExecutor.cpp.

References rewrite_expr().

Referenced by RelAlgExecutor::createCompoundWorkUnit().

4462  {
4463  std::list<std::shared_ptr<Analyzer::Expr>> rewritten_quals;
4464  for (const auto& qual : quals) {
4465  const auto rewritten_qual = rewrite_expr(qual.get());
4466  rewritten_quals.push_back(rewritten_qual ? rewritten_qual : qual);
4467  }
4468  return rewritten_quals;
4469 }
Analyzer::ExpressionPtr rewrite_expr(const Analyzer::Expr *expr)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::vector<const RexScalar*> anonymous_namespace{RelAlgExecutor.cpp}::rex_to_conjunctive_form ( const RexScalar qual_expr)

Definition at line 4592 of file RelAlgExecutor.cpp.

References CHECK, CHECK_GE, and kAND.

Referenced by RelAlgExecutor::makeJoinQuals().

4592  {
4593  CHECK(qual_expr);
4594  const auto bin_oper = dynamic_cast<const RexOperator*>(qual_expr);
4595  if (!bin_oper || bin_oper->getOperator() != kAND) {
4596  return {qual_expr};
4597  }
4598  CHECK_GE(bin_oper->size(), size_t(2));
4599  auto lhs_cf = rex_to_conjunctive_form(bin_oper->getOperand(0));
4600  for (size_t i = 1; i < bin_oper->size(); ++i) {
4601  const auto rhs_cf = rex_to_conjunctive_form(bin_oper->getOperand(i));
4602  lhs_cf.insert(lhs_cf.end(), rhs_cf.begin(), rhs_cf.end());
4603  }
4604  return lhs_cf;
4605 }
#define CHECK_GE(x, y)
Definition: Logger.h:306
std::vector< const RexScalar * > rex_to_conjunctive_form(const RexScalar *qual_expr)
Definition: sqldefs.h:36
#define CHECK(condition)
Definition: Logger.h:291

+ Here is the caller graph for this function:

const RexScalar* anonymous_namespace{RelAlgExecutor.cpp}::scalar_at ( const size_t  i,
const RelCompound compound 
)

Definition at line 1745 of file RelAlgExecutor.cpp.

References RelCompound::getScalarSource().

Referenced by translate_scalar_sources(), and translate_scalar_sources_for_update().

1745  {
1746  return compound->getScalarSource(i);
1747 }
const RexScalar * getScalarSource(const size_t i) const
Definition: RelAlgDag.h:1862

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

const RexScalar* anonymous_namespace{RelAlgExecutor.cpp}::scalar_at ( const size_t  i,
const RelProject project 
)

Definition at line 1749 of file RelAlgExecutor.cpp.

References RelProject::getProjectAt().

1749  {
1750  return project->getProjectAt(i);
1751 }
const RexScalar * getProjectAt(const size_t idx) const
Definition: RelAlgDag.h:1204

+ Here is the call graph for this function:

const RexScalar* anonymous_namespace{RelAlgExecutor.cpp}::scalar_at ( const size_t  i,
const RelTableFunction table_func 
)

Definition at line 1753 of file RelAlgExecutor.cpp.

References RelTableFunction::getTableFuncInputAt().

1753  {
1754  return table_func->getTableFuncInputAt(i);
1755 }
const RexScalar * getTableFuncInputAt(const size_t idx) const
Definition: RelAlgDag.h:2290

+ Here is the call graph for this function:

void anonymous_namespace{RelAlgExecutor.cpp}::set_parallelism_hints ( const RelAlgNode ra_node)

Definition at line 87 of file RelAlgExecutor.cpp.

References CHECK, Data_Namespace::CPU_LEVEL, StorageType::FOREIGN_TABLE, get_physical_inputs(), Catalog_Namespace::SysCatalog::getCatalog(), Catalog_Namespace::SysCatalog::getDataMgr(), PersistentStorageMgr::getForeignStorageMgr(), Data_Namespace::DataMgr::getPersistentStorageMgr(), Catalog_Namespace::SysCatalog::instance(), and foreign_storage::key_does_not_shard_to_leaf().

Referenced by prepare_foreign_table_for_execution().

87  {
88  std::map<ChunkKey, std::set<foreign_storage::ForeignStorageMgr::ParallelismHint>>
89  parallelism_hints_per_table;
90  for (const auto& physical_input : get_physical_inputs(&ra_node)) {
91  const auto table_id = physical_input.table_id;
92  const auto catalog =
94  CHECK(catalog);
95  const auto table = catalog->getMetadataForTable(table_id, true);
96  if (table && table->storageType == StorageType::FOREIGN_TABLE &&
97  !table->is_in_memory_system_table) {
98  const auto col_id = catalog->getColumnIdBySpi(table_id, physical_input.col_id);
99  const auto col_desc = catalog->getMetadataForColumn(table_id, col_id);
100  const auto foreign_table = catalog->getForeignTable(table_id);
101  for (const auto& fragment :
102  foreign_table->fragmenter->getFragmentsForQuery().fragments) {
103  Chunk_NS::Chunk chunk{col_desc};
104  ChunkKey chunk_key = {
105  physical_input.db_id, table_id, col_id, fragment.fragmentId};
106 
107  // Parallelism hints should not include fragments that are not mapped to the
108  // current node, otherwise we will try to prefetch them and run into trouble.
110  continue;
111  }
112 
113  // do not include chunk hints that are in CPU memory
114  if (!chunk.isChunkOnDevice(
115  &catalog->getDataMgr(), chunk_key, Data_Namespace::CPU_LEVEL, 0)) {
116  parallelism_hints_per_table[{physical_input.db_id, table_id}].insert(
118  fragment.fragmentId});
119  }
120  }
121  }
122  }
123  if (!parallelism_hints_per_table.empty()) {
124  auto foreign_storage_mgr = Catalog_Namespace::SysCatalog::instance()
125  .getDataMgr()
128  CHECK(foreign_storage_mgr);
129  foreign_storage_mgr->setParallelismHints(parallelism_hints_per_table);
130  }
131 }
std::vector< int > ChunkKey
Definition: types.h:36
PersistentStorageMgr * getPersistentStorageMgr() const
Definition: DataMgr.cpp:634
foreign_storage::ForeignStorageMgr * getForeignStorageMgr() const
Data_Namespace::DataMgr & getDataMgr() const
Definition: SysCatalog.h:234
bool key_does_not_shard_to_leaf(const ChunkKey &key)
static SysCatalog & instance()
Definition: SysCatalog.h:343
std::shared_ptr< Catalog > getCatalog(const std::string &dbName)
#define CHECK(condition)
Definition: Logger.h:291
std::unordered_set< PhysicalInput > get_physical_inputs(const RelAlgNode *ra)
static constexpr char const * FOREIGN_TABLE

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr<Analyzer::Expr> anonymous_namespace{RelAlgExecutor.cpp}::set_transient_dict ( const std::shared_ptr< Analyzer::Expr expr)

Definition at line 1757 of file RelAlgExecutor.cpp.

References kENCODING_DICT, kENCODING_NONE, and TRANSIENT_DICT_ID.

Referenced by set_transient_dict_maybe(), translate_groupby_exprs(), and translate_targets().

1758  {
1759  const auto& ti = expr->get_type_info();
1760  if (!ti.is_string() || ti.get_compression() != kENCODING_NONE) {
1761  return expr;
1762  }
1763  auto transient_dict_ti = ti;
1764  transient_dict_ti.set_compression(kENCODING_DICT);
1765  transient_dict_ti.set_comp_param(TRANSIENT_DICT_ID);
1766  transient_dict_ti.set_fixed_size();
1767  return expr->add_cast(transient_dict_ti);
1768 }
#define TRANSIENT_DICT_ID
Definition: DbObjectKeys.h:24

+ Here is the caller graph for this function:

void anonymous_namespace{RelAlgExecutor.cpp}::set_transient_dict_maybe ( std::vector< std::shared_ptr< Analyzer::Expr >> &  scalar_sources,
const std::shared_ptr< Analyzer::Expr > &  expr 
)

Definition at line 1770 of file RelAlgExecutor.cpp.

References fold_expr(), and set_transient_dict().

Referenced by translate_scalar_sources(), and translate_scalar_sources_for_update().

1772  {
1773  try {
1774  scalar_sources.push_back(set_transient_dict(fold_expr(expr.get())));
1775  } catch (...) {
1776  scalar_sources.push_back(fold_expr(expr.get()));
1777  }
1778 }
std::shared_ptr< Analyzer::Expr > set_transient_dict(const std::shared_ptr< Analyzer::Expr > expr)
std::shared_ptr< Analyzer::Expr > fold_expr(const Analyzer::Expr *expr)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool anonymous_namespace{RelAlgExecutor.cpp}::should_output_columnar ( const RelAlgExecutionUnit ra_exe_unit)

Definition at line 3554 of file RelAlgExecutor.cpp.

References g_columnar_large_projections, g_columnar_large_projections_threshold, and RelAlgExecutionUnit::scan_limit.

Referenced by RelAlgExecutor::executeWorkUnit().

3554  {
3557 }
bool g_columnar_large_projections
size_t g_columnar_large_projections_threshold

+ Here is the caller graph for this function:

std::vector<std::shared_ptr<Analyzer::Expr> > anonymous_namespace{RelAlgExecutor.cpp}::synthesize_inputs ( const RelAlgNode ra_node,
const size_t  nest_level,
const std::vector< TargetMetaInfo > &  in_metainfo,
const std::unordered_map< const RelAlgNode *, int > &  input_to_nest_level 
)

Definition at line 4757 of file RelAlgExecutor.cpp.

References CHECK, CHECK_GE, CHECK_LE, RelAlgNode::getInput(), RelAlgNode::inputCount(), and table_key_from_ra().

Referenced by RelAlgExecutor::createAggregateWorkUnit(), and get_inputs_meta().

4761  {
4762  CHECK_LE(size_t(1), ra_node->inputCount());
4763  CHECK_GE(size_t(2), ra_node->inputCount());
4764  const auto input = ra_node->getInput(nest_level);
4765  const auto it_rte_idx = input_to_nest_level.find(input);
4766  CHECK(it_rte_idx != input_to_nest_level.end());
4767  const int rte_idx = it_rte_idx->second;
4768  const auto table_key = table_key_from_ra(input);
4769  std::vector<std::shared_ptr<Analyzer::Expr>> inputs;
4770  const auto scan_ra = dynamic_cast<const RelScan*>(input);
4771  int input_idx = 0;
4772  for (const auto& input_meta : in_metainfo) {
4773  inputs.push_back(std::make_shared<Analyzer::ColumnVar>(
4774  input_meta.get_type_info(),
4775  shared::ColumnKey{table_key, scan_ra ? input_idx + 1 : input_idx},
4776  rte_idx));
4777  ++input_idx;
4778  }
4779  return inputs;
4780 }
shared::TableKey table_key_from_ra(const RelAlgNode *ra_node)
#define CHECK_GE(x, y)
Definition: Logger.h:306
const RelAlgNode * getInput(const size_t idx) const
Definition: RelAlgDag.h:892
#define CHECK_LE(x, y)
Definition: Logger.h:304
#define CHECK(condition)
Definition: Logger.h:291
const size_t inputCount() const
Definition: RelAlgDag.h:890

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

shared::TableKey anonymous_namespace{RelAlgExecutor.cpp}::table_key_from_ra ( const RelAlgNode ra_node)

Definition at line 1559 of file RelAlgExecutor.cpp.

References CHECK, shared::TableKey::db_id, and RelAlgNode::getId().

Referenced by collect_used_input_desc(), get_input_desc_impl(), and synthesize_inputs().

1559  {
1560  const auto scan_ra = dynamic_cast<const RelScan*>(ra_node);
1561  shared::TableKey table_key{0, int32_t(-ra_node->getId())};
1562  if (scan_ra) {
1563  table_key.db_id = scan_ra->getCatalog().getDatabaseId();
1564  const auto td = scan_ra->getTableDescriptor();
1565  CHECK(td);
1566  table_key.table_id = td->tableId;
1567  }
1568  return table_key;
1569 }
unsigned getId() const
Definition: RelAlgDag.h:880
#define CHECK(condition)
Definition: Logger.h:291

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::vector<std::shared_ptr<Analyzer::Expr> > anonymous_namespace{RelAlgExecutor.cpp}::target_exprs_for_union ( RelAlgNode const *  input_node)

Definition at line 4955 of file RelAlgExecutor.cpp.

References RelAlgNode::getId(), RelAlgNode::getOutputMetainfo(), shared::printContainer(), and VLOG.

Referenced by RelAlgExecutor::createUnionWorkUnit().

4956  {
4957  std::vector<TargetMetaInfo> const& tmis = input_node->getOutputMetainfo();
4958  VLOG(3) << "input_node->getOutputMetainfo()=" << shared::printContainer(tmis);
4959  const int negative_node_id = -input_node->getId();
4960  int32_t db_id{0};
4961  if (auto rel_scan = dynamic_cast<const RelScan*>(input_node)) {
4962  db_id = rel_scan->getCatalog().getDatabaseId();
4963  }
4964  std::vector<std::shared_ptr<Analyzer::Expr>> target_exprs;
4965  target_exprs.reserve(tmis.size());
4966  for (size_t i = 0; i < tmis.size(); ++i) {
4967  target_exprs.push_back(std::make_shared<Analyzer::ColumnVar>(
4968  tmis[i].get_type_info(),
4969  shared::ColumnKey{db_id, negative_node_id, int32_t(i)},
4970  0));
4971  }
4972  return target_exprs;
4973 }
PrintContainer< CONTAINER > printContainer(CONTAINER &container)
Definition: misc.h:107
#define VLOG(n)
Definition: Logger.h:387

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr<Analyzer::Expr> anonymous_namespace{RelAlgExecutor.cpp}::transform_to_inner ( const Analyzer::Expr expr)

Definition at line 2510 of file RelAlgExecutor.cpp.

Referenced by RelAlgExecutor::computeWindow().

2510  {
2511  const auto tuple = dynamic_cast<const Analyzer::ExpressionTuple*>(expr);
2512  if (tuple) {
2513  std::vector<std::shared_ptr<Analyzer::Expr>> transformed_tuple;
2514  for (const auto& element : tuple->getTuple()) {
2515  transformed_tuple.push_back(transform_to_inner(element.get()));
2516  }
2517  return makeExpr<Analyzer::ExpressionTuple>(transformed_tuple);
2518  }
2519  const auto col = dynamic_cast<const Analyzer::ColumnVar*>(expr);
2520  if (!col) {
2521  throw std::runtime_error("Only columns supported in the window partition for now");
2522  }
2523  return makeExpr<Analyzer::ColumnVar>(col->get_type_info(), col->getColumnKey(), 1);
2524 }
std::shared_ptr< Analyzer::Expr > transform_to_inner(const Analyzer::Expr *expr)

+ Here is the caller graph for this function:

std::list<std::shared_ptr<Analyzer::Expr> > anonymous_namespace{RelAlgExecutor.cpp}::translate_groupby_exprs ( const RelCompound compound,
const std::vector< std::shared_ptr< Analyzer::Expr >> &  scalar_sources 
)

Definition at line 1856 of file RelAlgExecutor.cpp.

References RelCompound::getGroupByCount(), RelCompound::isAggregate(), and set_transient_dict().

Referenced by RelAlgExecutor::createAggregateWorkUnit(), and RelAlgExecutor::createCompoundWorkUnit().

1858  {
1859  if (!compound->isAggregate()) {
1860  return {nullptr};
1861  }
1862  std::list<std::shared_ptr<Analyzer::Expr>> groupby_exprs;
1863  for (size_t group_idx = 0; group_idx < compound->getGroupByCount(); ++group_idx) {
1864  groupby_exprs.push_back(set_transient_dict(scalar_sources[group_idx]));
1865  }
1866  return groupby_exprs;
1867 }
std::shared_ptr< Analyzer::Expr > set_transient_dict(const std::shared_ptr< Analyzer::Expr > expr)
const size_t getGroupByCount() const
Definition: RelAlgDag.h:1871
bool isAggregate() const
Definition: RelAlgDag.h:1873

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::list<std::shared_ptr<Analyzer::Expr> > anonymous_namespace{RelAlgExecutor.cpp}::translate_groupby_exprs ( const RelAggregate aggregate,
const std::vector< std::shared_ptr< Analyzer::Expr >> &  scalar_sources 
)

Definition at line 1869 of file RelAlgExecutor.cpp.

References RelAggregate::getGroupByCount(), and set_transient_dict().

1871  {
1872  std::list<std::shared_ptr<Analyzer::Expr>> groupby_exprs;
1873  for (size_t group_idx = 0; group_idx < aggregate->getGroupByCount(); ++group_idx) {
1874  groupby_exprs.push_back(set_transient_dict(scalar_sources[group_idx]));
1875  }
1876  return groupby_exprs;
1877 }
const size_t getGroupByCount() const
Definition: RelAlgDag.h:1342
std::shared_ptr< Analyzer::Expr > set_transient_dict(const std::shared_ptr< Analyzer::Expr > expr)

+ Here is the call graph for this function:

QualsConjunctiveForm anonymous_namespace{RelAlgExecutor.cpp}::translate_quals ( const RelCompound compound,
const RelAlgTranslator translator 
)

Definition at line 1879 of file RelAlgExecutor.cpp.

References fold_expr(), RelCompound::getFilterExpr(), qual_to_conjunctive_form(), and RelAlgTranslator::translate().

Referenced by RelAlgExecutor::createCompoundWorkUnit().

1880  {
1881  const auto filter_rex = compound->getFilterExpr();
1882  const auto filter_expr = filter_rex ? translator.translate(filter_rex) : nullptr;
1883  return filter_expr ? qual_to_conjunctive_form(fold_expr(filter_expr.get()))
1885 }
const RexScalar * getFilterExpr() const
Definition: RelAlgDag.h:1846
QualsConjunctiveForm qual_to_conjunctive_form(const std::shared_ptr< Analyzer::Expr > qual_expr)
std::shared_ptr< Analyzer::Expr > translate(const RexScalar *rex) const
std::shared_ptr< Analyzer::Expr > fold_expr(const Analyzer::Expr *expr)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

template<class RA >
std::vector<std::shared_ptr<Analyzer::Expr> > anonymous_namespace{RelAlgExecutor.cpp}::translate_scalar_sources ( const RA *  ra_node,
const RelAlgTranslator translator,
const ::ExecutorType  executor_type 
)

Definition at line 1790 of file RelAlgExecutor.cpp.

References cast_dict_to_none(), RelRexToStringConfig::defaults(), fold_expr(), get_scalar_sources_size(), Native, rewrite_array_elements(), rewrite_expr(), scalar_at(), set_transient_dict_maybe(), TableFunctions, RelAlgTranslator::translate(), and VLOG.

Referenced by RelAlgExecutor::createCompoundWorkUnit(), RelAlgExecutor::createProjectWorkUnit(), and RelAlgExecutor::createTableFunctionWorkUnit().

1793  {
1794  std::vector<std::shared_ptr<Analyzer::Expr>> scalar_sources;
1795  const size_t scalar_sources_size = get_scalar_sources_size(ra_node);
1796  VLOG(3) << "get_scalar_sources_size("
1797  << ra_node->toString(RelRexToStringConfig::defaults())
1798  << ") = " << scalar_sources_size;
1799  for (size_t i = 0; i < scalar_sources_size; ++i) {
1800  const auto scalar_rex = scalar_at(i, ra_node);
1801  if (dynamic_cast<const RexRef*>(scalar_rex)) {
1802  // RexRef are synthetic scalars we append at the end of the real ones
1803  // for the sake of taking memory ownership, no real work needed here.
1804  continue;
1805  }
1806 
1807  const auto scalar_expr =
1808  rewrite_array_elements(translator.translate(scalar_rex).get());
1809  const auto rewritten_expr = rewrite_expr(scalar_expr.get());
1810  if (executor_type == ExecutorType::Native) {
1811  set_transient_dict_maybe(scalar_sources, rewritten_expr);
1812  } else if (executor_type == ExecutorType::TableFunctions) {
1813  scalar_sources.push_back(fold_expr(rewritten_expr.get()));
1814  } else {
1815  scalar_sources.push_back(cast_dict_to_none(fold_expr(rewritten_expr.get())));
1816  }
1817  }
1818 
1819  return scalar_sources;
1820 }
Analyzer::ExpressionPtr rewrite_array_elements(Analyzer::Expr const *expr)
size_t get_scalar_sources_size(const RelCompound *compound)
Analyzer::ExpressionPtr rewrite_expr(const Analyzer::Expr *expr)
std::shared_ptr< Analyzer::Expr > cast_dict_to_none(const std::shared_ptr< Analyzer::Expr > &input)
std::shared_ptr< Analyzer::Expr > translate(const RexScalar *rex) const
static RelRexToStringConfig defaults()
Definition: RelAlgDag.h:49
const RexScalar * scalar_at(const size_t i, const RelCompound *compound)
#define VLOG(n)
Definition: Logger.h:387
std::shared_ptr< Analyzer::Expr > fold_expr(const Analyzer::Expr *expr)
void set_transient_dict_maybe(std::vector< std::shared_ptr< Analyzer::Expr >> &scalar_sources, const std::shared_ptr< Analyzer::Expr > &expr)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

template<class RA >
std::vector<std::shared_ptr<Analyzer::Expr> > anonymous_namespace{RelAlgExecutor.cpp}::translate_scalar_sources_for_update ( const RA *  ra_node,
const RelAlgTranslator translator,
int32_t  tableId,
const Catalog_Namespace::Catalog cat,
const ColumnNameList colNames,
size_t  starting_projection_column_idx 
)

Definition at line 1823 of file RelAlgExecutor.cpp.

References cat(), get_scalar_sources_size(), rewrite_array_elements(), rewrite_expr(), scalar_at(), set_transient_dict_maybe(), and RelAlgTranslator::translate().

1829  {
1830  std::vector<std::shared_ptr<Analyzer::Expr>> scalar_sources;
1831  for (size_t i = 0; i < get_scalar_sources_size(ra_node); ++i) {
1832  const auto scalar_rex = scalar_at(i, ra_node);
1833  if (dynamic_cast<const RexRef*>(scalar_rex)) {
1834  // RexRef are synthetic scalars we append at the end of the real ones
1835  // for the sake of taking memory ownership, no real work needed here.
1836  continue;
1837  }
1838 
1839  std::shared_ptr<Analyzer::Expr> translated_expr;
1840  if (i >= starting_projection_column_idx && i < get_scalar_sources_size(ra_node) - 1) {
1841  translated_expr = cast_to_column_type(translator.translate(scalar_rex),
1842  tableId,
1843  cat,
1844  colNames[i - starting_projection_column_idx]);
1845  } else {
1846  translated_expr = translator.translate(scalar_rex);
1847  }
1848  const auto scalar_expr = rewrite_array_elements(translated_expr.get());
1849  const auto rewritten_expr = rewrite_expr(scalar_expr.get());
1850  set_transient_dict_maybe(scalar_sources, rewritten_expr);
1851  }
1852 
1853  return scalar_sources;
1854 }
Analyzer::ExpressionPtr rewrite_array_elements(Analyzer::Expr const *expr)
std::string cat(Ts &&...args)
size_t get_scalar_sources_size(const RelCompound *compound)
Analyzer::ExpressionPtr rewrite_expr(const Analyzer::Expr *expr)
std::shared_ptr< Analyzer::Expr > translate(const RexScalar *rex) const
const RexScalar * scalar_at(const size_t i, const RelCompound *compound)
void set_transient_dict_maybe(std::vector< std::shared_ptr< Analyzer::Expr >> &scalar_sources, const std::shared_ptr< Analyzer::Expr > &expr)

+ Here is the call graph for this function:

std::vector<Analyzer::Expr*> anonymous_namespace{RelAlgExecutor.cpp}::translate_targets ( std::vector< std::shared_ptr< Analyzer::Expr >> &  target_exprs_owned,
std::unordered_map< size_t, SQLTypeInfo > &  target_exprs_type_infos,
const std::vector< std::shared_ptr< Analyzer::Expr >> &  scalar_sources,
const std::list< std::shared_ptr< Analyzer::Expr >> &  groupby_exprs,
const RelCompound compound,
const RelAlgTranslator translator,
const ExecutorType  executor_type 
)

Definition at line 1910 of file RelAlgExecutor.cpp.

References cast_dict_to_none(), CHECK, CHECK_GE, CHECK_LE, anonymous_namespace{RelAlgExecutor.cpp}::anonymous_namespace{RelAlgExecutor.cpp}::conditionally_change_arg_to_int_type(), fold_expr(), RexRef::getIndex(), RelCompound::getTargetExpr(), Analyzer::Var::kGROUPBY, Native, rewrite_array_elements(), rewrite_expr(), set_transient_dict(), RelCompound::size(), RelAlgTranslator::translate(), RelAlgTranslator::translateAggregateRex(), and var_ref().

Referenced by RelAlgExecutor::createAggregateWorkUnit(), and RelAlgExecutor::createCompoundWorkUnit().

1917  {
1918  std::vector<Analyzer::Expr*> target_exprs;
1919  for (size_t i = 0; i < compound->size(); ++i) {
1920  const auto target_rex = compound->getTargetExpr(i);
1921  const auto target_rex_agg = dynamic_cast<const RexAgg*>(target_rex);
1922  std::shared_ptr<Analyzer::Expr> target_expr;
1923  if (target_rex_agg) {
1924  target_expr =
1925  RelAlgTranslator::translateAggregateRex(target_rex_agg, scalar_sources);
1926  conditionally_change_arg_to_int_type(i, target_expr, target_exprs_type_infos);
1927  } else {
1928  const auto target_rex_scalar = dynamic_cast<const RexScalar*>(target_rex);
1929  const auto target_rex_ref = dynamic_cast<const RexRef*>(target_rex_scalar);
1930  if (target_rex_ref) {
1931  const auto ref_idx = target_rex_ref->getIndex();
1932  CHECK_GE(ref_idx, size_t(1));
1933  CHECK_LE(ref_idx, groupby_exprs.size());
1934  const auto groupby_expr = *std::next(groupby_exprs.begin(), ref_idx - 1);
1935  target_expr = var_ref(groupby_expr.get(), Analyzer::Var::kGROUPBY, ref_idx);
1936  } else {
1937  target_expr =
1938  rewrite_array_elements(translator.translate(target_rex_scalar).get());
1939  auto rewritten_expr = rewrite_expr(target_expr.get());
1940  target_expr = fold_expr(rewritten_expr.get());
1941  if (executor_type == ExecutorType::Native) {
1942  try {
1943  target_expr = set_transient_dict(target_expr);
1944  } catch (...) {
1945  // noop
1946  }
1947  } else {
1948  target_expr = cast_dict_to_none(target_expr);
1949  }
1950  }
1951  target_exprs_type_infos.emplace(i, target_expr->get_type_info());
1952  }
1953  CHECK(target_expr);
1954  target_exprs_owned.push_back(target_expr);
1955  target_exprs.push_back(target_expr.get());
1956  }
1957  return target_exprs;
1958 }
Analyzer::ExpressionPtr rewrite_array_elements(Analyzer::Expr const *expr)
const Rex * getTargetExpr(const size_t i) const
Definition: RelAlgDag.h:1852
size_t getIndex() const
Definition: RelAlgDag.h:752
size_t size() const override
Definition: RelAlgDag.h:1844
std::shared_ptr< Analyzer::Var > var_ref(const Analyzer::Expr *expr, const Analyzer::Var::WhichRow which_row, const int varno)
Definition: Analyzer.h:2999
#define CHECK_GE(x, y)
Definition: Logger.h:306
std::shared_ptr< Analyzer::Expr > set_transient_dict(const std::shared_ptr< Analyzer::Expr > expr)
Analyzer::ExpressionPtr rewrite_expr(const Analyzer::Expr *expr)
std::shared_ptr< Analyzer::Expr > cast_dict_to_none(const std::shared_ptr< Analyzer::Expr > &input)
void conditionally_change_arg_to_int_type(size_t target_expr_idx, std::shared_ptr< Analyzer::Expr > &target_expr, std::unordered_map< size_t, SQLTypeInfo > &target_exprs_type_infos)
std::shared_ptr< Analyzer::Expr > translate(const RexScalar *rex) const
#define CHECK_LE(x, y)
Definition: Logger.h:304
#define CHECK(condition)
Definition: Logger.h:291
std::shared_ptr< Analyzer::Expr > fold_expr(const Analyzer::Expr *expr)
static std::shared_ptr< Analyzer::Expr > translateAggregateRex(const RexAgg *rex, const std::vector< std::shared_ptr< Analyzer::Expr >> &scalar_sources)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::vector<Analyzer::Expr*> anonymous_namespace{RelAlgExecutor.cpp}::translate_targets ( std::vector< std::shared_ptr< Analyzer::Expr >> &  target_exprs_owned,
std::unordered_map< size_t, SQLTypeInfo > &  target_exprs_type_infos,
const std::vector< std::shared_ptr< Analyzer::Expr >> &  scalar_sources,
const std::list< std::shared_ptr< Analyzer::Expr >> &  groupby_exprs,
const RelAggregate aggregate,
const RelAlgTranslator translator 
)

Definition at line 1960 of file RelAlgExecutor.cpp.

References CHECK, fold_expr(), RelAggregate::getAggExprs(), Analyzer::Var::kGROUPBY, RelAlgTranslator::translateAggregateRex(), and var_ref().

1966  {
1967  std::vector<Analyzer::Expr*> target_exprs;
1968  size_t group_key_idx = 1;
1969  for (const auto& groupby_expr : groupby_exprs) {
1970  auto target_expr =
1971  var_ref(groupby_expr.get(), Analyzer::Var::kGROUPBY, group_key_idx++);
1972  target_exprs_owned.push_back(target_expr);
1973  target_exprs.push_back(target_expr.get());
1974  }
1975 
1976  for (const auto& target_rex_agg : aggregate->getAggExprs()) {
1977  auto target_expr =
1978  RelAlgTranslator::translateAggregateRex(target_rex_agg.get(), scalar_sources);
1979  CHECK(target_expr);
1980  target_expr = fold_expr(target_expr.get());
1981  target_exprs_owned.push_back(target_expr);
1982  target_exprs.push_back(target_expr.get());
1983  }
1984  return target_exprs;
1985 }
std::shared_ptr< Analyzer::Var > var_ref(const Analyzer::Expr *expr, const Analyzer::Var::WhichRow which_row, const int varno)
Definition: Analyzer.h:2999
const std::vector< std::unique_ptr< const RexAgg > > & getAggExprs() const
Definition: RelAlgDag.h:1365
#define CHECK(condition)
Definition: Logger.h:291
std::shared_ptr< Analyzer::Expr > fold_expr(const Analyzer::Expr *expr)
static std::shared_ptr< Analyzer::Expr > translateAggregateRex(const RexAgg *rex, const std::vector< std::shared_ptr< Analyzer::Expr >> &scalar_sources)

+ Here is the call graph for this function: