OmniSciDB  f17484ade4
 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)
 
size_t groups_approx_upper_bound (const std::vector< InputTableInfo > &table_infos)
 
bool is_projection (const RelAlgExecutionUnit &ra_exe_unit)
 
bool can_output_columnar (const RelAlgExecutionUnit &ra_exe_unit, const RenderInfo *render_info, const RelAlgNode *body)
 
bool should_output_columnar (const RelAlgExecutionUnit &ra_exe_unit)
 
bool compute_output_buffer_size (const RelAlgExecutionUnit &ra_exe_unit)
 
bool exe_unit_has_quals (const RelAlgExecutionUnit ra_exe_unit)
 
RelAlgExecutionUnit decide_approx_count_distinct_implementation (const RelAlgExecutionUnit &ra_exe_unit_in, const std::vector< InputTableInfo > &table_infos, const Executor *executor, const ExecutorDeviceType device_type_in, std::vector< std::shared_ptr< Analyzer::Expr >> &target_exprs_owned)
 
bool can_use_bump_allocator (const RelAlgExecutionUnit &ra_exe_unit, const CompilationOptions &co, const ExecutionOptions &eo)
 
ErrorInfo getErrorDescription (const int32_t error_code)
 
JoinType get_join_type (const RelAlgNode *ra)
 
std::unique_ptr< const
RexOperator
get_bitwise_equals (const RexScalar *scalar)
 
std::unique_ptr< const
RexOperator
get_bitwise_equals_conjunction (const RexScalar *scalar)
 
std::vector< JoinTypeleft_deep_join_types (const RelLeftDeepInnerJoin *left_deep_join)
 
template<class RA >
std::vector< size_t > do_table_reordering (std::vector< InputDescriptor > &input_descs, std::list< std::shared_ptr< const InputColDescriptor >> &input_col_descs, const JoinQualsPerNestingLevel &left_deep_join_quals, std::unordered_map< const RelAlgNode *, int > &input_to_nest_level, const RA *node, const std::vector< InputTableInfo > &query_infos, const Executor *executor)
 
std::vector< size_t > get_left_deep_join_input_sizes (const RelLeftDeepInnerJoin *left_deep_join)
 
std::list< std::shared_ptr
< Analyzer::Expr > > 
rewrite_quals (const std::list< std::shared_ptr< Analyzer::Expr >> &quals)
 
std::vector< const RexScalar * > rex_to_conjunctive_form (const RexScalar *qual_expr)
 
std::shared_ptr< Analyzer::Exprbuild_logical_expression (const std::vector< std::shared_ptr< Analyzer::Expr >> &factors, const SQLOps sql_op)
 
template<class QualsList >
bool list_contains_expression (const QualsList &haystack, const std::shared_ptr< Analyzer::Expr > &needle)
 
std::shared_ptr< Analyzer::Exprreverse_logical_distribution (const std::shared_ptr< Analyzer::Expr > &expr)
 
std::vector< std::shared_ptr
< Analyzer::Expr > > 
synthesize_inputs (const RelAlgNode *ra_node, const size_t nest_level, const std::vector< TargetMetaInfo > &in_metainfo, const std::unordered_map< const RelAlgNode *, int > &input_to_nest_level)
 
std::vector< Analyzer::Expr * > get_raw_pointers (std::vector< std::shared_ptr< Analyzer::Expr >> const &input)
 
std::vector< std::shared_ptr
< Analyzer::Expr > > 
target_exprs_for_union (RelAlgNode const *input_node)
 
std::pair< std::vector
< TargetMetaInfo >
, std::vector< std::shared_ptr
< Analyzer::Expr > > > 
get_inputs_meta (const RelFilter *filter, const RelAlgTranslator &translator, const std::vector< std::shared_ptr< RexInput >> &inputs_owned, const std::unordered_map< const RelAlgNode *, int > &input_to_nest_level)
 

Function Documentation

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

Definition at line 4609 of file RelAlgExecutor.cpp.

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

Referenced by reverse_logical_distribution().

4611  {
4612  CHECK(!factors.empty());
4613  auto acc = factors.front();
4614  for (size_t i = 1; i < factors.size(); ++i) {
4615  acc = Parser::OperExpr::normalize(sql_op, kONE, acc, factors[i]);
4616  }
4617  return acc;
4618 }
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 3483 of file RelAlgExecutor.cpp.

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

Referenced by RelAlgExecutor::executeWorkUnit().

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

3632  {
3634  !eo.output_columnar_hint && ra_exe_unit.sort_info.order_entries.empty();
3635 }
std::list< Analyzer::OrderEntry > order_entries
ExecutorDeviceType device_type
bool g_enable_bump_allocator
Definition: Execute.cpp:125

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

References kENCODING_DICT, and kTEXT.

