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

Namespaces

 anonymous_namespace{RelAlgExecutor.cpp}
 

Classes

class  RexUsedInputsVisitor
 
struct  ErrorInfo
 

Functions

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

Function Documentation

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

Definition at line 4664 of file RelAlgExecutor.cpp.

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

Referenced by reverse_logical_distribution().

4666  {
4667  CHECK(!factors.empty());
4668  auto acc = factors.front();
4669  for (size_t i = 1; i < factors.size(); ++i) {
4670  acc = Parser::OperExpr::normalize(sql_op, kONE, acc, factors[i]);
4671  }
4672  return acc;
4673 }
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:380
Definition: sqldefs.h:74
#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 3488 of file RelAlgExecutor.cpp.

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

Referenced by RelAlgExecutor::executeWorkUnit().

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

3647  {
3649  !eo.output_columnar_hint && ra_exe_unit.sort_info.order_entries.empty();
3650 }
std::list< Analyzer::OrderEntry > order_entries
ExecutorDeviceType device_type
bool g_enable_bump_allocator
Definition: Execute.cpp:132

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

References kENCODING_DICT, and kTEXT.

Referenced by translate_scalar_sources(), and translate_targets().

1746  {
1747  const auto& input_ti = input->get_type_info();
1748  if (input_ti.is_string() && input_ti.get_compression() == kENCODING_DICT) {
1749  return input->add_cast(SQLTypeInfo(kTEXT, input_ti.get_notnull()));
1750  }
1751  return input;
1752 }
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 449 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().

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

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

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

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

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

Referenced by get_input_desc_impl().

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

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

Referenced by RelAlgExecutor::executeWorkUnit().

3545  {
3546  for (const auto target_expr : ra_exe_unit.target_exprs) {
3547  if (dynamic_cast<const Analyzer::AggExpr*>(target_expr)) {
3548  return false;
3549  }
3550  }
3551  size_t preflight_count_query_threshold = g_preflight_count_query_threshold;
3553  preflight_count_query_threshold =
3555  VLOG(1) << "Set the pre-flight count query's threshold as "
3556  << preflight_count_query_threshold << " by a query hint";
3557  }
3558  if (is_projection(ra_exe_unit) &&
3559  (!ra_exe_unit.scan_limit ||
3560  ra_exe_unit.scan_limit > preflight_count_query_threshold)) {
3561  return true;
3562  }
3563  return false;
3564 }
std::vector< Analyzer::Expr * > target_exprs
size_t g_preflight_count_query_threshold
Definition: Execute.cpp:84
size_t preflight_count_query_threshold
Definition: QueryHint.h:350
bool is_projection(const RelAlgExecutionUnit &ra_exe_unit)
bool isHintRegistered(const QueryHint hint) const
Definition: QueryHint.h:398
RegisteredQueryHint query_hint
#define VLOG(n)
Definition: Logger.h:388

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

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

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

4462  {
4463  if (g_cluster) {
4464  // Disable table reordering in distributed mode. The aggregator does not have enough
4465  // information to break ties
4466  return {};
4467  }
4468  if (node->isUpdateViaSelect() || node->isDeleteViaSelect()) {
4469  // Do not reorder tables for UPDATE and DELETE queries, since the outer table always
4470  // has to be the physical table.
4471  return {};
4472  }
4473  for (const auto& table_info : query_infos) {
4474  if (table_info.table_key.table_id < 0) {
4475  continue;
4476  }
4477  const auto td = Catalog_Namespace::get_metadata_for_table(table_info.table_key);
4478  CHECK(td);
4479  if (table_is_replicated(td)) {
4480  return {};
4481  }
4482  }
4483  const auto input_permutation =
4484  get_node_input_permutation(left_deep_join_quals, query_infos, executor);
4485  input_to_nest_level = get_input_nest_levels(node, input_permutation);
4486  std::tie(input_descs, input_col_descs, std::ignore) =
4487  get_input_desc(node, input_to_nest_level, input_permutation);
4488  return input_permutation;
4489 }
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 3566 of file RelAlgExecutor.cpp.

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

Referenced by RelAlgExecutor::executeWorkUnit().

3566  {
3567  return !(ra_exe_unit.quals.empty() && ra_exe_unit.join_quals.empty() &&
3568  ra_exe_unit.simple_quals.empty());
3569 }
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 3222 of file RelAlgExecutor.cpp.

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

3222  {
3223  return !order_entries.empty() && order_entries.front().is_desc;
3224 }

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

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

