OmniSciDB  72c90bc290
 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  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)
 
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)
 
void handle_query_hint (RegisteredQueryHint const &query_hints, ExecutionOptions &eo, CompilationOptions &co)
 
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_limit_value (std::optional< size_t > limit)
 
size_t get_scan_limit (const RelAlgNode *ra, std::optional< size_t > limit)
 
bool first_oe_is_desc (const std::list< Analyzer::OrderEntry > &order_entries)
 
bool is_none_encoded_text (TargetMetaInfo const &target_meta_info)
 
std::pair< size_t,
shared::TableKey
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)
 
std::string get_table_name_from_table_key (shared::TableKey const &table_key)
 
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 4688 of file RelAlgExecutor.cpp.

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

Referenced by reverse_logical_distribution().

4690  {
4691  CHECK(!factors.empty());
4692  auto acc = factors.front();
4693  for (size_t i = 1; i < factors.size(); ++i) {
4694  acc = Parser::OperExpr::normalize(sql_op, kONE, acc, factors[i]);
4695  }
4696  return acc;
4697 }
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:379
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:

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

Definition at line 3481 of file RelAlgExecutor.cpp.

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

Referenced by RelAlgExecutor::executeWorkUnit().

3483  {
3484  if (!is_projection(ra_exe_unit)) {
3485  return false;
3486  }
3487  if (render_info && render_info->isInSitu()) {
3488  return false;
3489  }
3490  if (!ra_exe_unit.sort_info.order_entries.empty()) {
3491  // disable output columnar when we have top-sort node query
3492  return false;
3493  }
3494  bool flatbuffer_is_used = false;
3495  for (const auto& target_expr : ra_exe_unit.target_exprs) {
3496  const auto ti = target_expr->get_type_info();
3497  // Usage of FlatBuffer memory layout implies columnar-only support.
3498  if (ti.usesFlatBuffer()) {
3499  flatbuffer_is_used = true;
3500  continue;
3501  }
3502  // We don't currently support varlen columnar projections, so
3503  // return false if we find one
3504  // TODO: notice that currently ti.supportsFlatBuffer() == ti.is_varlen()
3505  if (ti.is_varlen()) {
3506  return false;
3507  }
3508  }
3509  if (auto top_project = dynamic_cast<const RelProject*>(body)) {
3510  if (top_project->isRowwiseOutputForced()) {
3511  if (flatbuffer_is_used) {
3512  throw std::runtime_error(
3513  "Cannot force rowwise output when FlatBuffer layout is used.");
3514  }
3515  return false;
3516  }
3517  }
3518  return true;
3519 }
std::vector< Analyzer::Expr * > target_exprs
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 3638 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().

3640  {
3642  !eo.output_columnar_hint && ra_exe_unit.sort_info.order_entries.empty();
3643 }
std::list< Analyzer::OrderEntry > order_entries
ExecutorDeviceType device_type
bool g_enable_bump_allocator
Definition: Execute.cpp:128

+ 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 1739 of file RelAlgExecutor.cpp.

References kENCODING_DICT, and kTEXT.

Referenced by translate_scalar_sources(), and translate_targets().

1740  {
1741  const auto& input_ti = input->get_type_info();
1742  if (input_ti.is_string() && input_ti.get_compression() == kENCODING_DICT) {
1743  return input->add_cast(SQLTypeInfo(kTEXT, input_ti.get_notnull()));
1744  }
1745  return input;
1746 }
Definition: sqltypes.h:79

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

450  {
451  if (!g_enable_watchdog) {
452  return;
453  }
454  auto const tuples_upper_bound =
455  std::accumulate(query_infos.cbegin(),
456  query_infos.cend(),
457  size_t(0),
458  [](auto max, auto const& query_info) {
459  return std::max(max, query_info.info.getNumTuples());
460  });
461  if (tuples_upper_bound <= g_watchdog_none_encoded_string_translation_limit) {
462  return;
463  }
464 
465  const auto& text_cast_counts = get_text_cast_counts(ra_exe_unit);
466  const bool has_text_casts =
467  text_cast_counts.text_decoding_casts + text_cast_counts.text_encoding_casts > 0UL;
468 
469  if (!has_text_casts) {
470  return;
471  }
472  std::ostringstream oss;
473  oss << "Query requires one or more casts between none-encoded and dictionary-encoded "
474  << "strings, and the estimated table size (" << tuples_upper_bound << " rows) "
475  << "exceeds the configured watchdog none-encoded string translation limit of "
477  throw std::runtime_error(oss.str());
478 }
TextEncodingCastCounts get_text_cast_counts(const RelAlgExecutionUnit &ra_exe_unit)
size_t g_watchdog_none_encoded_string_translation_limit
Definition: Execute.cpp:82
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 795 of file RelAlgExecutor.cpp.

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

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

795  {
796  CHECK_EQ(size_t(1), sort->inputCount());
797  const auto source = sort->getInput(0);
798  if (dynamic_cast<const RelSort*>(source)) {
799  throw std::runtime_error("Sort node not supported as input to another sort");
800  }
801 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
const RelAlgNode * getInput(const size_t idx) const
Definition: RelAlgDag.h:877
const size_t inputCount() const
Definition: RelAlgDag.h:875

+ 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 1596 of file RelAlgExecutor.cpp.

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

Referenced by get_input_desc_impl().

1601  {
1602  VLOG(3) << "ra_node=" << ra_node->toString(RelRexToStringConfig::defaults())
1603  << " input_col_descs_unique.size()=" << input_col_descs_unique.size()
1604  << " source_used_inputs.size()=" << source_used_inputs.size();
1605  for (const auto used_input : source_used_inputs) {
1606  const auto input_ra = used_input->getSourceNode();
1607  const auto table_key = table_key_from_ra(input_ra);
1608  auto col_id = used_input->getIndex();
1609  auto it = input_to_nest_level.find(input_ra);
1610  if (it != input_to_nest_level.end()) {
1611  const int nest_level = it->second;
1612  if (auto rel_scan = dynamic_cast<const RelScan*>(input_ra)) {
1613  const auto& catalog = rel_scan->getCatalog();
1614  col_id = catalog.getColumnIdBySpi(table_key.table_id, col_id + 1);
1615  }
1616  input_col_descs_unique.insert(std::make_shared<const InputColDescriptor>(
1617  col_id, table_key.table_id, table_key.db_id, nest_level));
1618  } else if (!dynamic_cast<const RelLogicalUnion*>(ra_node)) {
1619  throw std::runtime_error("Bushy joins not supported");
1620  }
1621  }
1622 }
shared::TableKey table_key_from_ra(const RelAlgNode *ra_node)
virtual std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const =0
static RelRexToStringConfig defaults()
Definition: RelAlgDag.h:78
#define VLOG(n)
Definition: Logger.h:388

+ 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 3538 of file RelAlgExecutor.cpp.

References g_preflight_count_query_threshold, is_projection(), RegisteredQueryHint::isHintRegistered(), kPreflightCountQueryThreshold, RegisteredQueryHint::preflight_count_query_threshold, RelAlgExecutionUnit::query_hint, RelAlgExecutionUnit::scan_limit, RelAlgExecutionUnit::target_exprs, and VLOG.

Referenced by RelAlgExecutor::executeWorkUnit().

3538  {
3539  for (const auto target_expr : ra_exe_unit.target_exprs) {
3540  if (dynamic_cast<const Analyzer::AggExpr*>(target_expr)) {
3541  return false;
3542  }
3543  }
3544  size_t preflight_count_query_threshold = g_preflight_count_query_threshold;
3546  preflight_count_query_threshold =
3548  VLOG(1) << "Set the pre-flight count query's threshold as "
3549  << preflight_count_query_threshold << " by a query hint";
3550  }
3551  if (is_projection(ra_exe_unit) &&
3552  (!ra_exe_unit.scan_limit ||
3553  ra_exe_unit.scan_limit > preflight_count_query_threshold)) {
3554  return true;
3555  }
3556  return false;
3557 }
std::vector< Analyzer::Expr * > target_exprs
size_t g_preflight_count_query_threshold
Definition: Execute.cpp:84
size_t preflight_count_query_threshold
Definition: QueryHint.h:337
bool is_projection(const RelAlgExecutionUnit &ra_exe_unit)
bool isHintRegistered(const QueryHint hint) const
Definition: QueryHint.h:383
RegisteredQueryHint query_hint
#define VLOG(n)
Definition: Logger.h:388

+ Here is the call graph for this function:

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

3569  {
3570  RelAlgExecutionUnit ra_exe_unit = ra_exe_unit_in;
3571  for (size_t i = 0; i < ra_exe_unit.target_exprs.size(); ++i) {
3572  const auto target_expr = ra_exe_unit.target_exprs[i];
3573  const auto agg_info = get_target_info(target_expr, g_bigint_count);
3574  if (agg_info.agg_kind != kAPPROX_COUNT_DISTINCT) {
3575  continue;
3576  }
3577  CHECK(dynamic_cast<const Analyzer::AggExpr*>(target_expr));
3578  const auto arg = static_cast<Analyzer::AggExpr*>(target_expr)->get_own_arg();
3579  CHECK(arg);
3580  const auto& arg_ti = arg->get_type_info();
3581  // Avoid calling getExpressionRange for variable length types (string and array),
3582  // it'd trigger an assertion since that API expects to be called only for types
3583  // for which the notion of range is well-defined. A bit of a kludge, but the
3584  // logic to reject these types anyway is at lower levels in the stack and not
3585  // really worth pulling into a separate function for now.
3586  if (!(arg_ti.is_number() || arg_ti.is_boolean() || arg_ti.is_time() ||
3587  (arg_ti.is_string() && arg_ti.get_compression() == kENCODING_DICT))) {
3588  continue;
3589  }
3590  const auto arg_range = getExpressionRange(arg.get(), table_infos, executor);
3591  if (arg_range.getType() != ExpressionRangeType::Integer) {
3592  continue;
3593  }
3594  // When running distributed, the threshold for using the precise implementation
3595  // must be consistent across all leaves, otherwise we could have a mix of precise
3596  // and approximate bitmaps and we cannot aggregate them.
3597  const auto device_type = g_cluster ? ExecutorDeviceType::GPU : device_type_in;
3598  const auto bitmap_sz_bits = arg_range.getIntMax() - arg_range.getIntMin() + 1;
3599  const auto sub_bitmap_count =
3600  get_count_distinct_sub_bitmap_count(bitmap_sz_bits, ra_exe_unit, device_type);
3601  int64_t approx_bitmap_sz_bits{0};
3602  const auto error_rate_expr = static_cast<Analyzer::AggExpr*>(target_expr)->get_arg1();
3603  if (error_rate_expr) {
3604  CHECK(error_rate_expr->get_type_info().get_type() == kINT);
3605  auto const error_rate =
3606  dynamic_cast<Analyzer::Constant const*>(error_rate_expr.get());
3607  CHECK(error_rate);
3608  CHECK_GE(error_rate->get_constval().intval, 1);
3609  approx_bitmap_sz_bits = hll_size_for_rate(error_rate->get_constval().intval);
3610  } else {
3611  approx_bitmap_sz_bits = g_hll_precision_bits;
3612  }
3613  CountDistinctDescriptor approx_count_distinct_desc{CountDistinctImplType::Bitmap,
3614  arg_range.getIntMin(),
3615  0,
3616  approx_bitmap_sz_bits,
3617  true,
3618  device_type,
3619  sub_bitmap_count};
3620  CountDistinctDescriptor precise_count_distinct_desc{CountDistinctImplType::Bitmap,
3621  arg_range.getIntMin(),
3622  0,
3623  bitmap_sz_bits,
3624  false,
3625  device_type,
3626  sub_bitmap_count};
3627  if (approx_count_distinct_desc.bitmapPaddedSizeBytes() >=
3628  precise_count_distinct_desc.bitmapPaddedSizeBytes()) {
3629  auto precise_count_distinct = makeExpr<Analyzer::AggExpr>(
3630  get_agg_type(kCOUNT, arg.get()), kCOUNT, arg, true, nullptr);
3631  target_exprs_owned.push_back(precise_count_distinct);
3632  ra_exe_unit.target_exprs[i] = precise_count_distinct.get();
3633  }
3634  }
3635  return ra_exe_unit;
3636 }
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:92
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:72

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