Referenced by translate_scalar_sources(), and translate_targets().

1739  {
1740  const auto& input_ti = input->get_type_info();
1741  if (input_ti.is_string() && input_ti.get_compression() == kENCODING_DICT) {
1742  return input->add_cast(SQLTypeInfo(kTEXT, input_ti.get_notnull()));
1743  }
1744  return input;
1745 }
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 447 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().

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

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

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

794  {
795  CHECK_EQ(size_t(1), sort->inputCount());
796  const auto source = sort->getInput(0);
797  if (dynamic_cast<const RelSort*>(source)) {
798  throw std::runtime_error("Sort node not supported as input to another sort");
799  }
800 }
#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 1595 of file RelAlgExecutor.cpp.

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

Referenced by get_input_desc_impl().

1600  {
1601  VLOG(3) << "ra_node=" << ra_node->toString(RelRexToStringConfig::defaults())
1602  << " input_col_descs_unique.size()=" << input_col_descs_unique.size()
1603  << " source_used_inputs.size()=" << source_used_inputs.size();
1604  for (const auto used_input : source_used_inputs) {
1605  const auto input_ra = used_input->getSourceNode();
1606  const auto table_key = table_key_from_ra(input_ra);
1607  auto col_id = used_input->getIndex();
1608  auto it = input_to_nest_level.find(input_ra);
1609  if (it != input_to_nest_level.end()) {
1610  const int nest_level = it->second;
1611  if (auto rel_scan = dynamic_cast<const RelScan*>(input_ra)) {
1612  const auto& catalog = rel_scan->getCatalog();
1613  col_id = catalog.getColumnIdBySpi(table_key.table_id, col_id + 1);
1614  }
1615  input_col_descs_unique.insert(std::make_shared<const InputColDescriptor>(
1616  col_id, table_key.table_id, table_key.db_id, nest_level));
1617  } else if (!dynamic_cast<const RelLogicalUnion*>(ra_node)) {
1618  throw std::runtime_error("Bushy joins not supported");
1619  }
1620  }
1621 }
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 3540 of file RelAlgExecutor.cpp.

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

Referenced by RelAlgExecutor::executeWorkUnit().

3540  {
3541  for (const auto target_expr : ra_exe_unit.target_exprs) {
3542  if (dynamic_cast<const Analyzer::AggExpr*>(target_expr)) {
3543  return false;
3544  }
3545  }
3546  if (ra_exe_unit.groupby_exprs.size() == 1 && !ra_exe_unit.groupby_exprs.front() &&
3547  (!ra_exe_unit.scan_limit || ra_exe_unit.scan_limit > Executor::high_scan_limit)) {
3548  return true;
3549  }
3550  return false;
3551 }
std::vector< Analyzer::Expr * > target_exprs
const std::list< std::shared_ptr< Analyzer::Expr > > groupby_exprs
static const size_t high_scan_limit
Definition: Execute.h:693

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

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

4407  {
4408  if (g_cluster) {
4409  // Disable table reordering in distributed mode. The aggregator does not have enough
4410  // information to break ties
4411  return {};
4412  }
4413  if (node->isUpdateViaSelect() || node->isDeleteViaSelect()) {
4414  // Do not reorder tables for UPDATE and DELETE queries, since the outer table always
4415  // has to be the physical table.
4416  return {};
4417  }
4418  for (const auto& table_info : query_infos) {
4419  if (table_info.table_key.table_id < 0) {
4420  continue;
4421  }
4422  const auto td = Catalog_Namespace::get_metadata_for_table(table_info.table_key);
4423  CHECK(td);
4424  if (table_is_replicated(td)) {
4425  return {};
4426  }
4427  }
4428  const auto input_permutation =
4429  get_node_input_permutation(left_deep_join_quals, query_infos, executor);
4430  input_to_nest_level = get_input_nest_levels(node, input_permutation);
4431  std::tie(input_descs, input_col_descs, std::ignore) =
4432  get_input_desc(node, input_to_nest_level, input_permutation);
4433  return input_permutation;
4434 }
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 3553 of file RelAlgExecutor.cpp.

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

Referenced by RelAlgExecutor::executeWorkUnit().

3553  {
3554  return !(ra_exe_unit.quals.empty() && ra_exe_unit.join_quals.empty() &&
3555  ra_exe_unit.simple_quals.empty());
3556 }
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 3211 of file RelAlgExecutor.cpp.

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

3211  {
3212  return !order_entries.empty() && order_entries.front().is_desc;
3213 }

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

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

Referenced by get_bitwise_equals_conjunction().