Referenced by get_bitwise_equals_conjunction().

4370  {
4371  const auto condition = dynamic_cast<const RexOperator*>(scalar);
4372  if (!condition || condition->getOperator() != kOR || condition->size() != 2) {
4373  return nullptr;
4374  }
4375  const auto equi_join_condition =
4376  dynamic_cast<const RexOperator*>(condition->getOperand(0));
4377  if (!equi_join_condition || equi_join_condition->getOperator() != kEQ) {
4378  return nullptr;
4379  }
4380  const auto both_are_null_condition =
4381  dynamic_cast<const RexOperator*>(condition->getOperand(1));
4382  if (!both_are_null_condition || both_are_null_condition->getOperator() != kAND ||
4383  both_are_null_condition->size() != 2) {
4384  return nullptr;
4385  }
4386  const auto lhs_is_null =
4387  dynamic_cast<const RexOperator*>(both_are_null_condition->getOperand(0));
4388  const auto rhs_is_null =
4389  dynamic_cast<const RexOperator*>(both_are_null_condition->getOperand(1));
4390  if (!lhs_is_null || !rhs_is_null || lhs_is_null->getOperator() != kISNULL ||
4391  rhs_is_null->getOperator() != kISNULL) {
4392  return nullptr;
4393  }
4394  CHECK_EQ(size_t(1), lhs_is_null->size());
4395  CHECK_EQ(size_t(1), rhs_is_null->size());
4396  CHECK_EQ(size_t(2), equi_join_condition->size());
4397  const auto eq_lhs = dynamic_cast<const RexInput*>(equi_join_condition->getOperand(0));
4398  const auto eq_rhs = dynamic_cast<const RexInput*>(equi_join_condition->getOperand(1));
4399  const auto is_null_lhs = dynamic_cast<const RexInput*>(lhs_is_null->getOperand(0));
4400  const auto is_null_rhs = dynamic_cast<const RexInput*>(rhs_is_null->getOperand(0));
4401  if (!eq_lhs || !eq_rhs || !is_null_lhs || !is_null_rhs) {
4402  return nullptr;
4403  }
4404  std::vector<std::unique_ptr<const RexScalar>> eq_operands;
4405  if (*eq_lhs == *is_null_lhs && *eq_rhs == *is_null_rhs) {
4406  RexDeepCopyVisitor deep_copy_visitor;
4407  auto lhs_op_copy = deep_copy_visitor.visit(equi_join_condition->getOperand(0));
4408  auto rhs_op_copy = deep_copy_visitor.visit(equi_join_condition->getOperand(1));
4409  eq_operands.emplace_back(lhs_op_copy.release());
4410  eq_operands.emplace_back(rhs_op_copy.release());
4411  return boost::make_unique<const RexOperator>(
4412  kBW_EQ, eq_operands, equi_join_condition->getType());
4413  }
4414  return nullptr;
4415 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
Definition: sqldefs.h:40
Definition: sqldefs.h:32
virtual T visit(const RexScalar *rex_scalar) const
Definition: RexVisitor.h:27
Definition: sqldefs.h:39
Definition: sqldefs.h:33

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

References CHECK_GE, get_bitwise_equals(), and kAND.

Referenced by RelAlgExecutor::makeJoinQuals().

4418  {
4419  const auto condition = dynamic_cast<const RexOperator*>(scalar);
4420  if (condition && condition->getOperator() == kAND) {
4421  CHECK_GE(condition->size(), size_t(2));
4422  auto acc = get_bitwise_equals(condition->getOperand(0));
4423  if (!acc) {
4424  return nullptr;
4425  }
4426  for (size_t i = 1; i < condition->size(); ++i) {
4427  std::vector<std::unique_ptr<const RexScalar>> and_operands;
4428  and_operands.emplace_back(std::move(acc));
4429  and_operands.emplace_back(get_bitwise_equals_conjunction(condition->getOperand(i)));
4430  acc =
4431  boost::make_unique<const RexOperator>(kAND, and_operands, condition->getType());
4432  }
4433  return acc;
4434  }
4435  return get_bitwise_equals(scalar);
4436 }
std::unique_ptr< const RexOperator > get_bitwise_equals_conjunction(const RexScalar *scalar)
#define CHECK_GE(x, y)
Definition: Logger.h:306
Definition: sqldefs.h:39
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 1397 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().

1397  {
1398  if (auto table_func = dynamic_cast<const RelTableFunction*>(ra_node)) {
1399  return table_func;
1400  }
1401  if (auto join = dynamic_cast<const RelJoin*>(ra_node)) {
1402  CHECK_EQ(size_t(2), join->inputCount());
1403  return join;
1404  }
1405  if (!dynamic_cast<const RelLogicalUnion*>(ra_node)) {
1406  CHECK_EQ(size_t(1), ra_node->inputCount());
1407  }
1408  auto only_src = ra_node->getInput(0);
1409  const bool is_join = dynamic_cast<const RelJoin*>(only_src) ||
1410  dynamic_cast<const RelLeftDeepInnerJoin*>(only_src);
1411  return is_join ? only_src : ra_node;
1412 }
#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 1684 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().

1686  {
1687  std::unordered_set<const RexInput*> used_inputs;
1688  std::vector<std::shared_ptr<RexInput>> used_inputs_owned;
1689  std::tie(used_inputs, used_inputs_owned) = get_used_inputs(ra_node);
1690  VLOG(3) << "used_inputs.size() = " << used_inputs.size();
1691  auto input_desc_pair =
1692  get_input_desc_impl(ra_node, used_inputs, input_to_nest_level, input_permutation);
1693  return std::make_tuple(
1694  input_desc_pair.first, input_desc_pair.second, used_inputs_owned);
1695 }
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 1633 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().

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

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

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

Referenced by RelAlgExecutor::createFilterWorkUnit().

5364  {
5365  std::vector<TargetMetaInfo> in_metainfo;
5366  std::vector<std::shared_ptr<Analyzer::Expr>> exprs_owned;
5367  const auto data_sink_node = get_data_sink(filter);
5368  auto input_it = inputs_owned.begin();
5369  for (size_t nest_level = 0; nest_level < data_sink_node->inputCount(); ++nest_level) {
5370  const auto source = data_sink_node->getInput(nest_level);
5371  const auto scan_source = dynamic_cast<const RelScan*>(source);
5372  if (scan_source) {
5373  CHECK(source->getOutputMetainfo().empty());
5374  std::vector<std::shared_ptr<Analyzer::Expr>> scalar_sources_owned;
5375  for (size_t i = 0; i < scan_source->size(); ++i, ++input_it) {
5376  scalar_sources_owned.push_back(translator.translate(input_it->get()));
5377  }
5378  const auto source_metadata =
5379  get_targets_meta(scan_source, get_raw_pointers(scalar_sources_owned));
5380  in_metainfo.insert(
5381  in_metainfo.end(), source_metadata.begin(), source_metadata.end());
5382  exprs_owned.insert(
5383  exprs_owned.end(), scalar_sources_owned.begin(), scalar_sources_owned.end());
5384  } else {
5385  const auto& source_metadata = source->getOutputMetainfo();
5386  input_it += source_metadata.size();
5387  in_metainfo.insert(
5388  in_metainfo.end(), source_metadata.begin(), source_metadata.end());
5389  const auto scalar_sources_owned = synthesize_inputs(
5390  data_sink_node, nest_level, source_metadata, input_to_nest_level);
5391  exprs_owned.insert(
5392  exprs_owned.end(), scalar_sources_owned.begin(), scalar_sources_owned.end());
5393  }
5394  }
5395  return std::make_pair(in_metainfo, exprs_owned);
5396 }
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 1558 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().

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

4358  {
4359  auto sink = get_data_sink(ra);
4360  if (auto join = dynamic_cast<const RelJoin*>(sink)) {
4361  return join->getJoinType();
4362  }
4363  if (dynamic_cast<const RelLeftDeepInnerJoin*>(sink)) {
4364  return JoinType::INNER;
4365  }
4366 
4367  return JoinType::INVALID;
4368 }
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 4491 of file RelAlgExecutor.cpp.

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

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

4492  {
4493  std::vector<size_t> input_sizes;
4494  for (size_t i = 0; i < left_deep_join->inputCount(); ++i) {
4495  const auto inputs = get_node_output(left_deep_join->getInput(i));
4496  input_sizes.push_back(inputs.size());
4497  }
4498  return input_sizes;
4499 }
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 3209 of file RelAlgExecutor.cpp.

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

3209  {
3210  return limit ? *limit : 0;
3211 }

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

1972  {
1973  if (is_count_distinct(expr)) {
1974  return SQLTypeInfo(kBIGINT, true);
1975  } else if (is_agg(expr)) {
1977  }
1978  return get_logical_type_info(expr->get_type_info());
1979 }
bool is_agg(const Analyzer::Expr *expr)
SQLTypeInfo get_nullable_logical_type_info(const SQLTypeInfo &type_info)
Definition: sqltypes.h:1490
SQLTypeInfo get_logical_type_info(const SQLTypeInfo &type_info)
Definition: sqltypes.h:1472
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 77 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().

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

References shared::transform().

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

4840  {
4841  std::vector<Analyzer::Expr*> output(input.size());
4842  auto const raw_ptr = [](auto& shared_ptr) { return shared_ptr.get(); };
4843  std::transform(input.cbegin(), input.cend(), output.begin(), raw_ptr);
4844  return output;
4845 }
OUTPUT transform(INPUT const &input, FUNC const &func)
Definition: misc.h:329

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

References RelCompound::getScalarSourcesSize().

Referenced by translate_scalar_sources(), and translate_scalar_sources_for_update().

1697  {
1698  return compound->getScalarSourcesSize();
1699 }
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 1701 of file RelAlgExecutor.cpp.

References RelProject::size().

1701  {
1702  return project->size();
1703 }
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 1705 of file RelAlgExecutor.cpp.

References RelTableFunction::getTableFuncInputsSize().

1705  {
1706  return table_func->getTableFuncInputsSize();
1707 }
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 3213 of file RelAlgExecutor.cpp.

References get_limit_value().

Referenced by RelAlgExecutor::createSortInputWorkUnit().

3213  {
3214  const auto aggregate = dynamic_cast<const RelAggregate*>(ra);
3215  if (aggregate) {
3216  return 0;
3217  }
3218  const auto compound = dynamic_cast<const RelCompound*>(ra);
3219  return (compound && compound->isAggregate()) ? 0 : get_limit_value(limit);
3220 }
size_t get_limit_value(std::optional< size_t > limit)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 4054 of file RelAlgExecutor.cpp.

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

Referenced by RelAlgExecutor::getFilteredCountAll().

4054  {
4055  std::string table_name{""};
4056  if (table_key.db_id > 0) {
4057  auto catalog = Catalog_Namespace::SysCatalog::instance().getCatalog(table_key.db_id);
4058  CHECK(catalog);
4059  auto td = catalog->getMetadataForTable(table_key.table_id);
4060  CHECK(td);
4061  table_name = td->tableName;
4062  }
4063  return table_name;
4064 }
static SysCatalog & instance()
Definition: SysCatalog.h:343
std::shared_ptr< Catalog > getCatalog(const std::string &dbName)
#define CHECK(condition)
Definition: Logger.h:291

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

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

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

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

2000  {
2001  RelAlgNode const* input0 = filter->getInput(0);
2002  if (auto const* input = dynamic_cast<RelCompound const*>(input0)) {
2003  return get_targets_meta(input, target_exprs);
2004  } else if (auto const* input = dynamic_cast<RelProject const*>(input0)) {
2005  return get_targets_meta(input, target_exprs);
2006  } else if (auto const* input = dynamic_cast<RelLogicalUnion const*>(input0)) {
2007  return get_targets_meta(input, target_exprs);
2008  } else if (auto const* input = dynamic_cast<RelAggregate const*>(input0)) {
2009  return get_targets_meta(input, target_exprs);
2010  } else if (auto const* input = dynamic_cast<RelScan const*>(input0)) {
2011  return get_targets_meta(input, target_exprs);
2012  } else if (auto const* input = dynamic_cast<RelLogicalValues const*>(input0)) {
2013  return get_targets_meta(input, target_exprs);
2014  }
2015  UNREACHABLE() << "Unhandled node type: "
2017  return {};
2018 }
#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 1415 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().

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

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

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

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

1456  {
1457  RexUsedInputsVisitor visitor;
1458  std::unordered_set<const RexInput*> used_inputs;
1459  for (size_t i = 0; i < project->size(); ++i) {
1460  const auto proj_inputs = visitor.visit(project->getProjectAt(i));
1461  used_inputs.insert(proj_inputs.begin(), proj_inputs.end());
1462  }
1463  std::vector<std::shared_ptr<RexInput>> used_inputs_owned(visitor.get_inputs_owned());
1464  return std::make_pair(used_inputs, used_inputs_owned);
1465 }
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 1468 of file RelAlgExecutor.cpp.

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

1468  {
1469  RexUsedInputsVisitor visitor;
1470  std::unordered_set<const RexInput*> used_inputs;
1471  for (size_t i = 0; i < table_func->getTableFuncInputsSize(); ++i) {
1472  const auto table_func_inputs = visitor.visit(table_func->getTableFuncInputAt(i));
1473  used_inputs.insert(table_func_inputs.begin(), table_func_inputs.end());
1474  }
1475  std::vector<std::shared_ptr<RexInput>> used_inputs_owned(visitor.get_inputs_owned());
1476  return std::make_pair(used_inputs, used_inputs_owned);
1477 }
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 1480 of file RelAlgExecutor.cpp.

References CHECK, and get_data_sink().

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

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

1507  {
1508  std::unordered_set<const RexInput*> used_inputs(logical_union->inputCount());
1509  std::vector<std::shared_ptr<RexInput>> used_inputs_owned;
1510  used_inputs_owned.reserve(logical_union->inputCount());
1511  VLOG(3) << "logical_union->inputCount()=" << logical_union->inputCount();
1512  auto const n_inputs = logical_union->inputCount();
1513  for (size_t nest_level = 0; nest_level < n_inputs; ++nest_level) {
1514  auto input = logical_union->getInput(nest_level);
1515  for (size_t i = 0; i < input->size(); ++i) {
1516  used_inputs_owned.emplace_back(std::make_shared<RexInput>(input, i));
1517  used_inputs.insert(used_inputs_owned.back().get());
1518  }
1519  }
1520  return std::make_pair(std::move(used_inputs), std::move(used_inputs_owned));
1521 }
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 4301 of file RelAlgExecutor.cpp.

References report::error_code(), and to_string().

Referenced by RelAlgExecutor::getErrorMessageFromCode().

4301  {
4302  // 'designated initializers' don't compile on Windows for std 17
4303  // They require /std:c++20. They been removed for the windows port.
4304  if (0 < error_code && error_code < int32_t(ErrorCode::N_)) {
4305  auto const ec = static_cast<ErrorCode>(error_code);
4306  return {to_string(ec), to_description(ec)};
4307  }
4308  return {nullptr, nullptr};
4309 }
std::string to_string(char const *&&v)
def error_code
Definition: report.py:234

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

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

Definition at line 3469 of file RelAlgExecutor.cpp.

References CHECK.

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

3470  {
3471  CHECK(!table_infos.empty());
3472  const auto& first_table = table_infos.front();
3473  size_t max_num_groups = first_table.info.getNumTuplesUpperBound();
3474  auto table_key = first_table.table_key;
3475  for (const auto& table_info : table_infos) {
3476  if (table_info.info.getNumTuplesUpperBound() > max_num_groups) {
3477  max_num_groups = table_info.info.getNumTuplesUpperBound();
3478  table_key = table_info.table_key;
3479  }
3480  }
3481  return std::make_pair(std::max(max_num_groups, size_t(1)), table_key);
3482 }
#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 1037 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, kTableReorderingOff, 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, ExecutionOptions::table_reordering, VLOG, ExecutionOptions::with_dynamic_watchdog, and ExecutionOptions::with_watchdog.

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

References EMPTY_HASHED_PLAN_DAG_KEY, and RelAlgNode::getQueryPlanDagHash().

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

221  {
223 }
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 2805 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().

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

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

2844  {
2845  return insert_one_dict_str(col_data, cd->columnName, cd->columnType, col_cv, catalog);
2846 }
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 1957 of file RelAlgExecutor.cpp.

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

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

1957  {
1958  const auto agg_expr = dynamic_cast<const Analyzer::AggExpr*>(expr);
1959  if (agg_expr && agg_expr->get_contains_agg()) {
1960  auto agg_type = agg_expr->get_aggtype();
1962  SQLAgg::kMAX,
1963  SQLAgg::kSUM,
1965  SQLAgg::kAVG>(agg_type)) {
1966  return true;
1967  }
1968  }
1969  return false;
1970 }
bool is_any(T &&value)
Definition: misc.h:267
Definition: sqldefs.h:78
Definition: sqldefs.h:80
SQLAgg get_aggtype() const
Definition: Analyzer.h:1329
Definition: sqldefs.h:79
Definition: sqldefs.h:77

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