4486  {
4487  if (g_cluster) {
4488  // Disable table reordering in distributed mode. The aggregator does not have enough
4489  // information to break ties
4490  return {};
4491  }
4492  if (node->isUpdateViaSelect() || node->isDeleteViaSelect()) {
4493  // Do not reorder tables for UPDATE and DELETE queries, since the outer table always
4494  // has to be the physical table.
4495  return {};
4496  }
4497  for (const auto& table_info : query_infos) {
4498  if (table_info.table_key.table_id < 0) {
4499  continue;
4500  }
4501  const auto td = Catalog_Namespace::get_metadata_for_table(table_info.table_key);
4502  CHECK(td);
4503  if (table_is_replicated(td)) {
4504  return {};
4505  }
4506  }
4507  const auto input_permutation =
4508  get_node_input_permutation(left_deep_join_quals, query_infos, executor);
4509  input_to_nest_level = get_input_nest_levels(node, input_permutation);
4510  std::tie(input_descs, input_col_descs, std::ignore) =
4511  get_input_desc(node, input_to_nest_level, input_permutation);
4512  return input_permutation;
4513 }
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 3559 of file RelAlgExecutor.cpp.

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

Referenced by RelAlgExecutor::executeWorkUnit().

3559  {
3560  return !(ra_exe_unit.quals.empty() && ra_exe_unit.join_quals.empty() &&
3561  ra_exe_unit.simple_quals.empty());
3562 }
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 3214 of file RelAlgExecutor.cpp.

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

3214  {
3215  return !order_entries.empty() && order_entries.front().is_desc;
3216 }

+ 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 4394 of file RelAlgExecutor.cpp.

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

Referenced by get_bitwise_equals_conjunction().

4394  {
4395  const auto condition = dynamic_cast<const RexOperator*>(scalar);
4396  if (!condition || condition->getOperator() != kOR || condition->size() != 2) {
4397  return nullptr;
4398  }
4399  const auto equi_join_condition =
4400  dynamic_cast<const RexOperator*>(condition->getOperand(0));
4401  if (!equi_join_condition || equi_join_condition->getOperator() != kEQ) {
4402  return nullptr;
4403  }
4404  const auto both_are_null_condition =
4405  dynamic_cast<const RexOperator*>(condition->getOperand(1));
4406  if (!both_are_null_condition || both_are_null_condition->getOperator() != kAND ||
4407  both_are_null_condition->size() != 2) {
4408  return nullptr;
4409  }
4410  const auto lhs_is_null =
4411  dynamic_cast<const RexOperator*>(both_are_null_condition->getOperand(0));
4412  const auto rhs_is_null =
4413  dynamic_cast<const RexOperator*>(both_are_null_condition->getOperand(1));
4414  if (!lhs_is_null || !rhs_is_null || lhs_is_null->getOperator() != kISNULL ||
4415  rhs_is_null->getOperator() != kISNULL) {
4416  return nullptr;
4417  }
4418  CHECK_EQ(size_t(1), lhs_is_null->size());
4419  CHECK_EQ(size_t(1), rhs_is_null->size());
4420  CHECK_EQ(size_t(2), equi_join_condition->size());
4421  const auto eq_lhs = dynamic_cast<const RexInput*>(equi_join_condition->getOperand(0));
4422  const auto eq_rhs = dynamic_cast<const RexInput*>(equi_join_condition->getOperand(1));
4423  const auto is_null_lhs = dynamic_cast<const RexInput*>(lhs_is_null->getOperand(0));
4424  const auto is_null_rhs = dynamic_cast<const RexInput*>(rhs_is_null->getOperand(0));
4425  if (!eq_lhs || !eq_rhs || !is_null_lhs || !is_null_rhs) {
4426  return nullptr;
4427  }
4428  std::vector<std::unique_ptr<const RexScalar>> eq_operands;
4429  if (*eq_lhs == *is_null_lhs && *eq_rhs == *is_null_rhs) {
4430  RexDeepCopyVisitor deep_copy_visitor;
4431  auto lhs_op_copy = deep_copy_visitor.visit(equi_join_condition->getOperand(0));
4432  auto rhs_op_copy = deep_copy_visitor.visit(equi_join_condition->getOperand(1));
4433  eq_operands.emplace_back(lhs_op_copy.release());
4434  eq_operands.emplace_back(rhs_op_copy.release());
4435  return boost::make_unique<const RexOperator>(
4436  kBW_EQ, eq_operands, equi_join_condition->getType());
4437  }
4438  return nullptr;
4439 }
#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 4441 of file RelAlgExecutor.cpp.

References CHECK_GE, get_bitwise_equals(), and kAND.

Referenced by RelAlgExecutor::makeJoinQuals().

4442  {
4443  const auto condition = dynamic_cast<const RexOperator*>(scalar);
4444  if (condition && condition->getOperator() == kAND) {
4445  CHECK_GE(condition->size(), size_t(2));
4446  auto acc = get_bitwise_equals(condition->getOperand(0));
4447  if (!acc) {
4448  return nullptr;
4449  }
4450  for (size_t i = 1; i < condition->size(); ++i) {
4451  std::vector<std::unique_ptr<const RexScalar>> and_operands;
4452  and_operands.emplace_back(std::move(acc));
4453  and_operands.emplace_back(get_bitwise_equals_conjunction(condition->getOperand(i)));
4454  acc =
4455  boost::make_unique<const RexOperator>(kAND, and_operands, condition->getType());
4456  }
4457  return acc;
4458  }
4459  return get_bitwise_equals(scalar);
4460 }
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 1391 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().

1391  {
1392  if (auto table_func = dynamic_cast<const RelTableFunction*>(ra_node)) {
1393  return table_func;
1394  }
1395  if (auto join = dynamic_cast<const RelJoin*>(ra_node)) {
1396  CHECK_EQ(size_t(2), join->inputCount());
1397  return join;
1398  }
1399  if (!dynamic_cast<const RelLogicalUnion*>(ra_node)) {
1400  CHECK_EQ(size_t(1), ra_node->inputCount());
1401  }
1402  auto only_src = ra_node->getInput(0);
1403  const bool is_join = dynamic_cast<const RelJoin*>(only_src) ||
1404  dynamic_cast<const RelLeftDeepInnerJoin*>(only_src);
1405  return is_join ? only_src : ra_node;
1406 }
#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:877
const size_t inputCount() const
Definition: RelAlgDag.h:875

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

1680  {
1681  std::unordered_set<const RexInput*> used_inputs;
1682  std::vector<std::shared_ptr<RexInput>> used_inputs_owned;
1683  std::tie(used_inputs, used_inputs_owned) = get_used_inputs(ra_node);
1684  VLOG(3) << "used_inputs.size() = " << used_inputs.size();
1685  auto input_desc_pair =
1686  get_input_desc_impl(ra_node, used_inputs, input_to_nest_level, input_permutation);
1687  return std::make_tuple(
1688  input_desc_pair.first, input_desc_pair.second, used_inputs_owned);
1689 }
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:388

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

1630  {
1631  std::vector<InputDescriptor> input_descs;
1632  const auto data_sink_node = get_data_sink(ra_node);
1633  for (size_t input_idx = 0; input_idx < data_sink_node->inputCount(); ++input_idx) {
1634  const auto input_node_idx =
1635  input_permutation.empty() ? input_idx : input_permutation[input_idx];
1636  auto input_ra = data_sink_node->getInput(input_node_idx);
1637  const auto table_key = table_key_from_ra(input_ra);
1638  input_descs.emplace_back(table_key.db_id, table_key.table_id, input_idx);
1639  }
1640  std::unordered_set<std::shared_ptr<const InputColDescriptor>> input_col_descs_unique;
1641  collect_used_input_desc(input_descs,
1642  input_col_descs_unique, // modified
1643  ra_node,
1644  used_inputs,
1645  input_to_nest_level);
1646  std::unordered_set<const RexInput*> join_source_used_inputs;
1647  std::vector<std::shared_ptr<RexInput>> join_source_used_inputs_owned;
1648  std::tie(join_source_used_inputs, join_source_used_inputs_owned) =
1649  get_join_source_used_inputs(ra_node);
1650  collect_used_input_desc(input_descs,
1651  input_col_descs_unique, // modified
1652  ra_node,
1653  join_source_used_inputs,
1654  input_to_nest_level);
1655  std::vector<std::shared_ptr<const InputColDescriptor>> input_col_descs(
1656  input_col_descs_unique.begin(), input_col_descs_unique.end());
1657 
1658  std::sort(input_col_descs.begin(),
1659  input_col_descs.end(),
1660  [](std::shared_ptr<const InputColDescriptor> const& lhs,
1661  std::shared_ptr<const InputColDescriptor> const& rhs) {
1662  return std::make_tuple(lhs->getScanDesc().getNestLevel(),
1663  lhs->getColId(),
1664  lhs->getScanDesc().getTableKey()) <
1665  std::make_tuple(rhs->getScanDesc().getNestLevel(),
1666  rhs->getColId(),
1667  rhs->getScanDesc().getTableKey());
1668  });
1669  return {input_descs,
1670  std::list<std::shared_ptr<const InputColDescriptor>>(input_col_descs.begin(),
1671  input_col_descs.end())};
1672 }
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 1529 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().