4315  {
4316  const auto condition = dynamic_cast<const RexOperator*>(scalar);
4317  if (!condition || condition->getOperator() != kOR || condition->size() != 2) {
4318  return nullptr;
4319  }
4320  const auto equi_join_condition =
4321  dynamic_cast<const RexOperator*>(condition->getOperand(0));
4322  if (!equi_join_condition || equi_join_condition->getOperator() != kEQ) {
4323  return nullptr;
4324  }
4325  const auto both_are_null_condition =
4326  dynamic_cast<const RexOperator*>(condition->getOperand(1));
4327  if (!both_are_null_condition || both_are_null_condition->getOperator() != kAND ||
4328  both_are_null_condition->size() != 2) {
4329  return nullptr;
4330  }
4331  const auto lhs_is_null =
4332  dynamic_cast<const RexOperator*>(both_are_null_condition->getOperand(0));
4333  const auto rhs_is_null =
4334  dynamic_cast<const RexOperator*>(both_are_null_condition->getOperand(1));
4335  if (!lhs_is_null || !rhs_is_null || lhs_is_null->getOperator() != kISNULL ||
4336  rhs_is_null->getOperator() != kISNULL) {
4337  return nullptr;
4338  }
4339  CHECK_EQ(size_t(1), lhs_is_null->size());
4340  CHECK_EQ(size_t(1), rhs_is_null->size());
4341  CHECK_EQ(size_t(2), equi_join_condition->size());
4342  const auto eq_lhs = dynamic_cast<const RexInput*>(equi_join_condition->getOperand(0));
4343  const auto eq_rhs = dynamic_cast<const RexInput*>(equi_join_condition->getOperand(1));
4344  const auto is_null_lhs = dynamic_cast<const RexInput*>(lhs_is_null->getOperand(0));
4345  const auto is_null_rhs = dynamic_cast<const RexInput*>(rhs_is_null->getOperand(0));
4346  if (!eq_lhs || !eq_rhs || !is_null_lhs || !is_null_rhs) {
4347  return nullptr;
4348  }
4349  std::vector<std::unique_ptr<const RexScalar>> eq_operands;
4350  if (*eq_lhs == *is_null_lhs && *eq_rhs == *is_null_rhs) {
4351  RexDeepCopyVisitor deep_copy_visitor;
4352  auto lhs_op_copy = deep_copy_visitor.visit(equi_join_condition->getOperand(0));
4353  auto rhs_op_copy = deep_copy_visitor.visit(equi_join_condition->getOperand(1));
4354  eq_operands.emplace_back(lhs_op_copy.release());
4355  eq_operands.emplace_back(rhs_op_copy.release());
4356  return boost::make_unique<const RexOperator>(
4357  kBW_EQ, eq_operands, equi_join_condition->getType());
4358  }
4359  return nullptr;
4360 }
#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 4362 of file RelAlgExecutor.cpp.

References CHECK_GE, get_bitwise_equals(), and kAND.

Referenced by RelAlgExecutor::makeJoinQuals().

4363  {
4364  const auto condition = dynamic_cast<const RexOperator*>(scalar);
4365  if (condition && condition->getOperator() == kAND) {
4366  CHECK_GE(condition->size(), size_t(2));
4367  auto acc = get_bitwise_equals(condition->getOperand(0));
4368  if (!acc) {
4369  return nullptr;
4370  }
4371  for (size_t i = 1; i < condition->size(); ++i) {
4372  std::vector<std::unique_ptr<const RexScalar>> and_operands;
4373  and_operands.emplace_back(std::move(acc));
4374  and_operands.emplace_back(get_bitwise_equals_conjunction(condition->getOperand(i)));
4375  acc =
4376  boost::make_unique<const RexOperator>(kAND, and_operands, condition->getType());
4377  }
4378  return acc;
4379  }
4380  return get_bitwise_equals(scalar);
4381 }
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 1390 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().

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

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

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

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

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

Referenced by RelAlgExecutor::createFilterWorkUnit().

5309  {
5310  std::vector<TargetMetaInfo> in_metainfo;
5311  std::vector<std::shared_ptr<Analyzer::Expr>> exprs_owned;
5312  const auto data_sink_node = get_data_sink(filter);
5313  auto input_it = inputs_owned.begin();
5314  for (size_t nest_level = 0; nest_level < data_sink_node->inputCount(); ++nest_level) {
5315  const auto source = data_sink_node->getInput(nest_level);
5316  const auto scan_source = dynamic_cast<const RelScan*>(source);
5317  if (scan_source) {
5318  CHECK(source->getOutputMetainfo().empty());
5319  std::vector<std::shared_ptr<Analyzer::Expr>> scalar_sources_owned;
5320  for (size_t i = 0; i < scan_source->size(); ++i, ++input_it) {
5321  scalar_sources_owned.push_back(translator.translate(input_it->get()));
5322  }
5323  const auto source_metadata =
5324  get_targets_meta(scan_source, get_raw_pointers(scalar_sources_owned));
5325  in_metainfo.insert(
5326  in_metainfo.end(), source_metadata.begin(), source_metadata.end());
5327  exprs_owned.insert(
5328  exprs_owned.end(), scalar_sources_owned.begin(), scalar_sources_owned.end());
5329  } else {
5330  const auto& source_metadata = source->getOutputMetainfo();
5331  input_it += source_metadata.size();
5332  in_metainfo.insert(
5333  in_metainfo.end(), source_metadata.begin(), source_metadata.end());
5334  const auto scalar_sources_owned = synthesize_inputs(
5335  data_sink_node, nest_level, source_metadata, input_to_nest_level);
5336  exprs_owned.insert(
5337  exprs_owned.end(), scalar_sources_owned.begin(), scalar_sources_owned.end());
5338  }
5339  }
5340  return std::make_pair(in_metainfo, exprs_owned);
5341 }
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 1551 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().

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