References Analyzer::AggExpr::get_is_distinct().

Referenced by get_logical_type_for_expr().

1952  {
1953  const auto agg_expr = dynamic_cast<const Analyzer::AggExpr*>(expr);
1954  return agg_expr && agg_expr->get_is_distinct();
1955 }
bool get_is_distinct() const
Definition: Analyzer.h:1332

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 3226 of file RelAlgExecutor.cpp.

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

Referenced by RelAlgExecutor::executeSort().

3226  {
3227  return target_meta_info.get_type_info().is_none_encoded_string();
3228 }

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

References RelAlgExecutionUnit::groupby_exprs.

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

3484  {
3485  return ra_exe_unit.groupby_exprs.size() == 1 && !ra_exe_unit.groupby_exprs.front();
3486 }
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 2321 of file RelAlgExecutor.cpp.

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

Referenced by RelAlgExecutor::executeWorkUnit().

2321  {
2322  return std::any_of(ra_exe_unit.target_exprs.begin(),
2323  ra_exe_unit.target_exprs.end(),
2324  [](const Analyzer::Expr* expr) {
2325  return dynamic_cast<const Analyzer::WindowFunction*>(expr);
2326  });
2327 }
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 4438 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().

4438  {
4439  CHECK_GE(left_deep_join->inputCount(), size_t(2));
4440  std::vector<JoinType> join_types(left_deep_join->inputCount() - 1, JoinType::INNER);
4441  for (size_t nesting_level = 1; nesting_level <= left_deep_join->inputCount() - 1;
4442  ++nesting_level) {
4443  if (left_deep_join->getOuterCondition(nesting_level)) {
4444  join_types[nesting_level - 1] = JoinType::LEFT;
4445  }
4446  auto cur_level_join_type = left_deep_join->getJoinType(nesting_level);
4447  if (cur_level_join_type == JoinType::SEMI || cur_level_join_type == JoinType::ANTI) {
4448  join_types[nesting_level - 1] = cur_level_join_type;
4449  }
4450  }
4451  return join_types;
4452 }
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 4676 of file RelAlgExecutor.cpp.