1531  {
1532  const auto data_sink_node = get_data_sink(ra_node);
1533  std::unordered_map<const RelAlgNode*, int> input_to_nest_level;
1534  for (size_t input_idx = 0; input_idx < data_sink_node->inputCount(); ++input_idx) {
1535  const auto input_node_idx =
1536  input_permutation.empty() ? input_idx : input_permutation[input_idx];
1537  const auto input_ra = data_sink_node->getInput(input_node_idx);
1538  // Having a non-zero mapped value (input_idx) results in the query being interpretted
1539  // as a JOIN within CodeGenerator::codegenColVar() due to rte_idx being set to the
1540  // mapped value (input_idx) which originates here. This would be incorrect for UNION.
1541  size_t const idx = dynamic_cast<const RelLogicalUnion*>(ra_node) ? 0 : input_idx;
1542  const auto it_ok = input_to_nest_level.emplace(input_ra, idx);
1543  CHECK(it_ok.second);
1544  LOG_IF(DEBUG1, !input_permutation.empty())
1545  << "Assigned input " << input_ra->toString(RelRexToStringConfig::defaults())
1546  << " to nest level " << input_idx;
1547  }
1548  return input_to_nest_level;
1549 }
#define LOG_IF(severity, condition)
Definition: Logger.h:384
static RelRexToStringConfig defaults()
Definition: RelAlgDag.h:78
#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 5385 of file RelAlgExecutor.cpp.

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

Referenced by RelAlgExecutor::createFilterWorkUnit().

5388  {
5389  std::vector<TargetMetaInfo> in_metainfo;
5390  std::vector<std::shared_ptr<Analyzer::Expr>> exprs_owned;
5391  const auto data_sink_node = get_data_sink(filter);
5392  auto input_it = inputs_owned.begin();
5393  for (size_t nest_level = 0; nest_level < data_sink_node->inputCount(); ++nest_level) {
5394  const auto source = data_sink_node->getInput(nest_level);
5395  const auto scan_source = dynamic_cast<const RelScan*>(source);
5396  if (scan_source) {
5397  CHECK(source->getOutputMetainfo().empty());
5398  std::vector<std::shared_ptr<Analyzer::Expr>> scalar_sources_owned;
5399  for (size_t i = 0; i < scan_source->size(); ++i, ++input_it) {
5400  scalar_sources_owned.push_back(translator.translate(input_it->get()));
5401  }
5402  const auto source_metadata =
5403  get_targets_meta(scan_source, get_raw_pointers(scalar_sources_owned));
5404  in_metainfo.insert(
5405  in_metainfo.end(), source_metadata.begin(), source_metadata.end());
5406  exprs_owned.insert(
5407  exprs_owned.end(), scalar_sources_owned.begin(), scalar_sources_owned.end());
5408  } else {
5409  const auto& source_metadata = source->getOutputMetainfo();
5410  input_it += source_metadata.size();
5411  in_metainfo.insert(
5412  in_metainfo.end(), source_metadata.begin(), source_metadata.end());
5413  const auto scalar_sources_owned = synthesize_inputs(
5414  data_sink_node, nest_level, source_metadata, input_to_nest_level);
5415  exprs_owned.insert(
5416  exprs_owned.end(), scalar_sources_owned.begin(), scalar_sources_owned.end());
5417  }
5418  }
5419  return std::make_pair(in_metainfo, exprs_owned);
5420 }
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 1552 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().

1552  {
1553  const auto data_sink_node = get_data_sink(ra_node);
1554  if (auto join = dynamic_cast<const RelJoin*>(data_sink_node)) {
1555  CHECK_EQ(join->inputCount(), 2u);
1556  const auto condition = join->getCondition();
1557  RexUsedInputsVisitor visitor;
1558  auto condition_inputs = visitor.visit(condition);
1559  std::vector<std::shared_ptr<RexInput>> condition_inputs_owned(
1560  visitor.get_inputs_owned());
1561  return std::make_pair(condition_inputs, condition_inputs_owned);
1562  }
1563 
1564  if (auto left_deep_join = dynamic_cast<const RelLeftDeepInnerJoin*>(data_sink_node)) {
1565  CHECK_GE(left_deep_join->inputCount(), 2u);
1566  const auto condition = left_deep_join->getInnerCondition();
1567  RexUsedInputsVisitor visitor;
1568  auto result = visitor.visit(condition);
1569  for (size_t nesting_level = 1; nesting_level <= left_deep_join->inputCount() - 1;
1570  ++nesting_level) {
1571  const auto outer_condition = left_deep_join->getOuterCondition(nesting_level);
1572  if (outer_condition) {
1573  const auto outer_result = visitor.visit(outer_condition);
1574  result.insert(outer_result.begin(), outer_result.end());
1575  }
1576  }
1577  std::vector<std::shared_ptr<RexInput>> used_inputs_owned(visitor.get_inputs_owned());
1578  return std::make_pair(result, used_inputs_owned);
1579  }
1580 
1581  if (dynamic_cast<const RelLogicalUnion*>(ra_node)) {
1582  CHECK_GT(ra_node->inputCount(), 1u)
1584  } else if (dynamic_cast<const RelTableFunction*>(ra_node)) {
1585  // no-op
1586  CHECK_GE(ra_node->inputCount(), 0u)
1588  } else {
1589  CHECK_EQ(ra_node->inputCount(), 1u)
1591  }
1592  return std::make_pair(std::unordered_set<const RexInput*>{},
1593  std::vector<std::shared_ptr<RexInput>>{});
1594 }
#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=RelRexToStringConfig::defaults()) const =0
static RelRexToStringConfig defaults()
Definition: RelAlgDag.h:78
const size_t inputCount() const
Definition: RelAlgDag.h:875
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 4382 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().

4382  {
4383  auto sink = get_data_sink(ra);
4384  if (auto join = dynamic_cast<const RelJoin*>(sink)) {
4385  return join->getJoinType();
4386  }
4387  if (dynamic_cast<const RelLeftDeepInnerJoin*>(sink)) {
4388  return JoinType::INNER;
4389  }
4390 
4391  return JoinType::INVALID;
4392 }
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 4515 of file RelAlgExecutor.cpp.

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

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

4516  {
4517  std::vector<size_t> input_sizes;
4518  for (size_t i = 0; i < left_deep_join->inputCount(); ++i) {
4519  const auto inputs = get_node_output(left_deep_join->getInput(i));
4520  input_sizes.push_back(inputs.size());
4521  }
4522  return input_sizes;
4523 }
const RelAlgNode * getInput(const size_t idx) const
Definition: RelAlgDag.h:877
const size_t inputCount() const
Definition: RelAlgDag.h:875
RANodeOutput get_node_output(const RelAlgNode *ra_node)
Definition: RelAlgDag.cpp:371

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

size_t anonymous_namespace{RelAlgExecutor.cpp}::get_limit_value ( std::optional< size_t >  limit)

Definition at line 3201 of file RelAlgExecutor.cpp.

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

3201  {
3202  return limit ? *limit : 0;
3203 }

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

1966  {
1967  if (is_count_distinct(expr)) {
1968  return SQLTypeInfo(kBIGINT, true);
1969  } else if (is_agg(expr)) {
1971  }
1972  return get_logical_type_info(expr->get_type_info());
1973 }
bool is_agg(const Analyzer::Expr *expr)
SQLTypeInfo get_nullable_logical_type_info(const SQLTypeInfo &type_info)
Definition: sqltypes.h:1488
SQLTypeInfo get_logical_type_info(const SQLTypeInfo &type_info)
Definition: sqltypes.h:1470
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::unordered_set<PhysicalInput> anonymous_namespace{RelAlgExecutor.cpp}::get_physical_inputs_with_spi_col_id ( const RelAlgNode ra)

Definition at line 76 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().

77  {
78  const auto phys_inputs = get_physical_inputs(ra);
79  std::unordered_set<PhysicalInput> phys_inputs2;
80  for (auto& phi : phys_inputs) {
81  const auto catalog = Catalog_Namespace::SysCatalog::instance().getCatalog(phi.db_id);
82  CHECK(catalog);
83  phys_inputs2.insert(PhysicalInput{
84  catalog->getColumnIdBySpi(phi.table_id, phi.col_id), phi.table_id, phi.db_id});
85  }
86  return phys_inputs2;
87 }
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 4863 of file RelAlgExecutor.cpp.

References shared::transform().

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

4864  {
4865  std::vector<Analyzer::Expr*> output(input.size());
4866  auto const raw_ptr = [](auto& shared_ptr) { return shared_ptr.get(); };
4867  std::transform(input.cbegin(), input.cend(), output.begin(), raw_ptr);
4868  return output;
4869 }
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 1691 of file RelAlgExecutor.cpp.

References RelCompound::getScalarSourcesSize().

Referenced by translate_scalar_sources(), and translate_scalar_sources_for_update().

1691  {
1692  return compound->getScalarSourcesSize();
1693 }
const size_t getScalarSourcesSize() const
Definition: RelAlgDag.h:2110

+ 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 1695 of file RelAlgExecutor.cpp.

References RelProject::size().

1695  {
1696  return project->size();
1697 }
size_t size() const override
Definition: RelAlgDag.h:1320

+ 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 1699 of file RelAlgExecutor.cpp.

References RelTableFunction::getTableFuncInputsSize().

1699  {
1700  return table_func->getTableFuncInputsSize();
1701 }
size_t getTableFuncInputsSize() const
Definition: RelAlgDag.h:2560

+ Here is the call graph for this function:

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

Definition at line 3205 of file RelAlgExecutor.cpp.

References get_limit_value().

Referenced by RelAlgExecutor::createSortInputWorkUnit().