4303  {
4304  auto sink = get_data_sink(ra);
4305  if (auto join = dynamic_cast<const RelJoin*>(sink)) {
4306  return join->getJoinType();
4307  }
4308  if (dynamic_cast<const RelLeftDeepInnerJoin*>(sink)) {
4309  return JoinType::INNER;
4310  }
4311 
4312  return JoinType::INVALID;
4313 }
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 4436 of file RelAlgExecutor.cpp.

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

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

4437  {
4438  std::vector<size_t> input_sizes;
4439  for (size_t i = 0; i < left_deep_join->inputCount(); ++i) {
4440  const auto inputs = get_node_output(left_deep_join->getInput(i));
4441  input_sizes.push_back(inputs.size());
4442  }
4443  return input_sizes;
4444 }
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 3198 of file RelAlgExecutor.cpp.

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

3198  {
3199  return limit ? *limit : 0;
3200 }

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

1963  {
1964  if (is_count_distinct(&expr)) {
1965  return SQLTypeInfo(kBIGINT, false);
1966  } else if (is_agg(&expr)) {
1968  }
1969  return get_logical_type_info(expr.get_type_info());
1970 }
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 75 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().

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

References shared::transform().

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

4785  {
4786  std::vector<Analyzer::Expr*> output(input.size());
4787  auto const raw_ptr = [](auto& shared_ptr) { return shared_ptr.get(); };
4788  std::transform(input.cbegin(), input.cend(), output.begin(), raw_ptr);
4789  return output;
4790 }
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 1690 of file RelAlgExecutor.cpp.

References RelCompound::getScalarSourcesSize().

Referenced by translate_scalar_sources(), and translate_scalar_sources_for_update().

1690  {
1691  return compound->getScalarSourcesSize();
1692 }
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 1694 of file RelAlgExecutor.cpp.

References RelProject::size().

1694  {
1695  return project->size();
1696 }
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 1698 of file RelAlgExecutor.cpp.

References RelTableFunction::getTableFuncInputsSize().

1698  {
1699  return table_func->getTableFuncInputsSize();
1700 }
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 3202 of file RelAlgExecutor.cpp.

References get_limit_value().

Referenced by RelAlgExecutor::createSortInputWorkUnit().

3202  {
3203  const auto aggregate = dynamic_cast<const RelAggregate*>(ra);
3204  if (aggregate) {
3205  return 0;
3206  }
3207  const auto compound = dynamic_cast<const RelCompound*>(ra);
3208  return (compound && compound->isAggregate()) ? 0 : get_limit_value(limit);
3209 }
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:

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 1973 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().

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

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

1991  {
1992  RelAlgNode const* input0 = filter->getInput(0);
1993  if (auto const* input = dynamic_cast<RelCompound const*>(input0)) {
1994  return get_targets_meta(input, target_exprs);
1995  } else if (auto const* input = dynamic_cast<RelProject const*>(input0)) {
1996  return get_targets_meta(input, target_exprs);
1997  } else if (auto const* input = dynamic_cast<RelLogicalUnion const*>(input0)) {
1998  return get_targets_meta(input, target_exprs);
1999  } else if (auto const* input = dynamic_cast<RelAggregate const*>(input0)) {
2000  return get_targets_meta(input, target_exprs);
2001  } else if (auto const* input = dynamic_cast<RelScan const*>(input0)) {
2002  return get_targets_meta(input, target_exprs);
2003  } else if (auto const* input = dynamic_cast<RelLogicalValues const*>(input0)) {
2004  return get_targets_meta(input, target_exprs);
2005  }
2006  UNREACHABLE() << "Unhandled node type: "
2008  return {};
2009 }
#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 1408 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().