Referenced by reverse_logical_distribution().

4677  {
4678  for (const auto& qual : haystack) {
4679  if (*qual == *needle) {
4680  return true;
4681  }
4682  }
4683  return false;
4684 }

+ Here is the caller graph for this function:

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

Definition at line 71 of file RelAlgExecutor.cpp.

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

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

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

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

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

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

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

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

4690  {
4691  const auto expr_terms = qual_to_disjunctive_form(expr);
4692  CHECK_GE(expr_terms.size(), size_t(1));
4693  const auto& first_term = expr_terms.front();
4694  const auto first_term_factors = qual_to_conjunctive_form(first_term);
4695  std::vector<std::shared_ptr<Analyzer::Expr>> common_factors;
4696  // First, collect the conjunctive components common to all the disjunctive components.
4697  // Don't do it for simple qualifiers, we only care about expensive or join qualifiers.
4698  for (const auto& first_term_factor : first_term_factors.quals) {
4699  bool is_common =
4700  expr_terms.size() > 1; // Only report common factors for disjunction.
4701  for (size_t i = 1; i < expr_terms.size(); ++i) {
4702  const auto crt_term_factors = qual_to_conjunctive_form(expr_terms[i]);
4703  if (!list_contains_expression(crt_term_factors.quals, first_term_factor)) {
4704  is_common = false;
4705  break;
4706  }
4707  }
4708  if (is_common) {
4709  common_factors.push_back(first_term_factor);
4710  }
4711  }
4712  if (common_factors.empty()) {
4713  return expr;
4714  }
4715  // Now that the common expressions are known, collect the remaining expressions.
4716  std::vector<std::shared_ptr<Analyzer::Expr>> remaining_terms;
4717  for (const auto& term : expr_terms) {
4718  const auto term_cf = qual_to_conjunctive_form(term);
4719  std::vector<std::shared_ptr<Analyzer::Expr>> remaining_quals(
4720  term_cf.simple_quals.begin(), term_cf.simple_quals.end());
4721  for (const auto& qual : term_cf.quals) {
4722  if (!list_contains_expression(common_factors, qual)) {
4723  remaining_quals.push_back(qual);
4724  }
4725  }
4726  if (!remaining_quals.empty()) {
4727  remaining_terms.push_back(build_logical_expression(remaining_quals, kAND));
4728  }
4729  }
4730  // Reconstruct the expression with the transformation applied.
4731  const auto common_expr = build_logical_expression(common_factors, kAND);
4732  if (remaining_terms.empty()) {
4733  return common_expr;
4734  }
4735  const auto remaining_expr = build_logical_expression(remaining_terms, kOR);
4736  return Parser::OperExpr::normalize(kAND, kONE, common_expr, remaining_expr);
4737 }
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:380
Definition: sqldefs.h:40
#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:39
std::shared_ptr< Analyzer::Expr > build_logical_expression(const std::vector< std::shared_ptr< Analyzer::Expr >> &factors, const SQLOps sql_op)
Definition: sqldefs.h:74
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 4501 of file RelAlgExecutor.cpp.