3205  {
3206  const auto aggregate = dynamic_cast<const RelAggregate*>(ra);
3207  if (aggregate) {
3208  return 0;
3209  }
3210  const auto compound = dynamic_cast<const RelCompound*>(ra);
3211  return (compound && compound->isAggregate()) ? 0 : get_limit_value(limit);
3212 }
size_t get_limit_value(std::optional< size_t > limit)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::string anonymous_namespace{RelAlgExecutor.cpp}::get_table_name_from_table_key ( shared::TableKey const &  table_key)

Definition at line 4036 of file RelAlgExecutor.cpp.

References CHECK, shared::TableKey::db_id, Catalog_Namespace::SysCatalog::getCatalog(), Catalog_Namespace::SysCatalog::instance(), and shared::TableKey::table_id.

Referenced by RelAlgExecutor::getFilteredCountAll().

4036  {
4037  std::string table_name{""};
4038  if (table_key.db_id > 0) {
4039  auto catalog = Catalog_Namespace::SysCatalog::instance().getCatalog(table_key.db_id);
4040  CHECK(catalog);
4041  auto td = catalog->getMetadataForTable(table_key.table_id);
4042  CHECK(td);
4043  table_name = td->tableName;
4044  }
4045  return table_name;
4046 }
static SysCatalog & instance()
Definition: SysCatalog.h:343
std::shared_ptr< Catalog > getCatalog(const std::string &dbName)
#define CHECK(condition)
Definition: Logger.h:291

+ Here is the call graph for this function:

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

1978  {
1979  std::vector<TargetMetaInfo> targets_meta;
1980  CHECK_EQ(ra_node->size(), target_exprs.size());
1981  for (size_t i = 0; i < ra_node->size(); ++i) {
1982  CHECK(target_exprs[i]);
1983  // TODO(alex): remove the count distinct type fixup.
1984  auto ti = get_logical_type_for_expr(target_exprs[i]);
1985  targets_meta.emplace_back(
1986  ra_node->getFieldName(i), ti, target_exprs[i]->get_type_info());
1987  }
1988  return targets_meta;
1989 }
#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 1992 of file RelAlgExecutor.cpp.

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

1994  {
1995  RelAlgNode const* input0 = filter->getInput(0);
1996  if (auto const* input = dynamic_cast<RelCompound const*>(input0)) {
1997  return get_targets_meta(input, target_exprs);
1998  } else if (auto const* input = dynamic_cast<RelProject const*>(input0)) {
1999  return get_targets_meta(input, target_exprs);
2000  } else if (auto const* input = dynamic_cast<RelLogicalUnion const*>(input0)) {
2001  return get_targets_meta(input, target_exprs);
2002  } else if (auto const* input = dynamic_cast<RelAggregate const*>(input0)) {
2003  return get_targets_meta(input, target_exprs);
2004  } else if (auto const* input = dynamic_cast<RelScan const*>(input0)) {
2005  return get_targets_meta(input, target_exprs);
2006  } else if (auto const* input = dynamic_cast<RelLogicalValues const*>(input0)) {
2007  return get_targets_meta(input, target_exprs);
2008  }
2009  UNREACHABLE() << "Unhandled node type: "
2011  return {};
2012 }
#define UNREACHABLE()
Definition: Logger.h:338
const RelAlgNode * getInput(const size_t idx) const
Definition: RelAlgDag.h:877
virtual std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const =0
std::vector< TargetMetaInfo > get_targets_meta(const RA *ra_node, const std::vector< Analyzer::Expr * > &target_exprs)
static RelRexToStringConfig defaults()
Definition: RelAlgDag.h:78

+ 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 RelCompound compound)

Definition at line 1409 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().

1409  {
1410  RexUsedInputsVisitor visitor;
1411  const auto filter_expr = compound->getFilterExpr();
1412  std::unordered_set<const RexInput*> used_inputs =
1413  filter_expr ? visitor.visit(filter_expr) : std::unordered_set<const RexInput*>{};
1414  const auto sources_size = compound->getScalarSourcesSize();
1415  for (size_t i = 0; i < sources_size; ++i) {
1416  const auto source_inputs = visitor.visit(compound->getScalarSource(i));
1417  used_inputs.insert(source_inputs.begin(), source_inputs.end());
1418  }
1419  std::vector<std::shared_ptr<RexInput>> used_inputs_owned(visitor.get_inputs_owned());
1420  return std::make_pair(used_inputs, used_inputs_owned);
1421 }
const RexScalar * getFilterExpr() const
Definition: RelAlgDag.h:2096
const size_t getScalarSourcesSize() const
Definition: RelAlgDag.h:2110
const RexScalar * getScalarSource(const size_t i) const
Definition: RelAlgDag.h:2112

+ 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 1424 of file RelAlgExecutor.cpp.

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

1424  {
1425  CHECK_EQ(size_t(1), aggregate->inputCount());
1426  std::unordered_set<const RexInput*> used_inputs;
1427  std::vector<std::shared_ptr<RexInput>> used_inputs_owned;
1428  const auto source = aggregate->getInput(0);
1429  const auto& in_metainfo = source->getOutputMetainfo();
1430  const auto group_count = aggregate->getGroupByCount();
1431  CHECK_GE(in_metainfo.size(), group_count);
1432  for (size_t i = 0; i < group_count; ++i) {
1433  auto synthesized_used_input = new RexInput(source, i);
1434  used_inputs_owned.emplace_back(synthesized_used_input);
1435  used_inputs.insert(synthesized_used_input);
1436  }
1437  for (const auto& agg_expr : aggregate->getAggExprs()) {
1438  for (size_t i = 0; i < agg_expr->size(); ++i) {
1439  const auto operand_idx = agg_expr->getOperand(i);
1440  CHECK_GE(in_metainfo.size(), static_cast<size_t>(operand_idx));
1441  auto synthesized_used_input = new RexInput(source, operand_idx);
1442  used_inputs_owned.emplace_back(synthesized_used_input);
1443  used_inputs.insert(synthesized_used_input);
1444  }
1445  }
1446  return std::make_pair(used_inputs, used_inputs_owned);
1447 }
const size_t getGroupByCount() const
Definition: RelAlgDag.h:1508
#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:877
const std::vector< std::unique_ptr< const RexAgg > > & getAggExprs() const
Definition: RelAlgDag.h:1531
const size_t inputCount() const
Definition: RelAlgDag.h:875
const std::vector< TargetMetaInfo > & getOutputMetainfo() const
Definition: RelAlgDag.h:865

+ 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 1450 of file RelAlgExecutor.cpp.

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

1450  {
1451  RexUsedInputsVisitor visitor;
1452  std::unordered_set<const RexInput*> used_inputs;
1453  for (size_t i = 0; i < project->size(); ++i) {
1454  const auto proj_inputs = visitor.visit(project->getProjectAt(i));
1455  used_inputs.insert(proj_inputs.begin(), proj_inputs.end());
1456  }
1457  std::vector<std::shared_ptr<RexInput>> used_inputs_owned(visitor.get_inputs_owned());
1458  return std::make_pair(used_inputs, used_inputs_owned);
1459 }
size_t size() const override
Definition: RelAlgDag.h:1320
const RexScalar * getProjectAt(const size_t idx) const
Definition: RelAlgDag.h:1352

+ 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 1462 of file RelAlgExecutor.cpp.

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

1462  {
1463  RexUsedInputsVisitor visitor;
1464  std::unordered_set<const RexInput*> used_inputs;
1465  for (size_t i = 0; i < table_func->getTableFuncInputsSize(); ++i) {
1466  const auto table_func_inputs = visitor.visit(table_func->getTableFuncInputAt(i));
1467  used_inputs.insert(table_func_inputs.begin(), table_func_inputs.end());
1468  }
1469  std::vector<std::shared_ptr<RexInput>> used_inputs_owned(visitor.get_inputs_owned());
1470  return std::make_pair(used_inputs, used_inputs_owned);
1471 }
size_t getTableFuncInputsSize() const
Definition: RelAlgDag.h:2560
const RexScalar * getTableFuncInputAt(const size_t idx) const
Definition: RelAlgDag.h:2566

+ 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 1474 of file RelAlgExecutor.cpp.

References CHECK, and get_data_sink().

1474  {
1475  std::unordered_set<const RexInput*> used_inputs;
1476  std::vector<std::shared_ptr<RexInput>> used_inputs_owned;
1477  const auto data_sink_node = get_data_sink(filter);
1478  for (size_t nest_level = 0; nest_level < data_sink_node->inputCount(); ++nest_level) {
1479  const auto source = data_sink_node->getInput(nest_level);
1480  const auto scan_source = dynamic_cast<const RelScan*>(source);
1481  if (scan_source) {
1482  CHECK(source->getOutputMetainfo().empty());
1483  for (size_t i = 0; i < scan_source->size(); ++i) {
1484  auto synthesized_used_input = new RexInput(scan_source, i);
1485  used_inputs_owned.emplace_back(synthesized_used_input);
1486  used_inputs.insert(synthesized_used_input);
1487  }
1488  } else {
1489  const auto& partial_in_metadata = source->getOutputMetainfo();
1490  for (size_t i = 0; i < partial_in_metadata.size(); ++i) {
1491  auto synthesized_used_input = new RexInput(source, i);
1492  used_inputs_owned.emplace_back(synthesized_used_input);
1493  used_inputs.insert(synthesized_used_input);
1494  }
1495  }
1496  }
1497  return std::make_pair(used_inputs, used_inputs_owned);
1498 }
#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 1501 of file RelAlgExecutor.cpp.

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

1501  {
1502  std::unordered_set<const RexInput*> used_inputs(logical_union->inputCount());
1503  std::vector<std::shared_ptr<RexInput>> used_inputs_owned;
1504  used_inputs_owned.reserve(logical_union->inputCount());
1505  VLOG(3) << "logical_union->inputCount()=" << logical_union->inputCount();
1506  auto const n_inputs = logical_union->inputCount();
1507  for (size_t nest_level = 0; nest_level < n_inputs; ++nest_level) {
1508  auto input = logical_union->getInput(nest_level);
1509  for (size_t i = 0; i < input->size(); ++i) {
1510  used_inputs_owned.emplace_back(std::make_shared<RexInput>(input, i));
1511  used_inputs.insert(used_inputs_owned.back().get());
1512  }
1513  }
1514  return std::make_pair(std::move(used_inputs), std::move(used_inputs_owned));
1515 }
const RelAlgNode * getInput(const size_t idx) const
Definition: RelAlgDag.h:877
const size_t inputCount() const
Definition: RelAlgDag.h:875
#define VLOG(n)
Definition: Logger.h:388