1408  {
1409  RexUsedInputsVisitor visitor;
1410  const auto filter_expr = compound->getFilterExpr();
1411  std::unordered_set<const RexInput*> used_inputs =
1412  filter_expr ? visitor.visit(filter_expr) : std::unordered_set<const RexInput*>{};
1413  const auto sources_size = compound->getScalarSourcesSize();
1414  for (size_t i = 0; i < sources_size; ++i) {
1415  const auto source_inputs = visitor.visit(compound->getScalarSource(i));
1416  used_inputs.insert(source_inputs.begin(), source_inputs.end());
1417  }
1418  std::vector<std::shared_ptr<RexInput>> used_inputs_owned(visitor.get_inputs_owned());
1419  return std::make_pair(used_inputs, used_inputs_owned);
1420 }
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 1423 of file RelAlgExecutor.cpp.

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

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

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

1449  {
1450  RexUsedInputsVisitor visitor;
1451  std::unordered_set<const RexInput*> used_inputs;
1452  for (size_t i = 0; i < project->size(); ++i) {
1453  const auto proj_inputs = visitor.visit(project->getProjectAt(i));
1454  used_inputs.insert(proj_inputs.begin(), proj_inputs.end());
1455  }
1456  std::vector<std::shared_ptr<RexInput>> used_inputs_owned(visitor.get_inputs_owned());
1457  return std::make_pair(used_inputs, used_inputs_owned);
1458 }
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 1461 of file RelAlgExecutor.cpp.

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

1461  {
1462  RexUsedInputsVisitor visitor;
1463  std::unordered_set<const RexInput*> used_inputs;
1464  for (size_t i = 0; i < table_func->getTableFuncInputsSize(); ++i) {
1465  const auto table_func_inputs = visitor.visit(table_func->getTableFuncInputAt(i));
1466  used_inputs.insert(table_func_inputs.begin(), table_func_inputs.end());
1467  }
1468  std::vector<std::shared_ptr<RexInput>> used_inputs_owned(visitor.get_inputs_owned());
1469  return std::make_pair(used_inputs, used_inputs_owned);
1470 }
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 1473 of file RelAlgExecutor.cpp.

References CHECK, and get_data_sink().

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

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

1500  {
1501  std::unordered_set<const RexInput*> used_inputs(logical_union->inputCount());
1502  std::vector<std::shared_ptr<RexInput>> used_inputs_owned;
1503  used_inputs_owned.reserve(logical_union->inputCount());
1504  VLOG(3) << "logical_union->inputCount()=" << logical_union->inputCount();
1505  auto const n_inputs = logical_union->inputCount();
1506  for (size_t nest_level = 0; nest_level < n_inputs; ++nest_level) {
1507  auto input = logical_union->getInput(nest_level);
1508  for (size_t i = 0; i < input->size(); ++i) {
1509  used_inputs_owned.emplace_back(std::make_shared<RexInput>(input, i));
1510  used_inputs.insert(used_inputs_owned.back().get());
1511  }
1512  }
1513  return std::make_pair(std::move(used_inputs), std::move(used_inputs_owned));
1514 }
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 4204 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().