References rewrite_expr().

Referenced by RelAlgExecutor::createCompoundWorkUnit().

4502  {
4503  std::list<std::shared_ptr<Analyzer::Expr>> rewritten_quals;
4504  for (const auto& qual : quals) {
4505  const auto rewritten_qual = rewrite_expr(qual.get());
4506  rewritten_quals.push_back(rewritten_qual ? rewritten_qual : qual);
4507  }
4508  return rewritten_quals;
4509 }
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 4649 of file RelAlgExecutor.cpp.

References CHECK, CHECK_GE, and kAND.

Referenced by RelAlgExecutor::makeJoinQuals().

4649  {
4650  CHECK(qual_expr);
4651  const auto bin_oper = dynamic_cast<const RexOperator*>(qual_expr);
4652  if (!bin_oper || bin_oper->getOperator() != kAND) {
4653  return {qual_expr};
4654  }
4655  CHECK_GE(bin_oper->size(), size_t(2));
4656  auto lhs_cf = rex_to_conjunctive_form(bin_oper->getOperand(0));
4657  for (size_t i = 1; i < bin_oper->size(); ++i) {
4658  const auto rhs_cf = rex_to_conjunctive_form(bin_oper->getOperand(i));
4659  lhs_cf.insert(lhs_cf.end(), rhs_cf.begin(), rhs_cf.end());
4660  }
4661  return lhs_cf;
4662 }
#define CHECK_GE(x, y)
Definition: Logger.h:306
std::vector< const RexScalar * > rex_to_conjunctive_form(const RexScalar *qual_expr)
Definition: sqldefs.h:39
#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 1709 of file RelAlgExecutor.cpp.