+ Here is the call graph for this function:

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

Definition at line 4283 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().

4283  {
4284  // 'designated initializers' don't compile on Windows for std 17
4285  // They require /std:c++20. They been removed for the windows port.
4286  switch (error_code) {
4288  return {"ERR_DIV_BY_ZERO", "Division by zero"};
4290  return {"ERR_OUT_OF_GPU_MEM",
4291 
4292  "Query couldn't keep the entire working set of columns in GPU memory"};
4294  return {"ERR_UNSUPPORTED_SELF_JOIN", "Self joins not supported yet"};
4296  return {"ERR_OUT_OF_CPU_MEM", "Not enough host memory to execute the query"};
4298  return {"ERR_OVERFLOW_OR_UNDERFLOW", "Overflow or underflow"};
4300  return {"ERR_OUT_OF_TIME", "Query execution has exceeded the time limit"};
4302  return {"ERR_INTERRUPTED", "Query execution has been interrupted"};
4304  return {"ERR_COLUMNAR_CONVERSION_NOT_SUPPORTED",
4305  "Columnar conversion not supported for variable length types"};
4307  return {"ERR_TOO_MANY_LITERALS", "Too many literals in the query"};
4309  return {"ERR_STRING_CONST_IN_RESULTSET",
4310 
4311  "NONE ENCODED String types are not supported as input result set."};
4313  return {"ERR_OUT_OF_RENDER_MEM",
4314 
4315  "Insufficient GPU memory for query results in render output buffer "
4316  "sized by render-mem-bytes"};
4318  return {"ERR_STREAMING_TOP_N_NOT_SUPPORTED_IN_RENDER_QUERY",
4319  "Streaming-Top-N not supported in Render Query"};
4321  return {"ERR_SINGLE_VALUE_FOUND_MULTIPLE_VALUES",
4322  "Multiple distinct values encountered"};
4323  case Executor::ERR_GEOS:
4324  return {"ERR_GEOS", "ERR_GEOS"};
4326  return {"ERR_WIDTH_BUCKET_INVALID_ARGUMENT",
4327 
4328  "Arguments of WIDTH_BUCKET function does not satisfy the condition"};
4329  default:
4330  return {nullptr, nullptr};
4331  }
4332 }
static const int32_t ERR_INTERRUPTED
Definition: Execute.h:1623
static const int32_t ERR_GEOS
Definition: Execute.h:1629
static const int32_t ERR_TOO_MANY_LITERALS
Definition: Execute.h:1625
static const int32_t ERR_STRING_CONST_IN_RESULTSET
Definition: Execute.h:1626
static const int32_t ERR_STREAMING_TOP_N_NOT_SUPPORTED_IN_RENDER_QUERY
Definition: Execute.h:1627
static const int32_t ERR_COLUMNAR_CONVERSION_NOT_SUPPORTED
Definition: Execute.h:1624
static const int32_t ERR_DIV_BY_ZERO
Definition: Execute.h:1615
static const int32_t ERR_OUT_OF_RENDER_MEM
Definition: Execute.h:1619
static const int32_t ERR_OVERFLOW_OR_UNDERFLOW
Definition: Execute.h:1621
static const int32_t ERR_OUT_OF_TIME
Definition: Execute.h:1622
static const int32_t ERR_UNSUPPORTED_SELF_JOIN
Definition: Execute.h:1618
static const int32_t ERR_SINGLE_VALUE_FOUND_MULTIPLE_VALUES
Definition: Execute.h:1628
static const int32_t ERR_OUT_OF_GPU_MEM
Definition: Execute.h:1616
static const int32_t ERR_WIDTH_BUCKET_INVALID_ARGUMENT
Definition: Execute.h:1630
def error_code
Definition: report.py:244
static const int32_t ERR_OUT_OF_CPU_MEM
Definition: Execute.h:1620

+ Here is the caller graph for this function:

std::pair<size_t, shared::TableKey> 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 3462 of file RelAlgExecutor.cpp.

References CHECK.

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

3463  {
3464  CHECK(!table_infos.empty());
3465  const auto& first_table = table_infos.front();
3466  size_t max_num_groups = first_table.info.getNumTuplesUpperBound();
3467  auto table_key = first_table.table_key;
3468  for (const auto& table_info : table_infos) {
3469  if (table_info.info.getNumTuplesUpperBound() > max_num_groups) {
3470  max_num_groups = table_info.info.getNumTuplesUpperBound();
3471  table_key = table_info.table_key;
3472  }
3473  }
3474  return std::make_pair(std::max(max_num_groups, size_t(1)), table_key);
3475 }
#define CHECK(condition)
Definition: Logger.h:291

+ Here is the caller graph for this function:

void anonymous_namespace{RelAlgExecutor.cpp}::handle_query_hint ( RegisteredQueryHint const &  query_hints,
ExecutionOptions eo,
CompilationOptions co 
)

Definition at line 1036 of file RelAlgExecutor.cpp.

References ExecutionOptions::allow_loop_joins, CPU, CompilationOptions::device_type, ExecutionOptions::dynamic_watchdog_time_limit, g_cluster, g_enable_data_recycler, g_use_query_resultset_cache, logger::INFO, RegisteredQueryHint::isHintRegistered(), kAllowLoopJoin, kColumnarOutput, kCpuMode, kCudaBlockSize, kCudaGridSize, kDisableLoopJoin, kDynamicWatchdog, kDynamicWatchdogOff, ExecutionOptions::keep_result, kKeepResult, kKeepTableFuncResult, kMaxJoinHashTableSize, kOptCudaBlockAndGridSizes, kQueryTimeLimit, kRowwiseOutput, kWatchdog, kWatchdogOff, LOG, ExecutionOptions::max_join_hash_table_size, RegisteredQueryHint::max_join_hash_table_size, ExecutionOptions::optimize_cuda_block_and_grid_sizes, ExecutionOptions::output_columnar_hint, RegisteredQueryHint::query_time_limit, VLOG, ExecutionOptions::with_dynamic_watchdog, and ExecutionOptions::with_watchdog.

1038  {
1039  auto columnar_output_hint_enabled = false;
1040  auto rowwise_output_hint_enabled = false;
1041  if (query_hints.isHintRegistered(QueryHint::kCpuMode)) {
1042  VLOG(1) << "A user forces to run the query on the CPU execution mode";
1044  }
1045  if (query_hints.isHintRegistered(QueryHint::kKeepResult)) {
1046  if (!g_enable_data_recycler) {
1047  VLOG(1) << "A user enables keeping query resultset but is skipped since data "
1048  "recycler is disabled";
1049  }
1051  VLOG(1) << "A user enables keeping query resultset but is skipped since query "
1052  "resultset recycler is disabled";
1053  } else {
1054  VLOG(1) << "A user enables keeping query resultset";
1055  eo.keep_result = true;
1056  }
1057  }
1058  if (query_hints.isHintRegistered(QueryHint::kKeepTableFuncResult)) {
1059  // we use this hint within the function 'executeTableFunction`
1060  if (!g_enable_data_recycler) {
1061  VLOG(1) << "A user enables keeping table function's resultset but is skipped "
1062  "since data recycler is disabled";
1063  }
1065  VLOG(1) << "A user enables keeping table function's resultset but is skipped "
1066  "since query resultset recycler is disabled";
1067  } else {
1068  VLOG(1) << "A user enables keeping table function's resultset";
1069  eo.keep_result = true;
1070  }
1071  }
1072  if (query_hints.isHintRegistered(QueryHint::kWatchdog)) {
1073  if (!eo.with_watchdog) {
1074  VLOG(1) << "A user enables watchdog for this query";
1075  eo.with_watchdog = true;
1076  }
1077  }
1078  if (query_hints.isHintRegistered(QueryHint::kWatchdogOff)) {
1079  if (eo.with_watchdog) {
1080  VLOG(1) << "A user disables watchdog for this query";
1081  eo.with_watchdog = false;
1082  }
1083  }
1084  if (query_hints.isHintRegistered(QueryHint::kDynamicWatchdog)) {
1085  if (!eo.with_dynamic_watchdog) {
1086  VLOG(1) << "A user enables dynamic watchdog for this query";
1087  eo.with_watchdog = true;
1088  }
1089  }
1090  if (query_hints.isHintRegistered(QueryHint::kDynamicWatchdogOff)) {
1091  if (eo.with_dynamic_watchdog) {
1092  VLOG(1) << "A user disables dynamic watchdog for this query";
1093  eo.with_watchdog = false;
1094  }
1095  }
1096  if (query_hints.isHintRegistered(QueryHint::kQueryTimeLimit)) {
1097  std::ostringstream oss;
1098  oss << "A user sets query time limit to " << query_hints.query_time_limit << " ms";
1099  eo.dynamic_watchdog_time_limit = query_hints.query_time_limit;
1100  if (!eo.with_dynamic_watchdog) {
1101  eo.with_dynamic_watchdog = true;
1102  oss << " (and system automatically enables dynamic watchdog to activate the "
1103  "given \"query_time_limit\" hint)";
1104  }
1105  VLOG(1) << oss.str();
1106  }
1107  if (query_hints.isHintRegistered(QueryHint::kAllowLoopJoin)) {
1108  VLOG(1) << "A user enables loop join";
1109  eo.allow_loop_joins = true;
1110  }
1111  if (query_hints.isHintRegistered(QueryHint::kDisableLoopJoin)) {
1112  VLOG(1) << "A user disables loop join";
1113  eo.allow_loop_joins = false;
1114  }
1115  if (query_hints.isHintRegistered(QueryHint::kMaxJoinHashTableSize)) {
1116  eo.max_join_hash_table_size = query_hints.max_join_hash_table_size;
1117  VLOG(1) << "A user forces the maximum size of a join hash table as "
1118  << eo.max_join_hash_table_size << " bytes";
1119  }
1120  if (query_hints.isHintRegistered(QueryHint::kOptCudaBlockAndGridSizes)) {
1121  if (query_hints.isHintRegistered(QueryHint::kCudaGridSize) ||
1122  query_hints.isHintRegistered(QueryHint::kCudaBlockSize)) {
1123  VLOG(1) << "Skip query hint \"opt_cuda_grid_and_block_size\" when at least one "
1124  "of the following query hints are given simultaneously: "
1125  "\"cuda_block_size\" and \"cuda_grid_size_multiplier\"";
1126  } else {
1127  VLOG(1) << "A user enables optimization of cuda block and grid sizes";
1129  }
1130  }
1131  if (query_hints.isHintRegistered(QueryHint::kColumnarOutput)) {
1132  VLOG(1) << "A user forces the query to run with columnar output";
1133  columnar_output_hint_enabled = true;
1134  } else if (query_hints.isHintRegistered(QueryHint::kRowwiseOutput)) {
1135  VLOG(1) << "A user forces the query to run with rowwise output";
1136  rowwise_output_hint_enabled = true;
1137  }
1138  auto columnar_output_enabled = eo.output_columnar_hint ? !rowwise_output_hint_enabled
1139  : columnar_output_hint_enabled;
1140  if (g_cluster && (columnar_output_hint_enabled || rowwise_output_hint_enabled)) {
1141  LOG(INFO) << "Currently, we do not support applying query hint to change query "
1142  "output layout in distributed mode.";
1143  }
1144  eo.output_columnar_hint = columnar_output_enabled;
1145 }
bool g_use_query_resultset_cache
Definition: Execute.cpp:156
#define LOG(tag)
Definition: Logger.h:285
bool g_enable_data_recycler
Definition: Execute.cpp:154
ExecutorDeviceType device_type
bool optimize_cuda_block_and_grid_sizes
bool g_cluster
unsigned dynamic_watchdog_time_limit
#define VLOG(n)
Definition: Logger.h:388