4204  {
4205  // 'designated initializers' don't compile on Windows for std 17
4206  // They require /std:c++20. They been removed for the windows port.
4207  switch (error_code) {
4209  return {"ERR_DIV_BY_ZERO", "Division by zero"};
4211  return {"ERR_OUT_OF_GPU_MEM",
4212 
4213  "Query couldn't keep the entire working set of columns in GPU memory"};
4215  return {"ERR_UNSUPPORTED_SELF_JOIN", "Self joins not supported yet"};
4217  return {"ERR_OUT_OF_CPU_MEM", "Not enough host memory to execute the query"};
4219  return {"ERR_OVERFLOW_OR_UNDERFLOW", "Overflow or underflow"};
4221  return {"ERR_OUT_OF_TIME", "Query execution has exceeded the time limit"};
4223  return {"ERR_INTERRUPTED", "Query execution has been interrupted"};
4225  return {"ERR_COLUMNAR_CONVERSION_NOT_SUPPORTED",
4226  "Columnar conversion not supported for variable length types"};
4228  return {"ERR_TOO_MANY_LITERALS", "Too many literals in the query"};
4230  return {"ERR_STRING_CONST_IN_RESULTSET",
4231 
4232  "NONE ENCODED String types are not supported as input result set."};
4234  return {"ERR_OUT_OF_RENDER_MEM",
4235 
4236  "Insufficient GPU memory for query results in render output buffer "
4237  "sized by render-mem-bytes"};
4239  return {"ERR_STREAMING_TOP_N_NOT_SUPPORTED_IN_RENDER_QUERY",
4240  "Streaming-Top-N not supported in Render Query"};
4242  return {"ERR_SINGLE_VALUE_FOUND_MULTIPLE_VALUES",
4243  "Multiple distinct values encountered"};
4244  case Executor::ERR_GEOS:
4245  return {"ERR_GEOS", "ERR_GEOS"};
4247  return {"ERR_WIDTH_BUCKET_INVALID_ARGUMENT",
4248 
4249  "Arguments of WIDTH_BUCKET function does not satisfy the condition"};
4250  default:
4251  return {nullptr, nullptr};
4252  }
4253 }
static const int32_t ERR_INTERRUPTED
Definition: Execute.h:1621
static const int32_t ERR_GEOS
Definition: Execute.h:1627
static const int32_t ERR_TOO_MANY_LITERALS
Definition: Execute.h:1623
static const int32_t ERR_STRING_CONST_IN_RESULTSET
Definition: Execute.h:1624
static const int32_t ERR_STREAMING_TOP_N_NOT_SUPPORTED_IN_RENDER_QUERY
Definition: Execute.h:1625
static const int32_t ERR_COLUMNAR_CONVERSION_NOT_SUPPORTED
Definition: Execute.h:1622
static const int32_t ERR_DIV_BY_ZERO
Definition: Execute.h:1613
static const int32_t ERR_OUT_OF_RENDER_MEM
Definition: Execute.h:1617
static const int32_t ERR_OVERFLOW_OR_UNDERFLOW
Definition: Execute.h:1619
static const int32_t ERR_OUT_OF_TIME
Definition: Execute.h:1620
static const int32_t ERR_UNSUPPORTED_SELF_JOIN
Definition: Execute.h:1616
static const int32_t ERR_SINGLE_VALUE_FOUND_MULTIPLE_VALUES
Definition: Execute.h:1626
static const int32_t ERR_OUT_OF_GPU_MEM
Definition: Execute.h:1614
static const int32_t ERR_WIDTH_BUCKET_INVALID_ARGUMENT
Definition: Execute.h:1628
def error_code
Definition: report.py:244
static const int32_t ERR_OUT_OF_CPU_MEM
Definition: Execute.h:1618

+ Here is the caller graph for this function:

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

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

Definition at line 3467 of file RelAlgExecutor.cpp.

References CHECK.

Referenced by RelAlgExecutor::executeWorkUnit().

3467  {
3468  CHECK(!table_infos.empty());
3469  const auto& first_table = table_infos.front();
3470  size_t max_num_groups = first_table.info.getNumTuplesUpperBound();
3471  for (const auto& table_info : table_infos) {
3472  if (table_info.info.getNumTuplesUpperBound() > max_num_groups) {
3473  max_num_groups = table_info.info.getNumTuplesUpperBound();
3474  }
3475  }
3476  return std::max(max_num_groups, size_t(1));
3477 }
#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 1035 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.

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

219  {
221 }
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 2794 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().

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

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

2833  {
2834  return insert_one_dict_str(col_data, cd->columnName, cd->columnType, col_cv, catalog);
2835 }
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 1950 of file RelAlgExecutor.cpp.

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

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

1950  {
1951  const auto agg_expr = dynamic_cast<const Analyzer::AggExpr*>(expr);
1952  if (agg_expr && agg_expr->get_contains_agg()) {
1953  auto agg_type = agg_expr->get_aggtype();
1954  if (agg_type == SQLAgg::kMIN || agg_type == SQLAgg::kMAX ||
1955  agg_type == SQLAgg::kSUM || agg_type == SQLAgg::kSUM_IF ||
1956  agg_type == SQLAgg::kAVG) {
1957  return true;
1958  }
1959  }
1960  return false;
1961 }
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 1945 of file RelAlgExecutor.cpp.

References Analyzer::AggExpr::get_is_distinct().

Referenced by get_logical_type_for_expr().

1945  {
1946  const auto agg_expr = dynamic_cast<const Analyzer::AggExpr*>(expr);
1947  return agg_expr && agg_expr->get_is_distinct();
1948 }
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_projection ( const RelAlgExecutionUnit ra_exe_unit)

Definition at line 3479 of file RelAlgExecutor.cpp.

References RelAlgExecutionUnit::groupby_exprs.

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

3479  {
3480  return ra_exe_unit.groupby_exprs.size() == 1 && !ra_exe_unit.groupby_exprs.front();
3481 }
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 2312 of file RelAlgExecutor.cpp.

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

Referenced by RelAlgExecutor::executeWorkUnit().

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

4383  {
4384  CHECK_GE(left_deep_join->inputCount(), size_t(2));
4385  std::vector<JoinType> join_types(left_deep_join->inputCount() - 1, JoinType::INNER);
4386  for (size_t nesting_level = 1; nesting_level <= left_deep_join->inputCount() - 1;
4387  ++nesting_level) {
4388  if (left_deep_join->getOuterCondition(nesting_level)) {
4389  join_types[nesting_level - 1] = JoinType::LEFT;
4390  }
4391  auto cur_level_join_type = left_deep_join->getJoinType(nesting_level);
4392  if (cur_level_join_type == JoinType::SEMI || cur_level_join_type == JoinType::ANTI) {
4393  join_types[nesting_level - 1] = cur_level_join_type;
4394  }
4395  }
4396  return join_types;
4397 }
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 4621 of file RelAlgExecutor.cpp.