References RelCompound::getScalarSource().

Referenced by translate_scalar_sources(), and translate_scalar_sources_for_update().

1709  {
1710  return compound->getScalarSource(i);
1711 }
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 1713 of file RelAlgExecutor.cpp.

References RelProject::getProjectAt().

1713  {
1714  return project->getProjectAt(i);
1715 }
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 1717 of file RelAlgExecutor.cpp.

References RelTableFunction::getTableFuncInputAt().

1717  {
1718  return table_func->getTableFuncInputAt(i);
1719 }
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 90 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().

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

1722  {
1723  const auto& ti = expr->get_type_info();
1724  if (!ti.is_string() || ti.get_compression() != kENCODING_NONE) {
1725  return expr;
1726  }
1727  auto transient_dict_ti = ti;
1728  transient_dict_ti.set_compression(kENCODING_DICT);
1729  transient_dict_ti.set_comp_param(TRANSIENT_DICT_ID);
1730  transient_dict_ti.setStringDictKey(shared::StringDictKey::kTransientDictKey);
1731  transient_dict_ti.set_fixed_size();
1732  return expr->add_cast(transient_dict_ti);
1733 }
#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 1735 of file RelAlgExecutor.cpp.

References fold_expr(), and set_transient_dict().

Referenced by translate_scalar_sources(), and translate_scalar_sources_for_update().