+ Here is the call graph for this function:

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

Definition at line 220 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().

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

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

2801  {
2802  if (col_cv->get_is_null()) {
2803  *col_data = inline_fixed_encoding_null_val(columnType);
2804  } else {
2805  const int dict_id = columnType.get_comp_param();
2806  const auto col_datum = col_cv->get_constval();
2807  const auto& str = *col_datum.stringval;
2808  const auto dd = catalog.getMetadataForDict(dict_id);
2809  CHECK(dd && dd->stringDict);
2810  int32_t str_id = dd->stringDict->getOrAdd(str);
2811  if (!dd->dictIsTemp) {
2812  const auto checkpoint_ok = dd->stringDict->checkpoint();
2813  if (!checkpoint_ok) {
2814  throw std::runtime_error("Failed to checkpoint dictionary for column " +
2815  columnName);
2816  }
2817  }
2818  const bool invalid = str_id > max_valid_int_value<T>();
2819  if (invalid || str_id == inline_int_null_value<int32_t>()) {
2820  if (invalid) {
2821  LOG(ERROR) << "Could not encode string: " << str
2822  << ", the encoded value doesn't fit in " << sizeof(T) * 8
2823  << " bits. Will store NULL instead.";
2824  }
2825  str_id = inline_fixed_encoding_null_val(columnType);
2826  }
2827  *col_data = str_id;
2828  }
2829  return *col_data;
2830 }
#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:1904
std::string * stringval
Definition: Datum.h:79
Datum get_constval() const
Definition: Analyzer.h:348
HOST DEVICE int get_comp_param() const
Definition: sqltypes.h:402
#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 2833 of file RelAlgExecutor.cpp.

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

2836  {
2837  return insert_one_dict_str(col_data, cd->columnName, cd->columnType, col_cv, catalog);
2838 }
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 1951 of file RelAlgExecutor.cpp.

References Analyzer::AggExpr::get_aggtype(), shared::is_any(), 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().

1951  {
1952  const auto agg_expr = dynamic_cast<const Analyzer::AggExpr*>(expr);
1953  if (agg_expr && agg_expr->get_contains_agg()) {
1954  auto agg_type = agg_expr->get_aggtype();
1956  SQLAgg::kMAX,
1957  SQLAgg::kSUM,
1959  SQLAgg::kAVG>(agg_type)) {
1960  return true;
1961  }
1962  }
1963  return false;
1964 }
bool is_any(T &&value)
Definition: misc.h:258
Definition: sqldefs.h:75
Definition: sqldefs.h:77
SQLAgg get_aggtype() const
Definition: Analyzer.h:1329
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 1946 of file RelAlgExecutor.cpp.

References Analyzer::AggExpr::get_is_distinct().

Referenced by get_logical_type_for_expr().

1946  {
1947  const auto agg_expr = dynamic_cast<const Analyzer::AggExpr*>(expr);
1948  return agg_expr && agg_expr->get_is_distinct();
1949 }
bool get_is_distinct() const
Definition: Analyzer.h:1332

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool anonymous_namespace{RelAlgExecutor.cpp}::is_none_encoded_text ( TargetMetaInfo const &  target_meta_info)

Definition at line 3218 of file RelAlgExecutor.cpp.

References TargetMetaInfo::get_type_info(), and SQLTypeInfo::is_none_encoded_string().

Referenced by RelAlgExecutor::executeSort().

3218  {
3219  return target_meta_info.get_type_info().is_none_encoded_string();
3220 }

+ 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 3477 of file RelAlgExecutor.cpp.

References RelAlgExecutionUnit::groupby_exprs.

Referenced by can_output_columnar(), compute_output_buffer_size(), RelAlgExecutor::getFilteredCountAll(), and RelAlgTranslator::translateGeoFunctionArg().

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

+ 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 2315 of file RelAlgExecutor.cpp.

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

Referenced by RelAlgExecutor::executeWorkUnit().

2315  {
2316  return std::any_of(ra_exe_unit.target_exprs.begin(),
2317  ra_exe_unit.target_exprs.end(),
2318  [](const Analyzer::Expr* expr) {
2319  return dynamic_cast<const Analyzer::WindowFunction*>(expr);
2320  });
2321 }
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 4462 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().

4462  {
4463  CHECK_GE(left_deep_join->inputCount(), size_t(2));
4464  std::vector<JoinType> join_types(left_deep_join->inputCount() - 1, JoinType::INNER);
4465  for (size_t nesting_level = 1; nesting_level <= left_deep_join->inputCount() - 1;
4466  ++nesting_level) {
4467  if (left_deep_join->getOuterCondition(nesting_level)) {
4468  join_types[nesting_level - 1] = JoinType::LEFT;
4469  }
4470  auto cur_level_join_type = left_deep_join->getJoinType(nesting_level);
4471  if (cur_level_join_type == JoinType::SEMI || cur_level_join_type == JoinType::ANTI) {
4472  join_types[nesting_level - 1] = cur_level_join_type;
4473  }
4474  }
4475  return join_types;
4476 }
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:875

+ 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 4700 of file RelAlgExecutor.cpp.

Referenced by reverse_logical_distribution().

4701  {
4702  for (const auto& qual : haystack) {
4703  if (*qual == *needle) {
4704  return true;
4705  }
4706  }
4707  return false;
4708 }

+ Here is the caller graph for this function:

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

Definition at line 70 of file RelAlgExecutor.cpp.

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

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

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

156  {
158  const auto info_schema_catalog =
160  CHECK(info_schema_catalog);
161  std::map<int32_t, std::vector<int32_t>> system_table_columns_by_table_id;
162  for (const auto& physical_input : get_physical_inputs(&ra_node)) {
163  if (info_schema_catalog->getDatabaseId() != physical_input.db_id) {
164  continue;
165  }
166  const auto table_id = physical_input.table_id;
167  const auto table = info_schema_catalog->getMetadataForTable(table_id, false);
168  CHECK(table);
169  if (table->is_in_memory_system_table) {
170  const auto column_id =
171  info_schema_catalog->getColumnIdBySpi(table_id, physical_input.col_id);
172  system_table_columns_by_table_id[table_id].emplace_back(column_id);
173  }
174  }
175  // Execute on CPU for queries involving system tables
176  if (!system_table_columns_by_table_id.empty() &&
178  throw QueryMustRunOnCpu();
179  }
180 
181  for (const auto& [table_id, column_ids] : system_table_columns_by_table_id) {
182  // Clear any previously cached data, since system tables depend on point in
183  // time data snapshots.
184  info_schema_catalog->getDataMgr().deleteChunksWithPrefix(
185  ChunkKey{info_schema_catalog->getDatabaseId(), table_id},
187 
188  // TODO(Misiu): This prefetching can be removed if we can add support for
189  // ExpressionRanges to reduce invalid with valid ranges (right now prefetching
190  // causes us to fetch the chunks twice). Right now if we do not prefetch (i.e. if
191  // we remove the code below) some nodes will return valid ranges and others will
192  // return unknown because they only use placeholder metadata and the LeafAggregator
193  // has no idea how to reduce the two.
194  const auto td = info_schema_catalog->getMetadataForTable(table_id);
195  CHECK(td);
196  CHECK(td->fragmenter);
197  auto fragment_count = td->fragmenter->getFragmentsForQuery().fragments.size();
198  CHECK_LE(fragment_count, static_cast<size_t>(1))
199  << "In-memory system tables are expected to have a single fragment.";
200  if (fragment_count > 0) {
201  for (auto column_id : column_ids) {
202  // Prefetch system table chunks in order to force chunk statistics metadata
203  // computation.
204  const auto cd = info_schema_catalog->getMetadataForColumn(table_id, column_id);
205  const ChunkKey chunk_key{
206  info_schema_catalog->getDatabaseId(), table_id, column_id, 0};
208  &(info_schema_catalog->getDataMgr()),
209  chunk_key,
211  0,
212  0,
213  0);
214  }
215  }
216  }
217  }
218 }
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 147 of file RelAlgExecutor.cpp.

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

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

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

135  {
136  for (const auto [col_id, table_id, db_id] : get_physical_inputs(&ra_node)) {
137  const auto catalog = Catalog_Namespace::SysCatalog::instance().getCatalog(db_id);
138  CHECK(catalog);
139  const auto table = catalog->getMetadataForTable(table_id, false);
140  if (table && table->storageType == StorageType::FOREIGN_TABLE) {
141  const auto spi_col_id = catalog->getColumnIdBySpi(table_id, col_id);
142  foreign_storage::populate_string_dictionary(table_id, spi_col_id, db_id);
143  }
144  }
145 }
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:233
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 4713 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().