Referenced by reverse_logical_distribution().

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

+ Here is the caller graph for this function:

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

Definition at line 69 of file RelAlgExecutor.cpp.

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

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

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

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

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

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

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

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

4635  {
4636  const auto expr_terms = qual_to_disjunctive_form(expr);
4637  CHECK_GE(expr_terms.size(), size_t(1));
4638  const auto& first_term = expr_terms.front();
4639  const auto first_term_factors = qual_to_conjunctive_form(first_term);
4640  std::vector<std::shared_ptr<Analyzer::Expr>> common_factors;
4641  // First, collect the conjunctive components common to all the disjunctive components.
4642  // Don't do it for simple qualifiers, we only care about expensive or join qualifiers.
4643  for (const auto& first_term_factor : first_term_factors.quals) {
4644  bool is_common =
4645  expr_terms.size() > 1; // Only report common factors for disjunction.
4646  for (size_t i = 1; i < expr_terms.size(); ++i) {
4647  const auto crt_term_factors = qual_to_conjunctive_form(expr_terms[i]);
4648  if (!list_contains_expression(crt_term_factors.quals, first_term_factor)) {
4649  is_common = false;
4650  break;
4651  }
4652  }
4653  if (is_common) {
4654  common_factors.push_back(first_term_factor);
4655  }
4656  }
4657  if (common_factors.empty()) {
4658  return expr;
4659  }
4660  // Now that the common expressions are known, collect the remaining expressions.
4661  std::vector<std::shared_ptr<Analyzer::Expr>> remaining_terms;
4662  for (const auto& term : expr_terms) {
4663  const auto term_cf = qual_to_conjunctive_form(term);
4664  std::vector<std::shared_ptr<Analyzer::Expr>> remaining_quals(
4665  term_cf.simple_quals.begin(), term_cf.simple_quals.end());
4666  for (const auto& qual : term_cf.quals) {
4667  if (!list_contains_expression(common_factors, qual)) {
4668  remaining_quals.push_back(qual);
4669  }
4670  }
4671  if (!remaining_quals.empty()) {
4672  remaining_terms.push_back(build_logical_expression(remaining_quals, kAND));
4673  }
4674  }
4675  // Reconstruct the expression with the transformation applied.
4676  const auto common_expr = build_logical_expression(common_factors, kAND);
4677  if (remaining_terms.empty()) {
4678  return common_expr;
4679  }
4680  const auto remaining_expr = build_logical_expression(remaining_terms, kOR);
4681  return Parser::OperExpr::normalize(kAND, kONE, common_expr, remaining_expr);
4682 }
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 4446 of file RelAlgExecutor.cpp.

References rewrite_expr().

Referenced by RelAlgExecutor::createCompoundWorkUnit().

4447  {
4448  std::list<std::shared_ptr<Analyzer::Expr>> rewritten_quals;
4449  for (const auto& qual : quals) {
4450  const auto rewritten_qual = rewrite_expr(qual.get());
4451  rewritten_quals.push_back(rewritten_qual ? rewritten_qual : qual);
4452  }
4453  return rewritten_quals;
4454 }
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 4594 of file RelAlgExecutor.cpp.

References CHECK, CHECK_GE, and kAND.

Referenced by RelAlgExecutor::makeJoinQuals().

4594  {
4595  CHECK(qual_expr);
4596  const auto bin_oper = dynamic_cast<const RexOperator*>(qual_expr);
4597  if (!bin_oper || bin_oper->getOperator() != kAND) {
4598  return {qual_expr};
4599  }
4600  CHECK_GE(bin_oper->size(), size_t(2));
4601  auto lhs_cf = rex_to_conjunctive_form(bin_oper->getOperand(0));
4602  for (size_t i = 1; i < bin_oper->size(); ++i) {
4603  const auto rhs_cf = rex_to_conjunctive_form(bin_oper->getOperand(i));
4604  lhs_cf.insert(lhs_cf.end(), rhs_cf.begin(), rhs_cf.end());
4605  }
4606  return lhs_cf;
4607 }
#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 1702 of file RelAlgExecutor.cpp.

References RelCompound::getScalarSource().

Referenced by translate_scalar_sources(), and translate_scalar_sources_for_update().

1702  {
1703  return compound->getScalarSource(i);
1704 }
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 1706 of file RelAlgExecutor.cpp.

References RelProject::getProjectAt().