1737  {
1738  try {
1739  scalar_sources.push_back(set_transient_dict(fold_expr(expr.get())));
1740  } catch (...) {
1741  scalar_sources.push_back(fold_expr(expr.get()));
1742  }
1743 }
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 3528 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().

3528  {
3529  for (const auto& target_expr : ra_exe_unit.target_exprs) {
3530  if (target_expr->get_type_info().usesFlatBuffer()) {
3531  // using FlatBuffer memory layout implies columnar-only output
3532  return true;
3533  }
3534  }
3537 }
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 4814 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().

4818  {
4819  CHECK_LE(size_t(1), ra_node->inputCount());
4820  CHECK_GE(size_t(2), ra_node->inputCount());
4821  const auto input = ra_node->getInput(nest_level);
4822  const auto it_rte_idx = input_to_nest_level.find(input);
4823  CHECK(it_rte_idx != input_to_nest_level.end());
4824  const int rte_idx = it_rte_idx->second;
4825  const auto table_key = table_key_from_ra(input);
4826  std::vector<std::shared_ptr<Analyzer::Expr>> inputs;
4827  const auto scan_ra = dynamic_cast<const RelScan*>(input);
4828  int input_idx = 0;
4829  for (const auto& input_meta : in_metainfo) {
4830  inputs.push_back(std::make_shared<Analyzer::ColumnVar>(
4831  input_meta.get_type_info(),
4832  shared::ColumnKey{table_key, scan_ra ? input_idx + 1 : input_idx},
4833  rte_idx));
4834  ++input_idx;
4835  }
4836  return inputs;
4837 }
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 1523 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().

1523  {
1524  const auto scan_ra = dynamic_cast<const RelScan*>(ra_node);
1525  shared::TableKey table_key{0, int32_t(-ra_node->getId())};
1526  if (scan_ra) {
1527  table_key.db_id = scan_ra->getCatalog().getDatabaseId();
1528  const auto td = scan_ra->getTableDescriptor();
1529  CHECK(td);
1530  table_key.table_id = td->tableId;
1531  }
1532  return table_key;
1533 }
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 5027 of file RelAlgExecutor.cpp.

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

Referenced by RelAlgExecutor::createUnionWorkUnit().

5028  {
5029  std::vector<TargetMetaInfo> const& tmis = input_node->getOutputMetainfo();
5030  VLOG(3) << "input_node->getOutputMetainfo()=" << shared::printContainer(tmis);
5031  const int negative_node_id = -input_node->getId();
5032  int32_t db_id{0};
5033  if (auto rel_scan = dynamic_cast<const RelScan*>(input_node)) {
5034  db_id = rel_scan->getCatalog().getDatabaseId();
5035  }
5036  std::vector<std::shared_ptr<Analyzer::Expr>> target_exprs;
5037  target_exprs.reserve(tmis.size());
5038  for (size_t i = 0; i < tmis.size(); ++i) {
5039  target_exprs.push_back(std::make_shared<Analyzer::ColumnVar>(
5040  tmis[i].get_type_info(),
5041  shared::ColumnKey{db_id, negative_node_id, int32_t(i)},
5042  0));
5043  }
5044  return target_exprs;
5045 }
PrintContainer< CONTAINER > printContainer(CONTAINER &container)
Definition: misc.h:108
#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 2474 of file RelAlgExecutor.cpp.

Referenced by RelAlgExecutor::computeWindow().

2474  {
2475  const auto tuple = dynamic_cast<const Analyzer::ExpressionTuple*>(expr);
2476  if (tuple) {
2477  std::vector<std::shared_ptr<Analyzer::Expr>> transformed_tuple;
2478  for (const auto& element : tuple->getTuple()) {
2479  transformed_tuple.push_back(transform_to_inner(element.get()));
2480  }
2481  return makeExpr<Analyzer::ExpressionTuple>(transformed_tuple);
2482  }
2483  const auto col = dynamic_cast<const Analyzer::ColumnVar*>(expr);
2484  if (!col) {
2485  throw std::runtime_error("Only columns supported in the window partition for now");
2486  }
2487  return makeExpr<Analyzer::ColumnVar>(col->get_type_info(), col->getColumnKey(), 1);
2488 }
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 1821 of file RelAlgExecutor.cpp.

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

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

1823  {
1824  if (!compound->isAggregate()) {
1825  return {nullptr};
1826  }
1827  std::list<std::shared_ptr<Analyzer::Expr>> groupby_exprs;
1828  for (size_t group_idx = 0; group_idx < compound->getGroupByCount(); ++group_idx) {
1829  groupby_exprs.push_back(set_transient_dict(scalar_sources[group_idx]));
1830  }
1831  return groupby_exprs;
1832 }
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 1834 of file RelAlgExecutor.cpp.

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

1836  {
1837  std::list<std::shared_ptr<Analyzer::Expr>> groupby_exprs;
1838  for (size_t group_idx = 0; group_idx < aggregate->getGroupByCount(); ++group_idx) {
1839  groupby_exprs.push_back(set_transient_dict(scalar_sources[group_idx]));
1840  }
1841  return groupby_exprs;
1842 }
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 1844 of file RelAlgExecutor.cpp.

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

Referenced by RelAlgExecutor::createCompoundWorkUnit().

1845  {
1846  const auto filter_rex = compound->getFilterExpr();
1847  const auto filter_expr = filter_rex ? translator.translate(filter_rex) : nullptr;
1848  return filter_expr ? qual_to_conjunctive_form(fold_expr(filter_expr.get()))
1850 }
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 1755 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().

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

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

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

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

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

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