4714  {
4715  const auto expr_terms = qual_to_disjunctive_form(expr);
4716  CHECK_GE(expr_terms.size(), size_t(1));
4717  const auto& first_term = expr_terms.front();
4718  const auto first_term_factors = qual_to_conjunctive_form(first_term);
4719  std::vector<std::shared_ptr<Analyzer::Expr>> common_factors;
4720  // First, collect the conjunctive components common to all the disjunctive components.
4721  // Don't do it for simple qualifiers, we only care about expensive or join qualifiers.
4722  for (const auto& first_term_factor : first_term_factors.quals) {
4723  bool is_common =
4724  expr_terms.size() > 1; // Only report common factors for disjunction.
4725  for (size_t i = 1; i < expr_terms.size(); ++i) {
4726  const auto crt_term_factors = qual_to_conjunctive_form(expr_terms[i]);
4727  if (!list_contains_expression(crt_term_factors.quals, first_term_factor)) {
4728  is_common = false;
4729  break;
4730  }
4731  }
4732  if (is_common) {
4733  common_factors.push_back(first_term_factor);
4734  }
4735  }
4736  if (common_factors.empty()) {
4737  return expr;
4738  }
4739  // Now that the common expressions are known, collect the remaining expressions.
4740  std::vector<std::shared_ptr<Analyzer::Expr>> remaining_terms;
4741  for (const auto& term : expr_terms) {
4742  const auto term_cf = qual_to_conjunctive_form(term);
4743  std::vector<std::shared_ptr<Analyzer::Expr>> remaining_quals(
4744  term_cf.simple_quals.begin(), term_cf.simple_quals.end());
4745  for (const auto& qual : term_cf.quals) {
4746  if (!list_contains_expression(common_factors, qual)) {
4747  remaining_quals.push_back(qual);
4748  }
4749  }
4750  if (!remaining_quals.empty()) {
4751  remaining_terms.push_back(build_logical_expression(remaining_quals, kAND));
4752  }
4753  }
4754  // Reconstruct the expression with the transformation applied.
4755  const auto common_expr = build_logical_expression(common_factors, kAND);
4756  if (remaining_terms.empty()) {
4757  return common_expr;
4758  }
4759  const auto remaining_expr = build_logical_expression(remaining_terms, kOR);
4760  return Parser::OperExpr::normalize(kAND, kONE, common_expr, remaining_expr);
4761 }
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:379
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 4525 of file RelAlgExecutor.cpp.

References rewrite_expr().

Referenced by RelAlgExecutor::createCompoundWorkUnit().

4526  {
4527  std::list<std::shared_ptr<Analyzer::Expr>> rewritten_quals;
4528  for (const auto& qual : quals) {
4529  const auto rewritten_qual = rewrite_expr(qual.get());
4530  rewritten_quals.push_back(rewritten_qual ? rewritten_qual : qual);
4531  }
4532  return rewritten_quals;
4533 }
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 4673 of file RelAlgExecutor.cpp.

References CHECK, CHECK_GE, and kAND.

Referenced by RelAlgExecutor::makeJoinQuals().

4673  {
4674  CHECK(qual_expr);
4675  const auto bin_oper = dynamic_cast<const RexOperator*>(qual_expr);
4676  if (!bin_oper || bin_oper->getOperator() != kAND) {
4677  return {qual_expr};
4678  }
4679  CHECK_GE(bin_oper->size(), size_t(2));
4680  auto lhs_cf = rex_to_conjunctive_form(bin_oper->getOperand(0));
4681  for (size_t i = 1; i < bin_oper->size(); ++i) {
4682  const auto rhs_cf = rex_to_conjunctive_form(bin_oper->getOperand(i));
4683  lhs_cf.insert(lhs_cf.end(), rhs_cf.begin(), rhs_cf.end());
4684  }
4685  return lhs_cf;
4686 }
#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 1703 of file RelAlgExecutor.cpp.

References RelCompound::getScalarSource().

Referenced by translate_scalar_sources(), and translate_scalar_sources_for_update().

1703  {
1704  return compound->getScalarSource(i);
1705 }
const RexScalar * getScalarSource(const size_t i) const
Definition: RelAlgDag.h:2112

+ 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 1707 of file RelAlgExecutor.cpp.

References RelProject::getProjectAt().

1707  {
1708  return project->getProjectAt(i);
1709 }
const RexScalar * getProjectAt(const size_t idx) const
Definition: RelAlgDag.h:1352

+ 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 1711 of file RelAlgExecutor.cpp.

References RelTableFunction::getTableFuncInputAt().

1711  {
1712  return table_func->getTableFuncInputAt(i);
1713 }
const RexScalar * getTableFuncInputAt(const size_t idx) const
Definition: RelAlgDag.h:2566

+ Here is the call graph for this function:

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

Definition at line 89 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().

89  {
90  std::map<ChunkKey, std::set<foreign_storage::ForeignStorageMgr::ParallelismHint>>
91  parallelism_hints_per_table;
92  for (const auto& physical_input : get_physical_inputs(&ra_node)) {
93  const auto table_id = physical_input.table_id;
94  const auto catalog =
96  CHECK(catalog);
97  const auto table = catalog->getMetadataForTable(table_id, true);
98  if (table && table->storageType == StorageType::FOREIGN_TABLE &&
99  !table->is_in_memory_system_table) {
100  const auto col_id = catalog->getColumnIdBySpi(table_id, physical_input.col_id);
101  const auto col_desc = catalog->getMetadataForColumn(table_id, col_id);
102  const auto foreign_table = catalog->getForeignTable(table_id);
103  for (const auto& fragment :
104  foreign_table->fragmenter->getFragmentsForQuery().fragments) {
105  Chunk_NS::Chunk chunk{col_desc};
106  ChunkKey chunk_key = {
107  physical_input.db_id, table_id, col_id, fragment.fragmentId};
108 
109  // Parallelism hints should not include fragments that are not mapped to the
110  // current node, otherwise we will try to prefetch them and run into trouble.
112  continue;
113  }
114 
115  // do not include chunk hints that are in CPU memory
116  if (!chunk.isChunkOnDevice(
117  &catalog->getDataMgr(), chunk_key, Data_Namespace::CPU_LEVEL, 0)) {
118  parallelism_hints_per_table[{physical_input.db_id, table_id}].insert(
120  fragment.fragmentId});
121  }
122  }
123  }
124  }
125  if (!parallelism_hints_per_table.empty()) {
126  auto foreign_storage_mgr = Catalog_Namespace::SysCatalog::instance()
127  .getDataMgr()
130  CHECK(foreign_storage_mgr);
131  foreign_storage_mgr->setParallelismHints(parallelism_hints_per_table);
132  }
133 }
std::vector< int > ChunkKey
Definition: types.h:36
PersistentStorageMgr * getPersistentStorageMgr() const
Definition: DataMgr.cpp:677
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 1715 of file RelAlgExecutor.cpp.

References kENCODING_DICT, kENCODING_NONE, shared::StringDictKey::kTransientDictKey, and TRANSIENT_DICT_ID.

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

1716  {
1717  const auto& ti = expr->get_type_info();
1718  if (!ti.is_string() || ti.get_compression() != kENCODING_NONE) {
1719  return expr;
1720  }
1721  auto transient_dict_ti = ti;
1722  transient_dict_ti.set_compression(kENCODING_DICT);
1723  transient_dict_ti.set_comp_param(TRANSIENT_DICT_ID);
1724  transient_dict_ti.setStringDictKey(shared::StringDictKey::kTransientDictKey);
1725  transient_dict_ti.set_fixed_size();
1726  return expr->add_cast(transient_dict_ti);
1727 }
#define TRANSIENT_DICT_ID
Definition: DbObjectKeys.h:24
static const StringDictKey kTransientDictKey
Definition: DbObjectKeys.h:45

+ 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 1729 of file RelAlgExecutor.cpp.

References fold_expr(), and set_transient_dict().

Referenced by translate_scalar_sources(), and translate_scalar_sources_for_update().

1731  {
1732  try {
1733  scalar_sources.push_back(set_transient_dict(fold_expr(expr.get())));
1734  } catch (...) {
1735  scalar_sources.push_back(fold_expr(expr.get()));
1736  }
1737 }
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 3521 of file RelAlgExecutor.cpp.

References g_columnar_large_projections, g_columnar_large_projections_threshold, RelAlgExecutionUnit::scan_limit, and RelAlgExecutionUnit::target_exprs.

Referenced by RelAlgExecutor::executeWorkUnit().

3521  {
3522  for (const auto& target_expr : ra_exe_unit.target_exprs) {
3523  if (target_expr->get_type_info().usesFlatBuffer()) {
3524  // using FlatBuffer memory layout implies columnar-only output
3525  return true;
3526  }
3527  }
3530 }
std::vector< Analyzer::Expr * > target_exprs
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 4838 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().

4842  {
4843  CHECK_LE(size_t(1), ra_node->inputCount());
4844  CHECK_GE(size_t(2), ra_node->inputCount());
4845  const auto input = ra_node->getInput(nest_level);
4846  const auto it_rte_idx = input_to_nest_level.find(input);
4847  CHECK(it_rte_idx != input_to_nest_level.end());
4848  const int rte_idx = it_rte_idx->second;
4849  const auto table_key = table_key_from_ra(input);
4850  std::vector<std::shared_ptr<Analyzer::Expr>> inputs;
4851  const auto scan_ra = dynamic_cast<const RelScan*>(input);
4852  int input_idx = 0;
4853  for (const auto& input_meta : in_metainfo) {
4854  inputs.push_back(std::make_shared<Analyzer::ColumnVar>(
4855  input_meta.get_type_info(),
4856  shared::ColumnKey{table_key, scan_ra ? input_idx + 1 : input_idx},
4857  rte_idx));
4858  ++input_idx;
4859  }
4860  return inputs;
4861 }
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:877
#define CHECK_LE(x, y)
Definition: Logger.h:304
#define CHECK(condition)
Definition: Logger.h:291
const size_t inputCount() const
Definition: RelAlgDag.h:875

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

1517  {
1518  const auto scan_ra = dynamic_cast<const RelScan*>(ra_node);
1519  shared::TableKey table_key{0, int32_t(-ra_node->getId())};
1520  if (scan_ra) {
1521  table_key.db_id = scan_ra->getCatalog().getDatabaseId();
1522  const auto td = scan_ra->getTableDescriptor();
1523  CHECK(td);
1524  table_key.table_id = td->tableId;
1525  }
1526  return table_key;
1527 }
unsigned getId() const
Definition: RelAlgDag.h:869
#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 5051 of file RelAlgExecutor.cpp.

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

Referenced by RelAlgExecutor::createUnionWorkUnit().