1706  {
1707  return project->getProjectAt(i);
1708 }
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 1710 of file RelAlgExecutor.cpp.

References RelTableFunction::getTableFuncInputAt().

1710  {
1711  return table_func->getTableFuncInputAt(i);
1712 }
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 88 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().

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

1715  {
1716  const auto& ti = expr->get_type_info();
1717  if (!ti.is_string() || ti.get_compression() != kENCODING_NONE) {
1718  return expr;
1719  }
1720  auto transient_dict_ti = ti;
1721  transient_dict_ti.set_compression(kENCODING_DICT);
1722  transient_dict_ti.set_comp_param(TRANSIENT_DICT_ID);
1723  transient_dict_ti.setStringDictKey(shared::StringDictKey::kTransientDictKey);
1724  transient_dict_ti.set_fixed_size();
1725  return expr->add_cast(transient_dict_ti);
1726 }
#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 1728 of file RelAlgExecutor.cpp.

References fold_expr(), and set_transient_dict().

Referenced by translate_scalar_sources(), and translate_scalar_sources_for_update().

1730  {
1731  try {
1732  scalar_sources.push_back(set_transient_dict(fold_expr(expr.get())));
1733  } catch (...) {
1734  scalar_sources.push_back(fold_expr(expr.get()));
1735  }
1736 }
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 3523 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().

3523  {
3524  for (const auto& target_expr : ra_exe_unit.target_exprs) {
3525  if (target_expr->get_type_info().usesFlatBuffer()) {
3526  // using FlatBuffer memory layout implies columnar-only output
3527  return true;
3528  }
3529  }
3532 }
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 4759 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().

4763  {
4764  CHECK_LE(size_t(1), ra_node->inputCount());
4765  CHECK_GE(size_t(2), ra_node->inputCount());
4766  const auto input = ra_node->getInput(nest_level);
4767  const auto it_rte_idx = input_to_nest_level.find(input);
4768  CHECK(it_rte_idx != input_to_nest_level.end());
4769  const int rte_idx = it_rte_idx->second;
4770  const auto table_key = table_key_from_ra(input);
4771  std::vector<std::shared_ptr<Analyzer::Expr>> inputs;
4772  const auto scan_ra = dynamic_cast<const RelScan*>(input);
4773  int input_idx = 0;
4774  for (const auto& input_meta : in_metainfo) {
4775  inputs.push_back(std::make_shared<Analyzer::ColumnVar>(
4776  input_meta.get_type_info(),
4777  shared::ColumnKey{table_key, scan_ra ? input_idx + 1 : input_idx},
4778  rte_idx));
4779  ++input_idx;
4780  }
4781  return inputs;
4782 }
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 1516 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().

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

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

Referenced by RelAlgExecutor::createUnionWorkUnit().

4973  {
4974  std::vector<TargetMetaInfo> const& tmis = input_node->getOutputMetainfo();
4975  VLOG(3) << "input_node->getOutputMetainfo()=" << shared::printContainer(tmis);
4976  const int negative_node_id = -input_node->getId();
4977  int32_t db_id{0};
4978  if (auto rel_scan = dynamic_cast<const RelScan*>(input_node)) {
4979  db_id = rel_scan->getCatalog().getDatabaseId();
4980  }
4981  std::vector<std::shared_ptr<Analyzer::Expr>> target_exprs;
4982  target_exprs.reserve(tmis.size());
4983  for (size_t i = 0; i < tmis.size(); ++i) {
4984  target_exprs.push_back(std::make_shared<Analyzer::ColumnVar>(
4985  tmis[i].get_type_info(),
4986  shared::ColumnKey{db_id, negative_node_id, int32_t(i)},
4987  0));
4988  }
4989  return target_exprs;
4990 }
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 2462 of file RelAlgExecutor.cpp.

Referenced by RelAlgExecutor::computeWindow().

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

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

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

1816  {
1817  if (!compound->isAggregate()) {
1818  return {nullptr};
1819  }
1820  std::list<std::shared_ptr<Analyzer::Expr>> groupby_exprs;
1821  for (size_t group_idx = 0; group_idx < compound->getGroupByCount(); ++group_idx) {
1822  groupby_exprs.push_back(set_transient_dict(scalar_sources[group_idx]));
1823  }
1824  return groupby_exprs;
1825 }
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 1827 of file RelAlgExecutor.cpp.

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

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

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

Referenced by RelAlgExecutor::createCompoundWorkUnit().

1838  {
1839  const auto filter_rex = compound->getFilterExpr();
1840  const auto filter_expr = filter_rex ? translator.translate(filter_rex) : nullptr;
1841  return filter_expr ? qual_to_conjunctive_form(fold_expr(filter_expr.get()))
1843 }
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 1748 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().

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

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

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

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

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

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