5052  {
5053  std::vector<TargetMetaInfo> const& tmis = input_node->getOutputMetainfo();
5054  VLOG(3) << "input_node->getOutputMetainfo()=" << shared::printContainer(tmis);
5055  const int negative_node_id = -input_node->getId();
5056  int32_t db_id{0};
5057  if (auto rel_scan = dynamic_cast<const RelScan*>(input_node)) {
5058  db_id = rel_scan->getCatalog().getDatabaseId();
5059  }
5060  std::vector<std::shared_ptr<Analyzer::Expr>> target_exprs;
5061  target_exprs.reserve(tmis.size());
5062  for (size_t i = 0; i < tmis.size(); ++i) {
5063  target_exprs.push_back(std::make_shared<Analyzer::ColumnVar>(
5064  tmis[i].get_type_info(),
5065  shared::ColumnKey{db_id, negative_node_id, int32_t(i)},
5066  0));
5067  }
5068  return target_exprs;
5069 }
PrintContainer< CONTAINER > printContainer(CONTAINER &container)
Definition: misc.h:107
#define VLOG(n)
Definition: Logger.h:388

+ 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 2465 of file RelAlgExecutor.cpp.

Referenced by RelAlgExecutor::computeWindow().

2465  {
2466  const auto tuple = dynamic_cast<const Analyzer::ExpressionTuple*>(expr);
2467  if (tuple) {
2468  std::vector<std::shared_ptr<Analyzer::Expr>> transformed_tuple;
2469  for (const auto& element : tuple->getTuple()) {
2470  transformed_tuple.push_back(transform_to_inner(element.get()));
2471  }
2472  return makeExpr<Analyzer::ExpressionTuple>(transformed_tuple);
2473  }
2474  const auto col = dynamic_cast<const Analyzer::ColumnVar*>(expr);
2475  if (!col) {
2476  throw std::runtime_error("Only columns supported in the window partition for now");
2477  }
2478  return makeExpr<Analyzer::ColumnVar>(col->get_type_info(), col->getColumnKey(), 1);
2479 }
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 1815 of file RelAlgExecutor.cpp.

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

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

1817  {
1818  if (!compound->isAggregate()) {
1819  return {nullptr};
1820  }
1821  std::list<std::shared_ptr<Analyzer::Expr>> groupby_exprs;
1822  for (size_t group_idx = 0; group_idx < compound->getGroupByCount(); ++group_idx) {
1823  groupby_exprs.push_back(set_transient_dict(scalar_sources[group_idx]));
1824  }
1825  return groupby_exprs;
1826 }
std::shared_ptr< Analyzer::Expr > set_transient_dict(const std::shared_ptr< Analyzer::Expr > expr)
const size_t getGroupByCount() const
Definition: RelAlgDag.h:2121
bool isAggregate() const
Definition: RelAlgDag.h:2123

+ 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 1828 of file RelAlgExecutor.cpp.

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

1830  {
1831  std::list<std::shared_ptr<Analyzer::Expr>> groupby_exprs;
1832  for (size_t group_idx = 0; group_idx < aggregate->getGroupByCount(); ++group_idx) {
1833  groupby_exprs.push_back(set_transient_dict(scalar_sources[group_idx]));
1834  }
1835  return groupby_exprs;
1836 }
const size_t getGroupByCount() const
Definition: RelAlgDag.h:1508
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 1838 of file RelAlgExecutor.cpp.

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

Referenced by RelAlgExecutor::createCompoundWorkUnit().

1839  {
1840  const auto filter_rex = compound->getFilterExpr();
1841  const auto filter_expr = filter_rex ? translator.translate(filter_rex) : nullptr;
1842  return filter_expr ? qual_to_conjunctive_form(fold_expr(filter_expr.get()))
1844 }
const RexScalar * getFilterExpr() const
Definition: RelAlgDag.h:2096
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 1749 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().

1752  {
1753  std::vector<std::shared_ptr<Analyzer::Expr>> scalar_sources;
1754  const size_t scalar_sources_size = get_scalar_sources_size(ra_node);
1755  VLOG(3) << "get_scalar_sources_size("
1756  << ra_node->toString(RelRexToStringConfig::defaults())
1757  << ") = " << scalar_sources_size;
1758  for (size_t i = 0; i < scalar_sources_size; ++i) {
1759  const auto scalar_rex = scalar_at(i, ra_node);
1760  if (dynamic_cast<const RexRef*>(scalar_rex)) {
1761  // RexRef are synthetic scalars we append at the end of the real ones
1762  // for the sake of taking memory ownership, no real work needed here.
1763  continue;
1764  }
1765 
1766  const auto scalar_expr =
1767  rewrite_array_elements(translator.translate(scalar_rex).get());
1768  const auto rewritten_expr = rewrite_expr(scalar_expr.get());
1769  if (executor_type == ExecutorType::Native) {
1770  set_transient_dict_maybe(scalar_sources, rewritten_expr);
1771  } else if (executor_type == ExecutorType::TableFunctions) {
1772  scalar_sources.push_back(fold_expr(rewritten_expr.get()));
1773  } else {
1774  scalar_sources.push_back(cast_dict_to_none(fold_expr(rewritten_expr.get())));
1775  }
1776  }
1777 
1778  return scalar_sources;
1779 }
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:78
const RexScalar * scalar_at(const size_t i, const RelCompound *compound)
#define VLOG(n)
Definition: Logger.h:388
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 1782 of file RelAlgExecutor.cpp.

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

1788  {
1789  std::vector<std::shared_ptr<Analyzer::Expr>> scalar_sources;
1790  for (size_t i = 0; i < get_scalar_sources_size(ra_node); ++i) {
1791  const auto scalar_rex = scalar_at(i, ra_node);
1792  if (dynamic_cast<const RexRef*>(scalar_rex)) {
1793  // RexRef are synthetic scalars we append at the end of the real ones
1794  // for the sake of taking memory ownership, no real work needed here.
1795  continue;
1796  }
1797 
1798  std::shared_ptr<Analyzer::Expr> translated_expr;
1799  if (i >= starting_projection_column_idx && i < get_scalar_sources_size(ra_node) - 1) {
1800  translated_expr = cast_to_column_type(translator.translate(scalar_rex),
1801  tableId,
1802  cat,
1803  colNames[i - starting_projection_column_idx]);
1804  } else {
1805  translated_expr = translator.translate(scalar_rex);
1806  }
1807  const auto scalar_expr = rewrite_array_elements(translated_expr.get());
1808  const auto rewritten_expr = rewrite_expr(scalar_expr.get());
1809  set_transient_dict_maybe(scalar_sources, rewritten_expr);
1810  }
1811 
1812  return scalar_sources;
1813 }
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 1869 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().

1876  {
1877  std::vector<Analyzer::Expr*> target_exprs;
1878  for (size_t i = 0; i < compound->size(); ++i) {
1879  const auto target_rex = compound->getTargetExpr(i);
1880  const auto target_rex_agg = dynamic_cast<const RexAgg*>(target_rex);
1881  std::shared_ptr<Analyzer::Expr> target_expr;
1882  if (target_rex_agg) {
1883  target_expr =
1884  RelAlgTranslator::translateAggregateRex(target_rex_agg, scalar_sources);
1885  conditionally_change_arg_to_int_type(i, target_expr, target_exprs_type_infos);
1886  } else {
1887  const auto target_rex_scalar = dynamic_cast<const RexScalar*>(target_rex);
1888  const auto target_rex_ref = dynamic_cast<const RexRef*>(target_rex_scalar);
1889  if (target_rex_ref) {
1890  const auto ref_idx = target_rex_ref->getIndex();
1891  CHECK_GE(ref_idx, size_t(1));
1892  CHECK_LE(ref_idx, groupby_exprs.size());
1893  const auto groupby_expr = *std::next(groupby_exprs.begin(), ref_idx - 1);
1894  target_expr = var_ref(groupby_expr.get(), Analyzer::Var::kGROUPBY, ref_idx);
1895  } else {
1896  target_expr =
1897  rewrite_array_elements(translator.translate(target_rex_scalar).get());
1898  auto rewritten_expr = rewrite_expr(target_expr.get());
1899  target_expr = fold_expr(rewritten_expr.get());
1900  if (executor_type == ExecutorType::Native) {
1901  try {
1902  target_expr = set_transient_dict(target_expr);
1903  } catch (...) {
1904  // noop
1905  }
1906  } else {
1907  target_expr = cast_dict_to_none(target_expr);
1908  }
1909  }
1910  target_exprs_type_infos.emplace(i, target_expr->get_type_info());
1911  }
1912  CHECK(target_expr);
1913  target_exprs_owned.push_back(target_expr);
1914  target_exprs.push_back(target_expr.get());
1915  }
1916  return target_exprs;
1917 }
Analyzer::ExpressionPtr rewrite_array_elements(Analyzer::Expr const *expr)
const Rex * getTargetExpr(const size_t i) const
Definition: RelAlgDag.h:2102
size_t getIndex() const
Definition: RelAlgDag.h:741
size_t size() const override
Definition: RelAlgDag.h:2094
std::shared_ptr< Analyzer::Var > var_ref(const Analyzer::Expr *expr, const Analyzer::Var::WhichRow which_row, const int varno)
Definition: Analyzer.h:3217
#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 1919 of file RelAlgExecutor.cpp.

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

1925  {
1926  std::vector<Analyzer::Expr*> target_exprs;
1927  size_t group_key_idx = 1;
1928  for (const auto& groupby_expr : groupby_exprs) {
1929  auto target_expr =
1930  var_ref(groupby_expr.get(), Analyzer::Var::kGROUPBY, group_key_idx++);
1931  target_exprs_owned.push_back(target_expr);
1932  target_exprs.push_back(target_expr.get());
1933  }
1934 
1935  for (const auto& target_rex_agg : aggregate->getAggExprs()) {
1936  auto target_expr =
1937  RelAlgTranslator::translateAggregateRex(target_rex_agg.get(), scalar_sources);
1938  CHECK(target_expr);
1939  target_expr = fold_expr(target_expr.get());
1940  target_exprs_owned.push_back(target_expr);
1941  target_exprs.push_back(target_expr.get());
1942  }
1943  return target_exprs;
1944 }
std::shared_ptr< Analyzer::Var > var_ref(const Analyzer::Expr *expr, const Analyzer::Var::WhichRow which_row, const int varno)
Definition: Analyzer.h:3217
const std::vector< std::unique_ptr< const RexAgg > > & getAggExprs() const
Definition: RelAlgDag.h:1531
#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: